Skip to content
Browse files

fix #125: fixed regression in processing of responses without entity …

…body
  • Loading branch information...
1 parent e7da40d commit 3b5ec2f1eaa9c896b1450e44c273bb9532eec51b @tjanczuk tjanczuk committed
View
23 src/iisnode/chttpprotocol.cpp
@@ -102,12 +102,23 @@ HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void
HTTP_REQUEST* raw = request->GetRawHttpRequest();
USHORT major, minor;
char tmp[256];
+ PCSTR method = request->GetHttpMethod();
ErrorIf(NULL == (*result = context->AllocateRequestMemory(bufferLength)), ERROR_NOT_ENOUGH_MEMORY);
+
+ // Determine whether response entity body is to be expected
+
+ if (method && 0 == strcmpi("HEAD", method))
+ {
+ // HEAD requests do not have response entity body
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
+
+ ctx->SetExpectResponseBody(FALSE);
+ }
// Request-Line
- CheckError(CHttpProtocol::Append(context, request->GetHttpMethod(), 0, result, &bufferLength, &offset));
+ CheckError(CHttpProtocol::Append(context, method, 0, result, &bufferLength, &offset));
CheckError(CHttpProtocol::Append(context, " ", 1, result, &bufferLength, &offset));
CheckError(CHttpProtocol::Append(context, ctx->GetTargetUrl(), ctx->GetTargetUrlLength(), result, &bufferLength, &offset));
request->GetHttpVersion(&major, &minor);
@@ -236,6 +247,16 @@ HRESULT CHttpProtocol::ParseResponseStatusLine(CNodeHttpStoredContext* context)
ErrorIf(' ' != data[offset], ERROR_BAD_FORMAT);
offset++;
+ // Determine whether to expect response entity body
+ // http://www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.4
+
+ if (statusCode >= 100 && statusCode < 200
+ || statusCode == 204
+ || statusCode == 304)
+ {
+ context->SetExpectResponseBody(FALSE);
+ }
+
// Reason-Phrase CRLF
newOffset = offset;
View
12 src/iisnode/cnodehttpstoredcontext.cpp
@@ -4,7 +4,7 @@ CNodeHttpStoredContext::CNodeHttpStoredContext(CNodeApplication* nodeApplication
: nodeApplication(nodeApplication), context(context), process(NULL), buffer(NULL), bufferSize(0), dataSize(0), parsingOffset(0),
chunkLength(0), chunkTransmitted(0), isChunked(FALSE), pipe(INVALID_HANDLE_VALUE), result(S_OK), isLastChunk(FALSE),
requestNotificationStatus(RQ_NOTIFICATION_PENDING), connectionRetryCount(0), pendingAsyncOperationCount(1),
- targetUrl(NULL), targetUrlLength(0), childContext(NULL), isConnectionFromPool(FALSE)
+ targetUrl(NULL), targetUrlLength(0), childContext(NULL), isConnectionFromPool(FALSE), expectResponseBody(TRUE)
{
IHttpTraceContext* tctx;
LPCGUID pguid;
@@ -263,3 +263,13 @@ void CNodeHttpStoredContext::SetIsConnectionFromPool(BOOL fromPool)
{
this->isConnectionFromPool = fromPool;
}
+
+void CNodeHttpStoredContext::SetExpectResponseBody(BOOL expect)
+{
+ this->expectResponseBody = expect;
+}
+
+BOOL CNodeHttpStoredContext::GetExpectResponseBody()
+{
+ return this->expectResponseBody;
+}
View
3 src/iisnode/cnodehttpstoredcontext.h
@@ -30,6 +30,7 @@ class CNodeHttpStoredContext : public IHttpStoredContext
IHttpContext* childContext;
BOOL isLastChunk;
BOOL isConnectionFromPool;
+ BOOL expectResponseBody;
public:
@@ -82,6 +83,8 @@ class CNodeHttpStoredContext : public IHttpStoredContext
long DecreasePendingAsyncOperationCount();
BOOL GetIsConnectionFromPool();
void SetIsConnectionFromPool(BOOL fromPool);
+ void SetExpectResponseBody(BOOL expect);
+ BOOL GetExpectResponseBody();
static CNodeHttpStoredContext* Get(LPOVERLAPPED overlapped);
View
48 src/iisnode/cprotocolbridge.cpp
@@ -865,34 +865,44 @@ void WINAPI CProtocolBridge::ProcessResponseHeaders(DWORD error, DWORD bytesTran
ctx->SetDataSize(ctx->GetDataSize() + bytesTransfered);
CheckError(CHttpProtocol::ParseResponseHeaders(ctx));
- contentLength = ctx->GetHttpContext()->GetResponse()->GetHeader(HttpHeaderContentLength, &contentLengthLength);
- if (0 == contentLengthLength)
+ if (!ctx->GetExpectResponseBody())
{
- ctx->SetIsChunked(TRUE);
- ctx->SetNextProcessor(CProtocolBridge::ProcessChunkHeader);
+ ctx->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log(
+ L"iisnode determined the HTTP response does not have entity body", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId());
+
+ CProtocolBridge::FinalizeResponse(ctx);
}
else
{
- LONGLONG length = 0;
- int i = 0;
+ contentLength = ctx->GetHttpContext()->GetResponse()->GetHeader(HttpHeaderContentLength, &contentLengthLength);
+ if (0 == contentLengthLength)
+ {
+ ctx->SetIsChunked(TRUE);
+ ctx->SetNextProcessor(CProtocolBridge::ProcessChunkHeader);
+ }
+ else
+ {
+ LONGLONG length = 0;
+ int i = 0;
- // skip leading white space
- while (i < contentLengthLength && (contentLength[i] < '0' || contentLength[i] > '9'))
- i++;
+ // skip leading white space
+ while (i < contentLengthLength && (contentLength[i] < '0' || contentLength[i] > '9'))
+ i++;
- while (i < contentLengthLength && contentLength[i] >= '0' && contentLength[i] <= '9')
- length = length * 10 + contentLength[i++] - '0';
+ while (i < contentLengthLength && contentLength[i] >= '0' && contentLength[i] <= '9')
+ length = length * 10 + contentLength[i++] - '0';
- ctx->SetIsChunked(FALSE);
- ctx->SetIsLastChunk(TRUE);
- ctx->SetChunkLength(length);
- ctx->SetNextProcessor(CProtocolBridge::ProcessResponseBody);
- }
+ ctx->SetIsChunked(FALSE);
+ ctx->SetIsLastChunk(TRUE);
+ ctx->SetChunkLength(length);
+ ctx->SetNextProcessor(CProtocolBridge::ProcessResponseBody);
+ }
- ctx->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log(
- L"iisnode finished processing http response headers", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId());
+ ctx->GetNodeApplication()->GetApplicationManager()->GetEventProvider()->Log(
+ L"iisnode finished processing http response headers", WINEVENT_LEVEL_VERBOSE, ctx->GetActivityId());
- ctx->GetAsyncContext()->completionProcessor(S_OK, 0, ctx->GetOverlapped());
+ ctx->GetAsyncContext()->completionProcessor(S_OK, 0, ctx->GetOverlapped());
+ }
return;
Error:

0 comments on commit 3b5ec2f

Please sign in to comment.
Something went wrong with that request. Please try again.