HRESULT CHttpProtocol::SerializeRequestHeaders(IHttpContext* context, void** result, DWORD* resultSize, DWORD* resultLength) { HRESULT hr; CheckNull(context); CheckNull(result); CheckNull(resultSize); CheckNull(resultLength); DWORD bufferLength = CModuleConfiguration::GetInitialRequestBufferSize(context); DWORD offset = 0; IHttpRequest* request = context->GetRequest(); HTTP_REQUEST* raw = request->GetRawHttpRequest(); USHORT major, minor; char tmp[256]; ErrorIf(NULL == (*result = context->AllocateRequestMemory(bufferLength)), ERROR_NOT_ENOUGH_MEMORY); // Request-Line CheckError(CHttpProtocol::Append(context, request->GetHttpMethod(), 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, " ", 1, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->pRawUrl, raw->RawUrlLength, result, &bufferLength, &offset)); request->GetHttpVersion(&major, &minor); sprintf(tmp, " HTTP/%d.%d\r\n", major, minor); CheckError(CHttpProtocol::Append(context, tmp, 0, result, &bufferLength, &offset)); // Known headers for (int i = 0; i < HttpHeaderRequestMaximum; i++) { if (raw->Headers.KnownHeaders[i].RawValueLength > 0) { CheckError(CHttpProtocol::Append(context, CHttpProtocol::httpRequestHeaders[i], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.KnownHeaders[i].pRawValue, raw->Headers.KnownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // Unknown headers for (int i = 0; i < raw->Headers.UnknownHeaderCount; i++) { CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pName, raw->Headers.pUnknownHeaders[i].NameLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pRawValue, raw->Headers.pUnknownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } // CRLF CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); *resultSize = bufferLength; *resultLength = offset; return S_OK; Error: if (NULL != result) { *result = NULL; } if (NULL != resultLength) { *resultLength = 0; } if (NULL != resultSize) { *resultSize = 0; } return hr; }
HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void** result, DWORD* resultSize, DWORD* resultLength) { HRESULT hr; PCSTR originalUrl = NULL; USHORT originalUrlLength; DWORD remoteHostSize = INET6_ADDRSTRLEN + 1; char remoteHost[INET6_ADDRSTRLEN + 1]; BOOL addXFF; char** serverVars; int serverVarCount; CheckNull(ctx); CheckNull(result); CheckNull(resultSize); CheckNull(resultLength); IHttpContext* context = ctx->GetHttpContext(); DWORD bufferLength = CModuleConfiguration::GetInitialRequestBufferSize(context); DWORD offset = 0; IHttpRequest* request = context->GetRequest(); HTTP_REQUEST* raw = request->GetRawHttpRequest(); USHORT major, minor; const int tmpSize = 256; char tmp[tmpSize]; 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, 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); if (1 == major && 1 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.1\r\n", 11, result, &bufferLength, &offset)); } else if (1 == major && 0 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.0\r\n", 11, result, &bufferLength, &offset)); } else { sprintf(tmp, " HTTP/%d.%d\r\n", major, minor); CheckError(CHttpProtocol::Append(context, tmp, 0, result, &bufferLength, &offset)); } // Known headers for (int i = 0; i < HttpHeaderRequestMaximum; i++) { if (raw->Headers.KnownHeaders[i].RawValueLength > 0) { CheckError(CHttpProtocol::Append(context, CHttpProtocol::httpRequestHeaders[i], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.KnownHeaders[i].pRawValue, raw->Headers.KnownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // Unknown headers if (TRUE == (addXFF = CModuleConfiguration::GetEnableXFF(context))) { PSOCKADDR addr = request->GetRemoteAddress(); DWORD addrSize = addr->sa_family == AF_INET ? sizeof SOCKADDR_IN : sizeof SOCKADDR_IN6; ErrorIf(0 != WSAAddressToString(addr, addrSize, NULL, remoteHost, &remoteHostSize), GetLastError()); } for (int i = 0; i < raw->Headers.UnknownHeaderCount; i++) { CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pName, raw->Headers.pUnknownHeaders[i].NameLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pRawValue, raw->Headers.pUnknownHeaders[i].RawValueLength, result, &bufferLength, &offset)); if (addXFF && 15 == raw->Headers.pUnknownHeaders[i].NameLength && 0 == strcmpi("X-Forwarded-For", raw->Headers.pUnknownHeaders[i].pName)) { // augment existing X-Forwarded-For header CheckError(CHttpProtocol::Append(context, ", ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, remoteHost, remoteHostSize - 1, result, &bufferLength, &offset)); addXFF = FALSE; } CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } if (addXFF) { // add a new X-Forwarded-For header CheckError(CHttpProtocol::Append(context, "X-Forwarded-For: ", 17, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, remoteHost, remoteHostSize - 1, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } // promote server variables CheckError(CModuleConfiguration::GetPromoteServerVars(context, &serverVars, &serverVarCount)); while (serverVarCount) { serverVarCount--; PCSTR varValue; DWORD varValueLength; if (S_OK == context->GetServerVariable(serverVars[serverVarCount], &varValue, &varValueLength)) { CheckError(CHttpProtocol::Append(context, "X-iisnode-", 10, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, serverVars[serverVarCount], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, varValue, varValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // CRLF CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); *resultSize = bufferLength; *resultLength = offset; return S_OK; Error: if (NULL != result) { *result = NULL; } if (NULL != resultLength) { *resultLength = 0; } if (NULL != resultSize) { *resultSize = 0; } return hr; }
HRESULT CHttpProtocol::SerializeRequestHeaders(CNodeHttpStoredContext* ctx, void** result, DWORD* resultSize, DWORD* resultLength) { HRESULT hr; PCSTR originalUrl = NULL; USHORT originalUrlLength; CheckNull(ctx); CheckNull(result); CheckNull(resultSize); CheckNull(resultLength); IHttpContext* context = ctx->GetHttpContext(); DWORD bufferLength = CModuleConfiguration::GetInitialRequestBufferSize(context); DWORD offset = 0; IHttpRequest* request = context->GetRequest(); 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, 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); if (1 == major && 1 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.1\r\n", 11, result, &bufferLength, &offset)); } else if (1 == major && 0 == minor) { CheckError(CHttpProtocol::Append(context, " HTTP/1.0\r\n", 11, result, &bufferLength, &offset)); } else { sprintf(tmp, " HTTP/%d.%d\r\n", major, minor); CheckError(CHttpProtocol::Append(context, tmp, 0, result, &bufferLength, &offset)); } // Known headers for (int i = 0; i < HttpHeaderRequestMaximum; i++) { if (raw->Headers.KnownHeaders[i].RawValueLength > 0) { CheckError(CHttpProtocol::Append(context, CHttpProtocol::httpRequestHeaders[i], 0, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.KnownHeaders[i].pRawValue, raw->Headers.KnownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } } // Unknown headers for (int i = 0; i < raw->Headers.UnknownHeaderCount; i++) { CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pName, raw->Headers.pUnknownHeaders[i].NameLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, ": ", 2, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, raw->Headers.pUnknownHeaders[i].pRawValue, raw->Headers.pUnknownHeaders[i].RawValueLength, result, &bufferLength, &offset)); CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); } // CRLF CheckError(CHttpProtocol::Append(context, "\r\n", 2, result, &bufferLength, &offset)); *resultSize = bufferLength; *resultLength = offset; return S_OK; Error: if (NULL != result) { *result = NULL; } if (NULL != resultLength) { *resultLength = 0; } if (NULL != resultSize) { *resultSize = 0; } return hr; }