分块传输编码 [英] Chunked transfer encoding

查看:145
本文介绍了分块传输编码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

hi
i开发一个Http服务器,

我的响应代码摘要是:



 PHTTP_DATA_CHUND p = new HTTP_DATA_CHUND [count]; 
for(int i = 0; i< count; i ++)
{
p [i] .DataChunkType = HttpDataChunkFromMemory;
p [i] .FromMemory.pBuffer =dfdff;
p [i] .FromMemory.BufferLength = 5;
}

HTTP_RESPONSE响应;
ZeroMemory(& response,sizeof(HTTP_RESPONSE));
PCSTR Reason =OK;
response.StatusCode = 200;
response.pReason =原因;
response.ReasonLength = strlen(Reason);
ADD_KNOWN_HEADER(response,HttpHeaderContentType,text / html);
ADD_KNOWN_HEADER(响应,HttpHeaderConnection,keep-alive);
ADD_KNOWN_HEADER(响应,HttpHeaderTransferEncoding,chunked);
ADD_KNOWN_HEADER(response,HttpHeaderContentLength,chLen);

response.EntityChunkCoun = count;
response.pEntityChunks = p;
ULONG BytesSent;
ULONG result = HttpSendHttpResponse(ReqQueueHandle,HttpRequest-> RequestId,
0,& response,NULL,& BytesSent,NULL,
0,NULL,NULL,NULL);





但结果是87 !!!

现在如果我删除这行代码:

 ADD_KNOWN_HEADER(响应,HttpHeaderTransferEncoding,chunked); 



结果为0,我的回复发送给客户。

如何进行Chunked传输编码?

解决方案

我建​​议删除Content-Length标头似乎解决了这个问题(参见上面的评论) )。



使用分块传输时,不使用Content-Length标头。似乎 HttpSendHttpResponse 函数检查标头并在传输编码分块并且内容长度也存在时返回无效参数错误。



此行为符合 RFC 2616 [ ^ ],第4.4节:

Quote:

如果存在Content-Length头字段(第14.13节),则其在OCTET中的十进制值表示实体长度和传输长度。如果这两个长度不同(即,如果存在Transfer-Encoding头字段),则不得发送Content-Length头字段。





[更新回答客户端获取普通文本而不是分块数据的问题]:



Chunked是一种传输方法。附加信息仅用于传输数据,不属于原始数据。当客户端调用某个API函数来获取接收到的HTTP数据时,此API函数将解码分块数据,添加具有解码数据大小的Content-Length头,并提供解码后的原始数据。


< blockquote>我改变了我的代码:这可以发送回复



 response.EntityChunkCount = 0; 
response.pEntityChunks = 0;
ULONG BytesSent;
ULONG result = HttpSendHttpResponse(ReqQueueHandle,HttpRequest-> RequestId,
0,& response,NULL,& BytesSent,NULL,
0,NULL,NULL,NULL);
for(/ * buffers * /)
{
PHTTP_DATA_CHUND chunk;
chunk.DataChunkType = HttpDataChunkFromMemory;
chunk.FromMemory.pBuffer = buffer [i]; // ---bufferLen\r\\\
.... \\\\ n
chunk.FromMemory.BufferLength = len [i];
HttpSendResponseEntityBody(ReqQueueHandle,HttpRequest-> requestId,
HTT_SEND_RESPONSE_FLAG_MORE_DATA,1,& chunk,0
NULL,0,NULL,NULL);
}

PHTTP_DATA_CHUND chunkEnd;
chunkEnd.DataChunkType = HttpDataChunkFromMemory;
chunkEnd.FromMemory.pBuffer =\\\\ nn0 \\\\ n;
chunkEnd.FromMemory.BufferLength = 5;
HttpSendResponseEntityBody(ReqQueueHandle,HttpRequest-> requestId,
HTT_SEND_RESPONSE_FLAG_DISCONNECT,1,& chunkEnd,0
NULL,0,NULL,NULL);


