71 #define MAX_SIZE_HEADER_NAME 256
72 #define MAX_SIZE_HEADER_VALUE 2048
74 #define LOG_HTTP_DEFAULT 0
75 #define LOG_HTTP_EXTENDED 1
76 #define LOG_HTTP_REQUEST 2
77 #define LOG_HTTP_ARRAY 4
78 #define LOG_HTTP_REQ_HEADERS 8
79 #define LOG_HTTP_RES_HEADERS 16
164 {
"accept_range",
"accept-range", 0 },
166 {
"allow",
"allow", 0 },
167 {
"connection",
"connection", 0 },
168 {
"content_encoding",
"content-encoding", 0 },
169 {
"content_language",
"content-language", 0 },
170 {
"content_length",
"content-length", 0 },
171 {
"content_location",
"content-location", 0 },
172 {
"content_md5",
"content-md5", 0 },
173 {
"content_range",
"content-range", 0 },
174 {
"content_type",
"content-type", 0 },
175 {
"date",
"date", 0 },
176 {
"etag",
"etags", 0 },
177 {
"expires",
"expires" , 0 },
178 {
"last_modified",
"last-modified", 0 },
179 {
"link",
"link", 0 },
180 {
"location",
"location", 0 },
181 {
"proxy_authenticate",
"proxy-authenticate", 0 },
183 {
"refresh",
"refresh", 0 },
184 {
"retry_after",
"retry-after", 0 },
185 {
"server",
"server", 0 },
186 {
"set_cookie",
"set-cookie", 0 },
187 {
"trailer",
"trailer", 0 },
188 {
"transfer_encoding",
"transfer-encoding", 0 },
189 {
"upgrade",
"upgrade", 0 },
190 {
"vary",
"vary", 0 },
191 {
"warning",
"warning", 0 },
192 {
"www_authenticate",
"www-authenticate", 0 },
198 static void EveHttpLogJSONBasic(JsonBuilder *js, htp_tx_t *tx)
201 if (tx->request_hostname != NULL) {
202 jb_set_string_from_bytes(
203 js,
"hostname", bstr_ptr(tx->request_hostname), bstr_len(tx->request_hostname));
212 if (tx->request_port_number >= 0) {
213 jb_set_uint(js,
"http_port", tx->request_port_number);
217 if (tx->request_uri != NULL) {
218 jb_set_string_from_bytes(js,
"url", bstr_ptr(tx->request_uri), bstr_len(tx->request_uri));
221 if (tx->request_headers != NULL) {
223 htp_header_t *h_user_agent = htp_table_get_c(tx->request_headers,
"user-agent");
224 if (h_user_agent != NULL) {
225 jb_set_string_from_bytes(js,
"http_user_agent", bstr_ptr(h_user_agent->value),
226 bstr_len(h_user_agent->value));
230 htp_header_t *h_x_forwarded_for = htp_table_get_c(tx->request_headers,
"x-forwarded-for");
231 if (h_x_forwarded_for != NULL) {
232 jb_set_string_from_bytes(js,
"xff", bstr_ptr(h_x_forwarded_for->value),
233 bstr_len(h_x_forwarded_for->value));
238 if (tx->response_headers != NULL) {
239 htp_header_t *h_content_type = htp_table_get_c(tx->response_headers,
"content-type");
240 if (h_content_type != NULL) {
241 const size_t size = bstr_len(h_content_type->value) * 2 + 1;
243 BytesToStringBuffer(bstr_ptr(h_content_type->value), bstr_len(h_content_type->value),
string, size);
244 char *p = strchr(
string,
';');
247 jb_set_string(js,
"http_content_type",
string);
249 htp_header_t *h_content_range = htp_table_get_c(tx->response_headers,
"content-range");
250 if (h_content_range != NULL) {
251 jb_open_object(js,
"content_range");
252 jb_set_string_from_bytes(
253 js,
"raw", bstr_ptr(h_content_range->value), bstr_len(h_content_range->value));
254 HTTPContentRange crparsed;
256 if (crparsed.start >= 0)
257 jb_set_uint(js,
"start", crparsed.start);
258 if (crparsed.end >= 0)
259 jb_set_uint(js,
"end", crparsed.end);
260 if (crparsed.size >= 0)
261 jb_set_uint(js,
"size", crparsed.size);
268 static void EveHttpLogJSONCustom(
LogHttpFileCtx *http_ctx, JsonBuilder *js, htp_tx_t *tx)
275 if ((http_ctx->
fields & (1ULL<<f)) != 0)
283 htp_header_t *h_field = NULL;
286 if (tx->request_headers != NULL) {
287 h_field = htp_table_get_c(tx->request_headers,
291 if (tx->response_headers != NULL) {
292 h_field = htp_table_get_c(tx->response_headers,
296 if (h_field != NULL) {
297 c = bstr_util_strdup_to_c(h_field->value);
308 static void EveHttpLogJSONExtended(JsonBuilder *js, htp_tx_t *tx)
311 htp_header_t *h_referer = NULL;
312 if (tx->request_headers != NULL) {
313 h_referer = htp_table_get_c(tx->request_headers,
"referer");
315 if (h_referer != NULL) {
316 jb_set_string_from_bytes(
317 js,
"http_refer", bstr_ptr(h_referer->value), bstr_len(h_referer->value));
321 if (tx->request_method != NULL) {
322 jb_set_string_from_bytes(
323 js,
"http_method", bstr_ptr(tx->request_method), bstr_len(tx->request_method));
327 if (tx->request_protocol != NULL) {
328 jb_set_string_from_bytes(
329 js,
"protocol", bstr_ptr(tx->request_protocol), bstr_len(tx->request_protocol));
333 if (tx->response_status != NULL) {
334 const size_t status_size = bstr_len(tx->response_status) * 2 + 1;
335 char status_string[status_size];
337 status_string, status_size);
338 unsigned int val = strtoul(status_string, NULL, 10);
339 jb_set_uint(js,
"status", val);
341 htp_header_t *h_location = htp_table_get_c(tx->response_headers,
"location");
342 if (h_location != NULL) {
343 jb_set_string_from_bytes(
344 js,
"redirect", bstr_ptr(h_location->value), bstr_len(h_location->value));
349 jb_set_uint(js,
"length", tx->response_message_len);
352 static void EveHttpLogJSONHeaders(JsonBuilder *js, uint32_t direction, htp_tx_t *tx)
355 tx->request_headers : tx->response_headers;
358 size_t n = htp_table_size(headers);
360 for (
size_t i = 0; i < n; i++) {
361 htp_header_t * h = htp_table_get_index(headers, i, NULL);
368 memcpy(name, bstr_ptr(h->name), size_name);
369 name[size_name] =
'\0';
370 jb_set_string(js,
"name", name);
373 memcpy(value, bstr_ptr(h->value), size_value);
374 value[size_value] =
'\0';
375 jb_set_string(js,
"value", value);
382 static void BodyPrintableBuffer(JsonBuilder *js,
HtpBody *body,
const char *key)
384 if (body->
sb != NULL && body->
sb->
buf != NULL) {
386 const uint8_t *body_data;
387 uint32_t body_data_len;
388 uint64_t body_offset;
391 &body_data_len, &body_offset) == 0) {
395 uint8_t printable_buf[body_data_len + 1];
397 sizeof(printable_buf),
398 body_data, body_data_len);
400 jb_set_string(js, key, (
char *)printable_buf);
413 BodyPrintableBuffer(js, &htud->
request_body,
"http_request_body_printable");
414 BodyPrintableBuffer(js, &htud->
response_body,
"http_response_body_printable");
420 static void BodyBase64Buffer(JsonBuilder *js,
HtpBody *body,
const char *key)
422 if (body->
sb != NULL && body->
sb->
buf != NULL) {
423 const uint8_t *body_data;
424 uint32_t body_data_len;
425 uint64_t body_offset;
428 &body_data_len, &body_offset) == 0) {
432 jb_set_base64(js, key, body_data, body_data_len);
444 BodyBase64Buffer(js, &htud->
request_body,
"http_request_body");
445 BodyBase64Buffer(js, &htud->
response_body,
"http_response_body");
452 static void EveHttpLogJSON(
JsonHttpLogThread *aft, JsonBuilder *js, htp_tx_t *tx, uint64_t tx_id)
455 jb_open_object(js,
"http");
457 EveHttpLogJSONBasic(js, tx);
459 if (http_ctx->
fields != 0)
460 EveHttpLogJSONCustom(http_ctx, js, tx);
462 EveHttpLogJSONExtended(js, tx);
471 static int JsonHttpLogger(
ThreadVars *
tv,
void *thread_data,
const Packet *p,
Flow *f,
void *alstate,
void *txptr, uint64_t tx_id)
475 htp_tx_t *tx = txptr;
483 SCLogDebug(
"got a HTTP request and now logging !!");
485 EveHttpLogJSON(jhl, js, tx, tx_id);
498 jb_set_string(js,
"xff", buffer);
502 jb_set_string(js,
"dest_ip", buffer);
504 jb_set_string(js,
"src_ip", buffer);
523 EveHttpLogJSONBasic(js, tx);
524 EveHttpLogJSONExtended(js, tx);
532 static void OutputHttpLogDeinitSub(
OutputCtx *output_ctx)
550 memset(http_ctx, 0x00,
sizeof(*http_ctx));
564 if (extended != NULL) {
585 http_ctx->
fields |= (1ULL<<f);
593 conf,
"dump-all-headers");
594 if (all_headers != NULL) {
595 if (strncmp(all_headers,
"both", 4) == 0) {
598 }
else if (strncmp(all_headers,
"request", 7) == 0) {
600 }
else if (strncmp(all_headers,
"response", 8) == 0) {
608 if (http_ctx->
xff_cfg != NULL) {
615 output_ctx->
data = http_ctx;
616 output_ctx->
DeInit = OutputHttpLogDeinitSub;
621 result.
ctx = output_ctx;
626 static TmEcode JsonHttpLogThreadInit(
ThreadVars *t,
const void *initdata,
void **data)
634 SCLogDebug(
"Error getting context for EveLogHTTP. \"initdata\" argument NULL");
674 OutputHttpLogInitSub,
ALPROTO_HTTP1, JsonHttpLogger, JsonHttpLogThreadInit,
675 JsonHttpLogThreadDeinit, NULL);