|
32 | 32 |
|
33 | 33 | #include "winsock2.h"
|
34 | 34 |
|
35 |
| -// Used to hold each chunk of request body that gets read before the full ModSec engine is invoked |
36 |
| -typedef struct preAllocBodyChunk { |
37 |
| - preAllocBodyChunk* next; |
38 |
| - size_t length; |
39 |
| - void* data; |
40 |
| -} preAllocBodyChunk; |
41 | 35 |
|
42 | 36 | class REQUEST_STORED_CONTEXT : public IHttpStoredContext
|
43 | 37 | {
|
@@ -89,8 +83,6 @@ class REQUEST_STORED_CONTEXT : public IHttpStoredContext
|
89 | 83 | char *m_pResponseBuffer;
|
90 | 84 | ULONGLONG m_pResponseLength;
|
91 | 85 | ULONGLONG m_pResponsePosition;
|
92 |
| - |
93 |
| - preAllocBodyChunk* requestBodyBufferHead; |
94 | 86 | };
|
95 | 87 |
|
96 | 88 |
|
@@ -296,43 +288,6 @@ REQUEST_STORED_CONTEXT *RetrieveIISContext(request_rec *r)
|
296 | 288 | return NULL;
|
297 | 289 | }
|
298 | 290 |
|
299 |
| -HRESULT GetRequestBodyFromIIS(IHttpRequest* pRequest, preAllocBodyChunk** head) |
300 |
| -{ |
301 |
| - HRESULT hr = S_OK; |
302 |
| - HTTP_REQUEST * pRawRequest = pRequest->GetRawHttpRequest(); |
303 |
| - preAllocBodyChunk** cur = head; |
304 |
| - while (pRequest->GetRemainingEntityBytes() > 0) |
305 |
| - { |
306 |
| - // Allocate memory for the preAllocBodyChunk linked list structure, and also the actual body content |
307 |
| - // HUGE_STRING_LEN is hardcoded because this is also hardcoded in apache2_io.c's call to ap_get_brigade |
308 |
| - preAllocBodyChunk* chunk = (preAllocBodyChunk*)malloc(sizeof(preAllocBodyChunk) + HUGE_STRING_LEN); |
309 |
| - chunk->next = NULL; |
310 |
| - |
311 |
| - // Pointer to rest of allocated memory, for convenience |
312 |
| - chunk->data = chunk + 1; |
313 |
| - |
314 |
| - DWORD readcnt = 0; |
315 |
| - hr = pRequest->ReadEntityBody(chunk->data, HUGE_STRING_LEN, false, &readcnt, NULL); |
316 |
| - if (ERROR_HANDLE_EOF == (hr & 0x0000FFFF)) |
317 |
| - { |
318 |
| - free(chunk); |
319 |
| - hr = S_OK; |
320 |
| - break; |
321 |
| - } |
322 |
| - chunk->length = readcnt; |
323 |
| - |
324 |
| - // Append to linked list |
325 |
| - *cur = chunk; |
326 |
| - cur = &(chunk->next); |
327 |
| - |
328 |
| - if (hr != S_OK) |
329 |
| - { |
330 |
| - break; |
331 |
| - } |
332 |
| - } |
333 |
| - |
334 |
| - return hr; |
335 |
| -} |
336 | 291 |
|
337 | 292 | HRESULT CMyHttpModule::ReadFileChunk(HTTP_DATA_CHUNK *chunk, char *buf)
|
338 | 293 | {
|
@@ -800,24 +755,6 @@ CMyHttpModule::OnBeginRequest(
|
800 | 755 | goto Finished;
|
801 | 756 | }
|
802 | 757 |
|
803 |
| - // Get request body without holding lock, because some clients may be slow at sending |
804 |
| - LeaveCriticalSection(&m_csLock); |
805 |
| - preAllocBodyChunk* requestBodyBufferHead = NULL; |
806 |
| - hr = GetRequestBodyFromIIS(pRequest, &requestBodyBufferHead); |
807 |
| - if (hr != S_OK) |
808 |
| - { |
809 |
| - goto FinishedWithoutLock; |
810 |
| - } |
811 |
| - EnterCriticalSection(&m_csLock); |
812 |
| - |
813 |
| - // Get the config again, in case it changed during the time we released the lock |
814 |
| - hr = MODSECURITY_STORED_CONTEXT::GetConfig(pHttpContext, &pConfig); |
815 |
| - if (FAILED(hr)) |
816 |
| - { |
817 |
| - hr = S_OK; |
818 |
| - goto Finished; |
819 |
| - } |
820 |
| - |
821 | 758 | if(pConfig->m_Config == NULL)
|
822 | 759 | {
|
823 | 760 | char *path;
|
@@ -890,8 +827,6 @@ CMyHttpModule::OnBeginRequest(
|
890 | 827 | rsc->m_pRequestRec = r;
|
891 | 828 | rsc->m_pHttpContext = pHttpContext;
|
892 | 829 | rsc->m_pProvider = pProvider;
|
893 |
| - rsc->requestBodyBufferHead = requestBodyBufferHead; |
894 |
| - requestBodyBufferHead = NULL; // This is to indicate to the cleanup process to use rsc->requestBodyBufferHead instead of requestBodyBufferHead now |
895 | 830 |
|
896 | 831 | pHttpContext->GetModuleContextContainer()->SetModuleContext(rsc, g_pModuleContext);
|
897 | 832 |
|
@@ -1139,44 +1074,46 @@ CMyHttpModule::OnBeginRequest(
|
1139 | 1074 | Finished:
|
1140 | 1075 | LeaveCriticalSection(&m_csLock);
|
1141 | 1076 |
|
1142 |
| -FinishedWithoutLock: |
1143 |
| - // Free the preallocated body in case there was a failure and it wasn't consumed already |
1144 |
| - preAllocBodyChunk* chunkToFree = requestBodyBufferHead ? requestBodyBufferHead : rsc->requestBodyBufferHead; |
1145 |
| - while (chunkToFree != NULL) |
1146 |
| - { |
1147 |
| - preAllocBodyChunk* next = chunkToFree->next; |
1148 |
| - free(chunkToFree); |
1149 |
| - chunkToFree = next; |
1150 |
| - } |
1151 |
| - |
1152 | 1077 | if ( FAILED( hr ) )
|
1153 | 1078 | {
|
1154 | 1079 | return RQ_NOTIFICATION_FINISH_REQUEST;
|
1155 | 1080 | }
|
1156 | 1081 | return RQ_NOTIFICATION_CONTINUE;
|
1157 | 1082 | }
|
1158 | 1083 |
|
| 1084 | + |
1159 | 1085 | apr_status_t ReadBodyCallback(request_rec *r, char *buf, unsigned int length, unsigned int *readcnt, int *is_eos)
|
1160 | 1086 | {
|
1161 | 1087 | REQUEST_STORED_CONTEXT *rsc = RetrieveIISContext(r);
|
1162 | 1088 |
|
1163 |
| - if (rsc->requestBodyBufferHead == NULL) |
| 1089 | + *readcnt = 0; |
| 1090 | + |
| 1091 | + if (rsc == NULL) |
1164 | 1092 | {
|
1165 | 1093 | *is_eos = 1;
|
1166 | 1094 | return APR_SUCCESS;
|
1167 | 1095 | }
|
1168 | 1096 |
|
1169 |
| - *readcnt = length < (unsigned int) rsc->requestBodyBufferHead->length ? length : (unsigned int) rsc->requestBodyBufferHead->length; |
1170 |
| - void* src = (char*)rsc->requestBodyBufferHead->data; |
1171 |
| - memcpy_s(buf, length, src, *readcnt); |
| 1097 | + IHttpContext *pHttpContext = rsc->m_pHttpContext; |
| 1098 | + IHttpRequest *pRequest = pHttpContext->GetRequest(); |
1172 | 1099 |
|
1173 |
| - // Remove the front and proceed to next chunk in the linked list |
1174 |
| - preAllocBodyChunk* chunkToFree = rsc->requestBodyBufferHead; |
1175 |
| - rsc->requestBodyBufferHead = rsc->requestBodyBufferHead->next; |
1176 |
| - free(chunkToFree); |
| 1100 | + if (pRequest->GetRemainingEntityBytes() == 0) |
| 1101 | + { |
| 1102 | + *is_eos = 1; |
| 1103 | + return APR_SUCCESS; |
| 1104 | + } |
| 1105 | + |
| 1106 | + HRESULT hr = pRequest->ReadEntityBody(buf, length, false, (DWORD *)readcnt, NULL); |
1177 | 1107 |
|
1178 |
| - if (rsc->requestBodyBufferHead == NULL) |
| 1108 | + if (FAILED(hr)) |
1179 | 1109 | {
|
| 1110 | + // End of data is okay. |
| 1111 | + if (ERROR_HANDLE_EOF != (hr & 0x0000FFFF)) |
| 1112 | + { |
| 1113 | + // Set the error status. |
| 1114 | + rsc->m_pProvider->SetErrorStatus(hr); |
| 1115 | + } |
| 1116 | + |
1180 | 1117 | *is_eos = 1;
|
1181 | 1118 | }
|
1182 | 1119 |
|
|
0 commit comments