response bodies.
Also don't change app state for http from inside inspection.
}
int HtpRequestBodyHandleMultipart(HtpState *hstate, HtpTxUserData *htud,
- uint8_t *chunks_buffer, uint32_t chunks_buffer_len)
+ void *tx, uint8_t *chunks_buffer, uint32_t chunks_buffer_len)
{
int result = 0;
uint8_t *expected_boundary = NULL;
uint8_t *expected_boundary_end = NULL;
uint8_t expected_boundary_len = 0;
uint8_t expected_boundary_end_len = 0;
+ int tx_progress = 0;
#ifdef PRINT
printf("CHUNK START: \n");
SCLogDebug("header_start %p, header_end %p, form_end %p", header_start,
header_end, form_end);
+ /* we currently only handle multipart for ts. When we support it for tc,
+ * we will need to supply right direction */
+ tx_progress = AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0);
/* if we're in the file storage process, deal with that now */
if (htud->tsflags & HTP_FILENAME_SET) {
- if (header_start != NULL || form_end != NULL || (htud->tsflags & HTP_REQ_BODY_COMPLETE)) {
+ if (header_start != NULL || form_end != NULL || (tx_progress > HTP_REQUEST_BODY)) {
SCLogDebug("reached the end of the file");
uint8_t *filedata = chunks_buffer;
filedata_len = form_end - filedata;
} else if (form_end != NULL && form_end == header_start) {
filedata_len = form_end - filedata - 2; /* 0d 0a */
- } else if (htud->tsflags & HTP_REQ_BODY_COMPLETE) {
+ } else if (tx_progress > HTP_RESPONSE_BODY) {
filedata_len = chunks_buffer_len;
flags = FILE_TRUNCATED;
}
}
SCLogDebug("len %u", len);
- int r = HtpBodyAppendChunk(tx_ud, &tx_ud->request_body, (uint8_t *)d->data, len);
- if (r < 0) {
- tx_ud->tsflags |= HTP_REQ_BODY_COMPLETE;
- } else if (hstate->cfg->request_body_limit > 0 &&
- tx_ud->request_body.content_len_so_far >= hstate->cfg->request_body_limit)
- {
- tx_ud->tsflags |= HTP_REQ_BODY_COMPLETE;
- } else if (tx_ud->request_body.content_len_so_far == tx_ud->request_body.content_len) {
- tx_ud->tsflags |= HTP_REQ_BODY_COMPLETE;
- }
+ HtpBodyAppendChunk(tx_ud, &tx_ud->request_body, (uint8_t *)d->data, len);
uint8_t *chunks_buffer = NULL;
uint32_t chunks_buffer_len = 0;
printf("REASSCHUNK END: \n");
#endif
- HtpRequestBodyHandleMultipart(hstate, tx_ud, chunks_buffer, chunks_buffer_len);
+ HtpRequestBodyHandleMultipart(hstate, tx_ud, d->tx, chunks_buffer, chunks_buffer_len);
if (chunks_buffer != NULL) {
SCFree(chunks_buffer);
}
SCLogDebug("len %u", len);
- int r = HtpBodyAppendChunk(tx_ud, &tx_ud->response_body, (uint8_t *)d->data, len);
- if (r < 0) {
- tx_ud->tcflags |= HTP_RES_BODY_COMPLETE;
- } else if (hstate->cfg->response_body_limit > 0 &&
- tx_ud->response_body.content_len_so_far >= hstate->cfg->response_body_limit)
- {
- tx_ud->tcflags |= HTP_RES_BODY_COMPLETE;
- } else if (tx_ud->response_body.content_len_so_far == tx_ud->response_body.content_len) {
- tx_ud->tcflags |= HTP_RES_BODY_COMPLETE;
- }
+ HtpBodyAppendChunk(tx_ud, &tx_ud->response_body, (uint8_t *)d->data, len);
HtpResponseBodyHandle(hstate, tx_ud, d->tx, (uint8_t *)d->data, (uint32_t)d->len);
}
memset(&flow, 0x00, sizeof(flow));
AppLayerParserStateStore parser;
memset(&parser, 0x00, sizeof(parser));
+ htp_tx_t tx;
+ memset(&tx, 0, sizeof(tx));
hstate.f = &flow;
flow.alparser = &parser;
printf("REASSCHUNK END: \n");
#endif
- HtpRequestBodyHandleMultipart(&hstate, &htud, chunks_buffer, chunks_buffer_len);
+ HtpRequestBodyHandleMultipart(&hstate, &htud, &tx, chunks_buffer, chunks_buffer_len);
if (htud.request_body.content_len_so_far != 669) {
printf("htud.request_body.content_len_so_far %"PRIu64": ", htud.request_body.content_len_so_far);
uint64_t body_inspected;
} HtpBody;
-#define HTP_REQ_BODY_COMPLETE 0x01 /**< body is complete or limit is reached,
- either way, this is it. */
-#define HTP_RES_BODY_COMPLETE 0x02
-#define HTP_CONTENTTYPE_SET 0x04 /**< We have the content type */
-#define HTP_BOUNDARY_SET 0x08 /**< We have a boundary string */
-#define HTP_BOUNDARY_OPEN 0x10 /**< We have a boundary string */
-#define HTP_FILENAME_SET 0x20 /**< filename is registered in the flow */
-#define HTP_DONTSTORE 0x40 /**< not storing this file */
+#define HTP_CONTENTTYPE_SET 0x01 /**< We have the content type */
+#define HTP_BOUNDARY_SET 0x02 /**< We have a boundary string */
+#define HTP_BOUNDARY_OPEN 0x04 /**< We have a boundary string */
+#define HTP_FILENAME_SET 0x08 /**< filename is registered in the flow */
+#define HTP_DONTSTORE 0x10 /**< not storing this file */
#define HTP_TX_HAS_FILE 0x01
#define HTP_TX_HAS_FILENAME 0x02 /**< filename is known at this time */
goto end;
}
- /* in case of chunked transfer encoding, we don't have the length
- * of the request body until we see a chunk with length 0. This
- * doesn't let us use the request body callback function to
- * figure out the end of request body. Instead we do it here. If
- * the length is 0, and we have already seen content, it indicates
- * chunked transfer. We also check if the parser has truly seen
- * the last chunk by checking the progress state for the
- * transaction. If we are done parsing all the chunks, we would
- * have it set to something other than TX_PROGRESS_REQ_BODY.
- * Either ways we should be moving away from buffering in the end
- * and running content validation on this buffer type of architecture
- * to a stateful inspection, where we can inspect body chunks as and
- * when they come */
- if (htud->request_body.content_len == 0) {
- if ((htud->request_body.content_len_so_far > 0) &&
- tx->request_progress != HTP_REQUEST_BODY) {
- /* final length of the body */
- htud->tsflags |= HTP_REQ_BODY_COMPLETE;
- }
- } else {
- if (htud->request_body.content_len == (uint64_t)tx->request_entity_len) {
- SCLogDebug("content_len reached");
- htud->tsflags |= HTP_RES_BODY_COMPLETE;
- }
- }
-
- if (flags & STREAM_EOF) {
- htud->tsflags |= HTP_REQ_BODY_COMPLETE;
- }
-
/* inspect the body if the transfer is complete or we have hit
* our body size limit */
if (htud->request_body.content_len_so_far < htp_state->cfg->request_inspect_min_size &&
- !(htud->tsflags & HTP_REQ_BODY_COMPLETE)) {
+ !(AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 0) > HTP_REQUEST_BODY) &&
+ !(flags & STREAM_EOF)) {
SCLogDebug("we still haven't seen the entire request body. "
"Let's defer body inspection till we see the "
"entire body.");
goto end;
}
- /* in case of chunked transfer encoding, we don't have the length
- * of the response body until we see a chunk with length 0. This
- * doesn't let us use the response body callback function to
- * figure out the end of response body. Instead we do it here. If
- * the length is 0, and we have already seen content, it indicates
- * chunked transfer. We also check if the parser has truly seen
- * the last chunk by checking the progress state for the
- * transaction. If we are done parsing all the chunks, we would
- * have it set to something other than TX_PROGRESS_REQ_BODY.
- * Either ways we should be moving away from buffering in the end
- * and running content validation on this buffer type of architecture
- * to a stateful inspection, where we can inspect body chunks as and
- * when they come */
- if (htud->response_body.content_len == 0) {
- if ((htud->response_body.content_len_so_far > 0) &&
- tx->response_progress != HTP_RESPONSE_BODY) {
- /* final length of the body */
- htud->tcflags |= HTP_RES_BODY_COMPLETE;
- }
- } else {
- if (htud->response_body.content_len == (uint64_t)tx->response_entity_len) {
- SCLogDebug("content_len reached");
- htud->tcflags |= HTP_RES_BODY_COMPLETE;
- }
- }
-
- if (flags & STREAM_EOF) {
- htud->tcflags |= HTP_RES_BODY_COMPLETE;
- }
-
/* inspect the body if the transfer is complete or we have hit
* our body size limit */
if (htud->response_body.content_len_so_far < htp_state->cfg->response_inspect_min_size &&
- !(htud->tcflags & HTP_RES_BODY_COMPLETE)) {
+ !(AppLayerGetAlstateProgress(ALPROTO_HTTP, tx, 1) > HTP_RESPONSE_BODY) &&
+ !(flags & STREAM_EOF)) {
SCLogDebug("we still haven't seen the entire response body. "
"Let's defer body inspection till we see the "
"entire body.");
result = 1;
end:
+ HTPFreeConfig();
HtpConfigRestoreBackup();
ConfRestoreContextBackup();
result = 1;
end:
+ HTPFreeConfig();
HtpConfigRestoreBackup();
ConfRestoreContextBackup();