Restsharp: 端口被剥离主机头

创建于 2018-02-21  ·  35评论  ·  资料来源: restsharp/RestSharp

预期行为

Restsharp 应该按原样发送 Host 标头而不修改 Host 标头值中的端口。
https://github.com/minio/minio-dotnet/pull/212引入了 Restsharp 106.2.1 而不是 Restsharp.Netcore(支持 .netcore 的非官方版本)。 但是,我们发现签名不匹配错误,因为 minio dotnet sdk 使用的自定义身份验证器使用 ip:port 作为“Host”标头的值创建授权签名。 Restsharp httpclient 似乎正在剥离端口,因为服务器跟踪仅在主机标头值中显示 ip。

实际行为

端口正在从 Restsharp 106.2.1 中的“主机”标头值中剥离

重现问题的步骤

  1. 克隆 minio-dotnet sdk 并获取补丁https://github.com/minio/minio-dotnet/pull/212
    ➜ minio-dotnet git:(02cbcb5) ✗ dotnet restore;dotnet build
    ➜ minio-dotnet git:(02cbcb5) ✗ dotnet run --project SimpleTest
    2.
    3.

规格

堆栈跟踪

minio-dotnet client side trace
---------------------------------------
Full URL of Request http://192.168.1.157:9000/
Request completed in 90.1376 ms, Request: {
  "resource": "/",
  "parameters": [
    {
      "name": "x-amz-content-sha256",
      "value": "e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",
      "type": "HttpHeader"
    },
    {
      "name": "Host",
      "value": "192.168.1.157:9000",
      "type": "HttpHeader"
    },
    {
      "name": "x-amz-date",
      "value": "20180221T205958Z",
      "type": "HttpHeader"
    },
    {
      "name": "Authorization",
      "value": "AWS4-HMAC-SHA256 Credential=minio/20180221/us-east-1/s3/aws4_request, SignedHeaders=host;x-amz-content-sha256;x-amz-date, Signature=db0fbcc9aa66975a530a2621962a87787559289a218da881420686263da862df",
      "type": "HttpHeader"
    },
    {
      "name": "Accept",
      "value": "application/json, application/xml, text/json, text/x-json, text/javascript, text/xml",
      "type": "HttpHeader"
    }
  ],
  "method": "GET",
  "uri": "http://192.168.1.157:9000/"
}, Response: {
  "statusCode": 403,
  "content": "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<Error><Code>SignatureDoesNotMatch</Code><Message>The request signature we calculated does not match the signature you provided. Check your key and signing method.</Message><Key></Key><BucketName></BucketName><Resource>/</Resource><RequestId>3L137</RequestId><HostId>3L137</HostId></Error>",
  "headers": [
    {
      "Name": "Accept-Ranges",
      "Value": "bytes",
      "Type": 3,
      "ContentType": null
    },
    {
      "Name": "Server",
      "Value": "Minio/DEVELOPMENT.GOGET, (linux; amd64)",
      "Type": 3,
      "ContentType": null
    },
    {
      "Name": "Vary",
      "Value": "Origin",
      "Type": 3,
      "ContentType": null
    },
    {
      "Name": "X-Amz-Request-Id",
      "Value": "151572E9DCF94747",
      "Type": 3,
      "ContentType": null
    },
    {
      "Name": "Date",
      "Value": "Wed, 21 Feb 2018 20:59:58 GMT",
      "Type": 3,
      "ContentType": null
    },
    {
      "Name": "Transfer-Encoding",
      "Value": "chunked",
      "Type": 3,
      "ContentType": null
    },
    {
      "Name": "Content-Type",
      "Value": "application/xml",
      "Type": 3,
      "ContentType": null
    }
  ],
  "responseUri": "http://192.168.1.157:9000/",
  "errorMessage": null
}
I'm not handling the Minio.Exceptions.MinioException.

