const char *config_field;
const char *htp_field;
uint32_t flags;
-} http_fields[] = {
+} http_fields[] = {
{ "accept", "accept", LOG_HTTP_REQUEST },
{ "accept_charset", "accept-charset", LOG_HTTP_REQUEST },
{ "accept_encoding", "accept-encoding", LOG_HTTP_REQUEST },
{ "accept_datetime", "accept-datetime", LOG_HTTP_REQUEST },
{ "authorization", "authorization", LOG_HTTP_REQUEST },
{ "cache_control", "cache-control", LOG_HTTP_REQUEST },
- { "cookie", "cookie", LOG_HTTP_REQUEST|LOG_HTTP_ARRAY },
+ { "cookie", "cookie", LOG_HTTP_REQUEST | LOG_HTTP_ARRAY },
{ "from", "from", LOG_HTTP_REQUEST },
{ "max_forwards", "max-forwards", LOG_HTTP_REQUEST },
{ "origin", "origin", LOG_HTTP_REQUEST },
{ "content_type", "content-type", 0 },
{ "date", "date", 0 },
{ "etag", "etags", 0 },
- { "expires", "expires" , 0 },
+ { "expires", "expires", 0 },
{ "last_modified", "last-modified", 0 },
{ "link", "link", 0 },
{ "location", "location", 0 },
{ "proxy_authenticate", "proxy-authenticate", 0 },
- { "referrer", "referrer", LOG_HTTP_EXTENDED },
+ { "referer", "referer", LOG_HTTP_EXTENDED },
{ "refresh", "refresh", 0 },
{ "retry_after", "retry-after", 0 },
{ "server", "server", 0 },
}
}
-static void EveHttpLogJSONCustom(LogHttpFileCtx *http_ctx, JsonBuilder *js, htp_tx_t *tx)
-{
- char *c;
- HttpField f;
-
- for (f = HTTP_FIELD_ACCEPT; f < HTTP_FIELD_SIZE; f++)
- {
- if ((http_ctx->fields & (1ULL<<f)) != 0)
- {
- /* prevent logging a field twice if extended logging is
- enabled */
- if (((http_ctx->flags & LOG_HTTP_EXTENDED) == 0) ||
- ((http_ctx->flags & LOG_HTTP_EXTENDED) !=
- (http_fields[f].flags & LOG_HTTP_EXTENDED)))
- {
- htp_header_t *h_field = NULL;
- if ((http_fields[f].flags & LOG_HTTP_REQUEST) != 0)
- {
- if (tx->request_headers != NULL) {
- h_field = htp_table_get_c(tx->request_headers,
- http_fields[f].htp_field);
- }
- } else {
- if (tx->response_headers != NULL) {
- h_field = htp_table_get_c(tx->response_headers,
- http_fields[f].htp_field);
- }
- }
- if (h_field != NULL) {
- c = bstr_util_strdup_to_c(h_field->value);
- if (c != NULL) {
- jb_set_string(js, http_fields[f].config_field, c);
- SCFree(c);
- }
- }
- }
- }
- }
-}
-
static void EveHttpLogJSONExtended(JsonBuilder *js, htp_tx_t *tx)
{
/* referer */
jb_set_uint(js, "length", tx->response_message_len);
}
-static void EveHttpLogJSONHeaders(JsonBuilder *js, uint32_t direction, htp_tx_t *tx)
+static void EveHttpLogJSONHeaders(
+ JsonBuilder *js, uint32_t direction, htp_tx_t *tx, LogHttpFileCtx *http_ctx)
{
htp_table_t * headers = direction & LOG_HTTP_REQ_HEADERS ?
tx->request_headers : tx->response_headers;
char name[MAX_SIZE_HEADER_NAME] = {0};
char value[MAX_SIZE_HEADER_VALUE] = {0};
size_t n = htp_table_size(headers);
+ JsonBuilderMark mark = { 0, 0, 0 };
+ jb_get_mark(js, &mark);
+ bool array_empty = true;
jb_open_array(js, direction & LOG_HTTP_REQ_HEADERS ? "request_headers" : "response_headers");
for (size_t i = 0; i < n; i++) {
htp_header_t * h = htp_table_get_index(headers, i, NULL);
if (h == NULL) {
continue;
}
+ if ((http_ctx->flags & direction) == 0 && http_ctx->fields != 0) {
+ bool tolog = false;
+ for (HttpField f = HTTP_FIELD_ACCEPT; f < HTTP_FIELD_SIZE; f++) {
+ if ((http_ctx->fields & (1ULL << f)) != 0) {
+ /* prevent logging a field twice if extended logging is
+ enabled */
+ if (((http_ctx->flags & LOG_HTTP_EXTENDED) == 0) ||
+ ((http_ctx->flags & LOG_HTTP_EXTENDED) !=
+ (http_fields[f].flags & LOG_HTTP_EXTENDED))) {
+ if (bstr_cmp_c_nocase(h->name, http_fields[f].htp_field) == 0) {
+ tolog = true;
+ break;
+ }
+ }
+ }
+ }
+ if (!tolog) {
+ continue;
+ }
+ }
+ array_empty = false;
jb_start_object(js);
size_t size_name = bstr_len(h->name) < MAX_SIZE_HEADER_NAME - 1 ?
bstr_len(h->name) : MAX_SIZE_HEADER_NAME - 1;
jb_set_string(js, "value", value);
jb_close(js);
}
- // Close array.
- jb_close(js);
+ if (array_empty) {
+ jb_restore_mark(js, &mark);
+ } else {
+ // Close array.
+ jb_close(js);
+ }
}
static void BodyPrintableBuffer(JsonBuilder *js, HtpBody *body, const char *key)
jb_open_object(js, "http");
EveHttpLogJSONBasic(js, tx);
- /* log custom fields if configured */
- if (http_ctx->fields != 0)
- EveHttpLogJSONCustom(http_ctx, js, tx);
if (http_ctx->flags & LOG_HTTP_EXTENDED)
EveHttpLogJSONExtended(js, tx);
- if (http_ctx->flags & LOG_HTTP_REQ_HEADERS)
- EveHttpLogJSONHeaders(js, LOG_HTTP_REQ_HEADERS, tx);
- if (http_ctx->flags & LOG_HTTP_RES_HEADERS)
- EveHttpLogJSONHeaders(js, LOG_HTTP_RES_HEADERS, tx);
+ if (http_ctx->flags & LOG_HTTP_REQ_HEADERS || http_ctx->fields != 0)
+ EveHttpLogJSONHeaders(js, LOG_HTTP_REQ_HEADERS, tx, http_ctx);
+ if (http_ctx->flags & LOG_HTTP_RES_HEADERS || http_ctx->fields != 0)
+ EveHttpLogJSONHeaders(js, LOG_HTTP_RES_HEADERS, tx, http_ctx);
jb_close(js);
}
}
}
+ const char *all_headers = ConfNodeLookupChildValue(conf, "dump-all-headers");
+ if (all_headers != NULL) {
+ if (strncmp(all_headers, "both", 4) == 0) {
+ http_ctx->flags |= LOG_HTTP_REQ_HEADERS;
+ http_ctx->flags |= LOG_HTTP_RES_HEADERS;
+ } else if (strncmp(all_headers, "request", 7) == 0) {
+ http_ctx->flags |= LOG_HTTP_REQ_HEADERS;
+ } else if (strncmp(all_headers, "response", 8) == 0) {
+ http_ctx->flags |= LOG_HTTP_RES_HEADERS;
+ }
+ }
ConfNode *custom;
if ((custom = ConfNodeLookupChild(conf, "custom")) != NULL) {
+ if ((http_ctx->flags & (LOG_HTTP_REQ_HEADERS | LOG_HTTP_RES_HEADERS)) ==
+ (LOG_HTTP_REQ_HEADERS | LOG_HTTP_RES_HEADERS)) {
+ SCLogWarning("No need for custom as dump-all-headers is already present");
+ }
ConfNode *field;
TAILQ_FOREACH (field, &custom->head, next) {
HttpField f;
}
}
}
- const char *all_headers = ConfNodeLookupChildValue(
- conf, "dump-all-headers");
- if (all_headers != NULL) {
- if (strncmp(all_headers, "both", 4) == 0) {
- http_ctx->flags |= LOG_HTTP_REQ_HEADERS;
- http_ctx->flags |= LOG_HTTP_RES_HEADERS;
- } else if (strncmp(all_headers, "request", 7) == 0) {
- http_ctx->flags |= LOG_HTTP_REQ_HEADERS;
- } else if (strncmp(all_headers, "response", 8) == 0) {
- http_ctx->flags |= LOG_HTTP_RES_HEADERS;
- }
- }
}
if (conf != NULL && ConfNodeLookupChild(conf, "xff") != NULL) {