InternetReadFile 因分块响应而失败

Posted

技术标签:

【中文标题】InternetReadFile 因分块响应而失败【英文标题】:InternetReadFile fails for a chunked response 【发布时间】:2014-09-19 08:39:46 【问题描述】:

我有一个发送分块传输编码数据的服务器。我使用 InternetReadFile 读取数据,但 InternetReadFile 在读取第一个块后失败并显示 12004。我使用提琴手 (Wireshark) 来截取接收到的数据。 Wireshark 显示第二个块,但 InternetReadFile API 失败。

示例代码:

    CString totalbuffer ;

    While ( 1 )
    
      char recv [ 10 ] = '\0' ;
      DWORD dwBytesRead = 0 ;
      if ( InternetReadFile ( httpSocket.hReq , recv, 10 , &dwBytesRead ) )
      
         recv[ dwBytesRead] = '\0' ;
         totalbuffer += recv ;
         printf ( " received buffer : %s" , recv ) ;
         return 1 ;
      
      else
      
         printf ( " InternetReadFile failed with : %d" , GetLastError ( ) ) ;
         return 0 ;
      
    ;  

WireShark 显示:

HTTP/1.1 200 正常

传输编码:分块

日期:格林威治标准时间 2014 年 9 月 18 日星期四 14:16:16

服务器:CHND

3

好的\n

3

CMD

客户端只读取前 3 个字节的块。当我尝试读取下一个 3 字节块“CMD”时,它不起作用。

请帮助客户端应该做哪些必要的更改?还是服务器端需要处理一些额外的事情?

【问题讨论】:

相关:您知道您正在读取的前 10 个字节,如果完全填充该缓冲区,则紧随其后的行将通过超出您的数组大小一个元素来调用 undefined behavior . (即当数组只有 10 个元素宽(因此只能从 0..9 开始索引)时,dwBytesRead == 10recv[dwBytesRead] = '\0'; 不利。 【参考方案1】:

我遇到了类似的问题,您需要使用InternetQueryDataAvailable()“查询”连接以获取任何额外信息:

  while(TRUE)
  
    res = InternetQueryDataAvailable(hr, &len, 0, 0);
    if (!res || len == 0) break;

    res = InternetReadFile(hr, recv, len, &dwbread);
    if(!res || (res && dwbread == 0)) break;
    totalbuffer += recv ;
    ...
  

使用它,它将查看是否有更多来自此 HTTP 请求的数据,并且这似乎处理了分块编码,因为字节数(“块”长度)不会显示在 recv缓冲区,所以我们不能以原始形式使用它。

注意:我的程序是用 C 语言编写的,而不是 C++,但你会明白的。

【讨论】:

以上是关于InternetReadFile 因分块响应而失败的主要内容,如果未能解决你的问题,请参考以下文章

Spring MVC 测试框架因 HTTP 响应 406 而失败

带有文本/纯文本响应的 API 因“不可接受的内容类型”而失败

CORS 因请求而失败,带有 OPTIONS(状态为 0 的响应)

python中的Elasticsearch parallel_bulk辅助函数在使用响应时会因部分失败而引发错误

CORS 预检神秘地因大猩猩/处理程序而失败

雪花程序因任务执行而失败