Unhandled Exception: System.AggregateException: One or more errors occurred. (Minio API responded with message=The request signature we calculated does not match the signature you provided. Check your key and signing method.) (Minio API responded with message=The request signature we calculated does not match the signature you provided. Check your key and signing method.) ---> Minio.Exceptions.MinioException: Minio API responded with message=The request signature we calculated does not match the signature you provided. Check your key and signing method.
   at Minio.MinioClient.ParseError(IRestResponse response) in /home/kris/code/minio-dotnet/Minio/MinioClient.cs:line 475
   at Minio.MinioClient.<>c.<.ctor>b__78_0(IRestResponse response) in /home/kris/code/minio-dotnet/Minio/MinioClient.cs:line 70
   at Minio.MinioClient.HandleIfErrorResponse(IRestResponse response, IEnumerable`1 handlers, DateTime startTime) in /home/kris/code/minio-dotnet/Minio/MinioClient.cs:line 502
   at Minio.MinioClient.<ExecuteTaskAsync>d__81.MoveNext() in /home/kris/code/minio-dotnet/Minio/MinioClient.cs:line 349
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at System.Runtime.CompilerServices.TaskAwaiter.HandleNonSuccessAndDebuggerNotification(Task task)
   at System.Runtime.CompilerServices.TaskAwaiter`1.GetResult()
   at Minio.MinioClient.<ListBucketsAsync>d__0.MoveNext() in /home/kris/code/minio-dotnet/Minio/ApiEndpoints/BucketOperations.cs:line 52
   --- End of inner exception stack trace ---
   at System.AggregateException.Handle(Func`2 predicate)
   at SimpleTest.Program.Main(String[] args) in /home/kris/code/minio-dotnet/SimpleTest/Program.cs:line 47

Server side trace: 
--------------------------
➜  minio git:(debugnet) minio server ~/ex                               
Drive Capacity: 6.9 GiB Free, 221 GiB Total

Endpoint:  http://192.168.1.157:9000  http://172.17.0.1:9000  http://172.18.0.1:9000  http://172.19.0.1:9000  http://172.20.0.1:9000  http://127.0.0.1:9000
AccessKey: minio 
SecretKey: minio123 

Browser Access:
   http://192.168.1.157:9000  http://172.17.0.1:9000  http://172.18.0.1:9000  http://172.19.0.1:9000  http://172.20.0.1:9000  http://127.0.0.1:9000

Command-line Access: https://docs.minio.io/docs/minio-client-quickstart-guide
   $ mc config host add myminio http://192.168.1.157:9000 minio minio123

Object API (Amazon S3 compatible):
   Go:         https://docs.minio.io/docs/golang-client-quickstart-guide
   Java:       https://docs.minio.io/docs/java-client-quickstart-guide
   Python:     https://docs.minio.io/docs/python-client-quickstart-guide
   JavaScript: https://docs.minio.io/docs/javascript-client-quickstart-guide
   .NET:       https://docs.minio.io/docs/dotnet-client-quickstart-guide
signed headers .... map[X-Amz-Content-Sha256:[e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855] X-Amz-Date:[20180221T205638Z] Host:[192.168.1.157]]

最有用的评论

让我们举起它!

所有35条评论

有没有办法在简单的测试中重现它?

https://github.com/poornas/restsharp-test - 这是一个简单的项目,使用 restsharp 对 minio 服务器进行 List buckets 调用。 它使用自定义身份验证器 - 您会看到它由于签名不匹配而失败。 一旦请求被传递给restsharp,端口在传递给服务器之前被剥离。

谢谢。 我会看看并尝试修复它。

谢谢!

@alexeyzimarev关于可能导致这种情况的任何想法?

@alexeyzimarev ,你有机会调查一下吗? 谢谢

现在检查

我克隆了你的复制品,我看到了这个:

  "parameters": [
...
    {
      "name": "Host",
      "value": "play.minio.io:9000",
      "type": "HttpHeader"
    }

您的意思是请求中的参数很好,但值没有正确发送到服务器?

@alexeyzimarev ,这是正确的 - 您在上面看到的跟踪是在调用 executeAsync 之前。 当调用 ExecuteAsync 时,Restsharp 调用 Authenticate 方法,我们在自定义身份验证器中根据url:port设置签名授权标头。 在访问服务器之前和 Authenticate() 调用之后,Restsharp 似乎剥离了端口。

对此有何更新? 我们在这方面受到了很大的阻碍。

抱歉,我还不能看这个。 如果很关键,你们可以花一个小时调试吗?

我对此进行了快速浏览。 据我所知,这里的问题实际上不在于 RestSharp,而实际上是HttpWebRequest System.Net

当 RestSharp 将请求移交给 System.Net 时,$#$ HttpWebRequest $#$ 中的Host属性 (Uri) 仍然包含端口信息。 但是,当调用.SendRequest()时,使用的 Host 标头仅由 URI Host 填充,而不是 host 和 port

这是上面链接中我的调试器的屏幕截图。
screen shot 2018-03-22 at 11 22 52 am

这显然违背了关于端口使用的HTTP 规范

如果我错了,请有人纠正我,因为我从未在 dotnet 框架中发现错误,而且通常当我认为我有 - 我没有。 否则我想接下来的步骤是在 CoreFX 回购中提出这个问题?

让我们举起它!

完成 - 让我们看看这是否是错误所在的合法位置。

只是好奇 - 有人知道这是否是最近 .NET Core 的回归吗? (2.1)或最后一个稳定(2.0)? 还是 .NET Framework 与 .NET Core 的区别,或者 OS Windows 与 Linux 的区别? (“不知道”是很好的答案,谢谢!)

@karelz TBH 我研究了这个问题以解决另一个问题,所以我可以停止收到编译器警告😆 对我来说这是一个“不知道”,我只在 MacOS 上的 .NET Core 2.0 上尝试过这个。 该库仅在最近(可能几个月)升级为仅支持 .NET Core 而不是 .NET Framework。 也许@alexeyzimarev可能知道更多?

好的,你至少知道:它在 .NET Framework (Windows) 上工作,在 .NET Core 2.0 (Mac) 上失败。 这是正确的总结吗?

不 - 从我所在的其他线程来看,我会说它在 .NET Core 2.0 上的所有平台上都失败了,而且我不知道 .NET Framework。

@karelz我会说这个假设是正确的。 我刚刚从完整框架更改为 .net 核心/标准,然后测试就中断了。 我不确定这是否是 1.x 的回归,因为我们只尝试迁移到 .net 标准 2.0

@niemyjski感谢您的确认。 在这一点上,这是足够的信息。 我只是在寻找已知的事实/经验。

我们是否保持这个问题开放?

CoreFx 中的修复在 PR 中: https ://github.com/dotnet/corefx/pull/28375

是的 :)

谢谢
——布莱克·涅米斯基

2018 年 3 月 22 日星期四下午 3:57,Caesar Chen [email protected]
写道:

CoreFx 中的修复在 PR 中:dotnet/corefx#28375
https://github.com/dotnet/corefx/pull/28375


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/restsharp/RestSharp/issues/1085#issuecomment-375454963
或使线程静音
https://github.com/notifications/unsubscribe-auth/AA-So67a2QfPq72jMHNxaSCBhDXiWXOMks5thBAygaJpZM4SOXLx
.

有什么原因我们不能切换到更快的 HttpClient
并且更容易使用? 不会有这个问题吧?

谢谢
——布莱克·涅米斯基

2018 年 3 月 23 日星期五上午 7:14,Blake Niemyjski [email protected]
写道:

是的 :)

谢谢
——布莱克·涅米斯基

2018 年 3 月 22 日星期四下午 3:57,Caesar Chen [email protected]
写道:

CoreFx 中的修复在 PR 中:dotnet/corefx#28375
https://github.com/dotnet/corefx/pull/28375


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/restsharp/RestSharp/issues/1085#issuecomment-375454963
或使线程静音
https://github.com/notifications/unsubscribe-auth/AA-So67a2QfPq72jMHNxaSCBhDXiWXOMks5thBAygaJpZM4SOXLx
.

@niemyjski你的意思是你切换 RestSharp 使用HttpClient而不是HttpWebRequest

是的 :)

谢谢
——布莱克·涅米斯基

2018 年 3 月 23 日星期五上午 9:22,Alexey Zimarev [email protected]
写道:

@niemyjski https://github.com/niemyjski你的意思是你切换
RestSharp 使用 HttpClient 而不是 HttpWebRequest?


你收到这个是因为你被提到了。
直接回复此邮件,在 GitHub 上查看
https://github.com/restsharp/RestSharp/issues/1085#issuecomment-375680769
或使线程静音
https://github.com/notifications/unsubscribe-auth/AA-So0cbK66_Nq-MRdk0xwdb7sLPSGUoks5thQUUgaJpZM4SOXLx
.

@niemyjski问题是一个_或_另一个,_是_真的不是一个有效的答案:)

如果您的意思是 RestSharp 应该使用HttpClient - 我很赞成它,但上次我尝试匹配 RestClient 中的所有参数需要做很多工作。

是的,我们应该切换到 HttpClient,它具有更大的灵活性、更好的性能和我们知道在任何地方都可以使用的现代 api。 我们可以做一些突破性的改变,并改变主要的 :)

是的,我很好,但我不是一个人做的。 我试过了,工作量太大了。 我还将删除接受回调的异步调用。 ContinueWith 应该没问题。

看起来这已被合并到 2.1 中,我们是否应该发布引用新预览 2 位的每晚,并且我们可以将其他包移动很长时间? 对于 < 2.1 运行时/库,我们可以做些什么变通?

我对解决方法一无所知

我需要先发布一个版本,然后才能将预发布版更改为参考 2.1 预览版

这已经解决了吗? 2.1 rtm 包在 nuget 上。

所以,你需要尝试使用 2.1 看看他们是否修复了它?

@niemyjski我 4 月 20 日的评论很愚蠢。 我不需要在任何地方指出任何东西。 该库编译为 .NET Standard 2.0。 该错误是由 .NET Core 2.0 运行时中的错误引起的,因此一旦您使用 .NET Core 2.1 重建应用程序,如果问题得到修复,它应该开始工作。 很抱歉造成混乱。

此页面是否有帮助?
0 / 5 - 0 等级