hi i develop a Http server,
my Summary of response code is this:

PHTTP_DATA_CHUND p = new HTTP_DATA_CHUND[count];
for (int i = 0; i<count; i++)
{
  p[i].DataChunkType = HttpDataChunkFromMemory;
  p[i].FromMemory.pBuffer = "dfdff"; 
  p[i].FromMemory.BufferLength = 5;
}

HTTP_RESPONSE response;  
ZeroMemory(&response,sizeof(HTTP_RESPONSE));  
PCSTR Reason="OK";  
response.StatusCode=200;  
response.pReason=Reason;  
response.ReasonLength=strlen(Reason);  
ADD_KNOWN_HEADER(response, HttpHeaderContentType, "text/html");
ADD_KNOWN_HEADER(response, HttpHeaderConnection, "keep-alive");
ADD_KNOWN_HEADER(response, HttpHeaderTransferEncoding, "chunked");
ADD_KNOWN_HEADER(response, HttpHeaderContentLength, chLen);

response.EntityChunkCoun = count;
response.pEntityChunks=p;
ULONG BytesSent;
ULONG result = HttpSendHttpResponse(ReqQueueHandle, HttpRequest->RequestId, 
                                            0, &response, NULL,&BytesSent, NULL, 
                                            0,NULL,NULL, NULL);



but the result is 87 !!!
now if i remove this line of code:

ADD_KNOWN_HEADER(response, HttpHeaderTransferEncoding, "chunked");


the result is 0 and my response is sent to client.
How i to make Chunked transfer encoding?

解决方案

My suggestion to remove the Content-Length header seems to solve the problem (see my above comment).

With chunked transfers, the Content-Length header is not used. It seems that the HttpSendHttpResponse function checks the headers and returns with an invalid parameter error when the transfer encoding is chunked and the content length is also present.

This behaviour complies with RFC 2616[^], section 4.4:

Quote:

If a Content-Length header field (section 14.13) is present, its decimal value in OCTETs represents both the entity-length and the transfer-length. The Content-Length header field MUST NOT be sent if these two lengths are different (i.e., if a Transfer-Encoding header field is present).



[UPDATE to answer the question why the client gets normal text rather the chunked data]:

Chunked is a transfer method. The additional information is used only for transferring data and does not belong to the original data. When a client calls some API function to get received HTTP data, this API function will decode chunked data, add a Content-Length header with the size of the decoded data and provides the decoded original data.


i changed my code : this is ok to send response

response.EntityChunkCount = 0;
response.pEntityChunks=0;
ULONG BytesSent;
ULONG result = HttpSendHttpResponse(ReqQueueHandle, HttpRequest->RequestId,
                                            0, &response, NULL,&BytesSent, NULL,
                                            0,NULL,NULL, NULL);
for (/*buffers */)
{
PHTTP_DATA_CHUND chunk;
chunk.DataChunkType = HttpDataChunkFromMemory;
chunk.FromMemory.pBuffer = buffer[i]; //--- "bufferLen\r\n .... \r\n"
chunk.FromMemory.BufferLength = len[i];
HttpSendResponseEntityBody(ReqQueueHandle, HttpRequest->requestId, 
                                 HTT_SEND_RESPONSE_FLAG_MORE_DATA, 1, &chunk, 0
                                 NULL, 0, NULL, NULL);
}

PHTTP_DATA_CHUND chunkEnd;
chunkEnd.DataChunkType = HttpDataChunkFromMemory;
chunkEnd.FromMemory.pBuffer = "\r\n0\r\n";
chunkEnd.FromMemory.BufferLength = 5;
HttpSendResponseEntityBody(ReqQueueHandle, HttpRequest->requestId,
                                 HTT_SEND_RESPONSE_FLAG_DISCONNECT, 1, &chunkEnd, 0
                                 NULL, 0, NULL, NULL);


这篇关于分块传输编码的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