【问题标题】:Translating cURL to HttpClient.PutAsync将 cURL 转换为 HttpClient.PutAsync
【发布时间】:2016-09-30 19:35:29
【问题描述】:

我正在尝试将一些 cURL 命令转换为 C# 实现,但我遇到了一个我无法解决的异常。

我试图收集尽可能多的信息,希望有人可以进一步帮助我。就这样吧……

cURL 语句:

curl -i -X PUT "http://[ipaddress]:[port]/webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=[username]&op=CREATE"

C# 版本:

var response = await client.PutAsync(
    "http://[ipaddress]:[port]/webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=[username]&op=CREATE",
    null);

C# 版本的结果是 WebException:

HResult = -2146233088

消息 = 无法解析远程名称:'ip-172-31-9-79.eu-central-1.compute.internal'

我要连接的服务器是 Hadoop 服务器。该服务器上有多个实例正在运行。因此,当我存储文件时,服务器会回复有关该文件存储在哪个实例的信息(以便在我想写入该文件时可以引用该实例)。

根据错误消息,它似乎收到了对它无法访问的 IP 地址的某种引用(这是有道理的,因为该 IP 地址是该 Hadoop 服务器中的内部 IP 地址。

我使用 Wireshark 查找发送请求的差异。

使用 cURL:

Frame 57: 204 bytes on wire (1632 bits), 204 bytes captured (1632 bits) on interface 0
Ethernet II, Src: IntelCor_da:f4:44 (fc:f8:ae:da:f4:44), Dst: AsustekC_32:7d:b0 (ac:22:0b:32:7d:b0)
Internet Protocol Version 4, Src: 192.168.1.107, Dst: [ipaddress]
Transmission Control Protocol, Src Port: 60454, Dst Port: 50070, Seq: 1, Ack: 1, Len: 150
Hypertext Transfer Protocol
    PUT /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): PUT /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE HTTP/1.1\r\n]
            [PUT /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: PUT
        Request URI: /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE
            Request URI Path: /webhdfs/v1/[appname]/staging/sensors/aap.txt
            Request URI Query: user.name=hdfs&op=CREATE
                Request URI Query Parameter: user.name=hdfs
                Request URI Query Parameter: op=CREATE
        Request Version: HTTP/1.1
    Host: [ipaddress]:50070\r\n
    User-Agent: curl/7.50.0\r\n
    Accept: */*\r\n
    \r\n
    [Full request URI: http://[ipaddress]:50070/webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE]
    [HTTP request 1/1]
    [Response in frame: 59]

使用HttpClient

Frame 381: 209 bytes on wire (1672 bits), 209 bytes captured (1672 bits) on interface 0
Ethernet II, Src: IntelCor_da:f4:44 (fc:f8:ae:da:f4:44), Dst: AsustekC_32:7d:b0 (ac:22:0b:32:7d:b0)
Internet Protocol Version 4, Src: 192.168.1.107, Dst: [ipaddress]
Transmission Control Protocol, Src Port: 60541, Dst Port: 50070, Seq: 1, Ack: 1, Len: 155
Hypertext Transfer Protocol
    PUT /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE HTTP/1.1\r\n
        [Expert Info (Chat/Sequence): PUT /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE HTTP/1.1\r\n]
            [PUT /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE HTTP/1.1\r\n]
            [Severity level: Chat]
            [Group: Sequence]
        Request Method: PUT
        Request URI: /webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE
            Request URI Path: /webhdfs/v1/[appname]/staging/sensors/aap.txt
            Request URI Query: user.name=hdfs&op=CREATE
                Request URI Query Parameter: user.name=hdfs
                Request URI Query Parameter: op=CREATE
        Request Version: HTTP/1.1
    Host: [ipaddress]:50070\r\n
    Content-Length: 0\r\n
    Connection: Keep-Alive\r\n
    \r\n
    [Full request URI: http://[ipaddress]:50070/webhdfs/v1/[appname]/staging/sensors/aap.txt?user.name=hdfs&op=CREATE]
    [HTTP request 1/1]
    [Response in frame: 383]

对我来说,唯一值得注意(但对我来说毫无意义)的区别是:

  • 用户代理:curl/7.50.0\r\n
  • 接受:/\r\n

  • 内容长度:0\r\n
  • 连接:保持活动状态\r\n

我对 REST 编程的经验很少,而且在分析 Web 请求方面显然没有足够的知识。一些帮助/指导/解释将不胜感激。

只是为了完整性:

  • 是的,我知道 cURL 有 Windows 可执行文件,但我在 Raspberry PI / Windows IoT 上运行。据我所知,该特定平台还没有(还)
  • 在上面的陈述中,我故意省略了 ipaddress/appname/etc,只是为了安全起见

【问题讨论】:

    标签: c# rest redirect httpclient


    【解决方案1】:

    我发现唯一出错的是读取 C# 中的响应。通过 Wireshark 监控的 HTTP 响应是相同的(使用 cURL.exe 和在 C# 中使用 PutAsync)。

    我能够忽略重定向并有机会自己处理响应。

    所以禁用自动重定向(并自己处理响应)解决了我的问题:

    var httpClientHandler = new HttpClientHandler {AllowAutoRedirect = false};
    var client = new HttpClient(httpClientHandler);
    

    【讨论】:

      猜你喜欢
      • 2017-06-05
      • 2016-01-08
      • 2018-03-28
      • 2021-03-27
      • 2019-11-12
      • 2016-05-20
      • 2018-05-23
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多