Browse Source

[Rework] Stop using of uthash for http headers

tags/2.3
Vsevolod Stakhov 4 years ago
parent
commit
87def67d97

+ 3
- 3
src/client/rspamc.c View File

@@ -1277,11 +1277,11 @@ rspamc_stat_output (FILE *out, ucl_object_t *obj)
static void
rspamc_output_headers (FILE *out, struct rspamd_http_message *msg)
{
struct rspamd_http_header *h, *htmp;
struct rspamd_http_header *h;

HASH_ITER (hh, msg->headers, h, htmp) {
kh_foreach_value (msg->headers, h, {
rspamd_fprintf (out, "%T: %T\n", &h->name, &h->value);
}
});

rspamd_fprintf (out, "\n");
}

+ 3
- 3
src/libserver/protocol.c View File

@@ -450,10 +450,10 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,
{
rspamd_ftok_t *hn_tok, *hv_tok, srch;
gboolean has_ip = FALSE, seen_settings_header = FALSE;
struct rspamd_http_header *header, *h, *htmp;
struct rspamd_http_header *header, *h;
gchar *ntok;

HASH_ITER (hh, msg->headers, header, htmp) {
kh_foreach_value (msg->headers, header, {
DL_FOREACH (header, h) {
ntok = rspamd_mempool_ftokdup (task->task_pool, &h->name);
hn_tok = rspamd_mempool_alloc (task->task_pool, sizeof (*hn_tok));
@@ -702,7 +702,7 @@ rspamd_protocol_handle_headers (struct rspamd_task *task,

rspamd_task_add_request_header (task, hn_tok, hv_tok);
}
}
}); /* End of kh_foreach_value */

if (seen_settings_header && task->settings_elt) {
msg_warn_task ("ignore settings id %s as settings header is also presented",

+ 58
- 31
src/libutil/http_connection.c View File

@@ -243,6 +243,8 @@ rspamd_http_finish_header (struct rspamd_http_connection *conn,
struct rspamd_http_connection_private *priv)
{
struct rspamd_http_header *hdr;
khiter_t k;
gint r;

priv->header->combined = rspamd_fstring_append (priv->header->combined,
"\r\n", 2);
@@ -252,12 +254,15 @@ rspamd_http_finish_header (struct rspamd_http_connection *conn,
priv->header->name.len + 2;
priv->header->name.begin = priv->header->combined->str;

HASH_FIND (hh, priv->msg->headers, priv->header->name.begin,
priv->header->name.len, hdr);
k = kh_put (rspamd_http_headers_hash, priv->msg->headers, &priv->header->name,
&r);

if (hdr == NULL) {
HASH_ADD_KEYPTR (hh, priv->msg->headers, priv->header->name.begin,
priv->header->name.len, priv->header);
if (r != 0) {
kh_value (priv->msg->headers, k) = priv->header;
hdr = NULL;
}
else {
hdr = kh_value (priv->msg->headers, k);
}

DL_APPEND (hdr, priv->header);
@@ -565,7 +570,7 @@ rspamd_http_decrypt_message (struct rspamd_http_connection *conn,
const guchar *nm;
gsize dec_len;
struct rspamd_http_message *msg = priv->msg;
struct rspamd_http_header *hdr, *hdrtmp, *hcur, *hcurtmp;
struct rspamd_http_header *hdr, *hcur, *hcurtmp;
struct http_parser decrypted_parser;
struct http_parser_settings decrypted_cb;
enum rspamd_cryptobox_mode mode;
@@ -589,16 +594,15 @@ rspamd_http_decrypt_message (struct rspamd_http_connection *conn,
}

/* Cleanup message */
HASH_ITER (hh, msg->headers, hdr, hdrtmp) {
HASH_DELETE (hh, msg->headers, hdr);

kh_foreach_value (msg->headers, hdr, {
DL_FOREACH_SAFE (hdr, hcur, hcurtmp) {
rspamd_fstring_free (hcur->combined);
g_free (hcur);
}
}
});

msg->headers = NULL;
kh_destroy (rspamd_http_headers_hash, msg->headers);
msg->headers = kh_init (rspamd_http_headers_hash);

if (msg->url != NULL) {
msg->url = rspamd_fstring_assign (msg->url, "", 0);
@@ -1325,7 +1329,7 @@ struct rspamd_http_message *
rspamd_http_connection_copy_msg (struct rspamd_http_message *msg, GError **err)
{
struct rspamd_http_message *new_msg;
struct rspamd_http_header *hdr, *nhdr, *nhdrs, *thdr, *hcur;
struct rspamd_http_header *hdr, *nhdr, *nhdrs, *hcur;
const gchar *old_body;
gsize old_len;
struct stat st;
@@ -1420,7 +1424,7 @@ rspamd_http_connection_copy_msg (struct rspamd_http_message *msg, GError **err)
new_msg->date = msg->date;
new_msg->last_modified = msg->last_modified;

HASH_ITER (hh, msg->headers, hdr, thdr) {
kh_foreach_value (msg->headers, hdr, {
nhdrs = NULL;

DL_FOREACH (hdr, hcur) {
@@ -1429,17 +1433,25 @@ rspamd_http_connection_copy_msg (struct rspamd_http_message *msg, GError **err)
nhdr->combined = rspamd_fstring_new_init (hcur->combined->str,
hcur->combined->len);
nhdr->name.begin = nhdr->combined->str +
(hcur->name.begin - hcur->combined->str);
(hcur->name.begin - hcur->combined->str);
nhdr->name.len = hcur->name.len;
nhdr->value.begin = nhdr->combined->str +
(hcur->value.begin - hcur->combined->str);
(hcur->value.begin - hcur->combined->str);
nhdr->value.len = hcur->value.len;
DL_APPEND (nhdrs, nhdr);
}

HASH_ADD_KEYPTR (hh, new_msg->headers, nhdrs->name.begin,
nhdrs->name.len, nhdrs);
}
gint r;
khiter_t k = kh_put (rspamd_http_headers_hash, new_msg->headers,
&nhdrs->name,&r);

if (r != 0) {
kh_value (new_msg->headers, k) = nhdrs;
}
else {
DL_CONCAT (kh_value (new_msg->headers, k), nhdrs);
}
});

return new_msg;
}
@@ -1550,7 +1562,7 @@ rspamd_http_connection_encrypt_message (
const guchar *nm;
gint i, cnt;
guint outlen;
struct rspamd_http_header *hdr, *htmp, *hcur;
struct rspamd_http_header *hdr, *hcur;
enum rspamd_cryptobox_mode mode;

mode = rspamd_keypair_alg (priv->local_key);
@@ -1585,12 +1597,12 @@ rspamd_http_connection_encrypt_message (
}


HASH_ITER (hh, msg->headers, hdr, htmp) {
kh_foreach_value (msg->headers, hdr, {
DL_FOREACH (hdr, hcur) {
segments[i].data = hcur->combined->str;
segments[i++].len = hcur->combined->len;
}
}
});

/* crlfp should point now at the second crlf */
segments[i].data = crlfp;
@@ -1915,7 +1927,7 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
gboolean allow_shared)
{
struct rspamd_http_connection_private *priv = conn->priv;
struct rspamd_http_header *hdr, *htmp, *hcur;
struct rspamd_http_header *hdr, *hcur;
gchar repbuf[512], *pbody;
gint i, hdrcount, meth_len = 0, preludelen = 0;
gsize bodylen, enclen = 0;
@@ -1988,14 +2000,29 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
}

if (priv->ctx->config.user_agent && conn->type == RSPAMD_HTTP_CLIENT) {
struct rspamd_http_header *found = NULL;
rspamd_ftok_t srch;
khiter_t k;
gint r;

RSPAMD_FTOK_ASSIGN (&srch, "User-Agent");

HASH_FIND (hh, msg->headers, "User-Agent",
sizeof ("User-Agent") - 1, found);
k = kh_put (rspamd_http_headers_hash, msg->headers, &srch,&r);

if (!found) {
rspamd_http_message_add_header (msg, "User-Agent",
if (r != 0) {
hdr = g_malloc0 (sizeof (struct rspamd_http_header));
guint vlen = strlen (priv->ctx->config.user_agent);
hdr->combined = rspamd_fstring_sized_new (srch.len + vlen + 4);
rspamd_printf_fstring (&hdr->combined, "%T: %*s\r\n", &srch, vlen,
priv->ctx->config.user_agent);
hdr->name.begin = hdr->combined->str;
hdr->name.len = srch.len;
hdr->value.begin = hdr->combined->str + srch.len + 2;
hdr->value.len = vlen;
hdr->prev = hdr; /* for utlists */

kh_value (msg->headers, k) = hdr;
/* as we searched using static buffer */
kh_key (msg->headers, k) = &hdr->name;
}
}

@@ -2117,7 +2144,7 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
hdrcount = 0;

if (msg->method < HTTP_SYMBOLS) {
HASH_ITER (hh, msg->headers, hdr, htmp) {
kh_foreach_value (msg->headers, hdr, {
DL_FOREACH (hdr, hcur) {
/* <name: value\r\n> */
priv->wr_total += hcur->combined->len;
@@ -2125,7 +2152,7 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
priv->outlen ++;
hdrcount ++;
}
}
});
}

/* Allocate iov */
@@ -2195,12 +2222,12 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
else {
i = 1;
if (msg->method < HTTP_SYMBOLS) {
HASH_ITER (hh, msg->headers, hdr, htmp) {
kh_foreach_value (msg->headers, hdr, {
DL_FOREACH (hdr, hcur) {
priv->out[i].iov_base = hcur->combined->str;
priv->out[i++].iov_len = hcur->combined->len;
}
}
});

priv->out[i].iov_base = "\r\n";
priv->out[i++].iov_len = 2;

+ 55
- 27
src/libutil/http_message.c View File

@@ -39,6 +39,7 @@ rspamd_http_new_message (enum rspamd_http_message_type type)
new->port = 80;
new->type = type;
new->method = HTTP_INVALID;
new->headers = kh_init (rspamd_http_headers_hash);

REF_INIT_RETAIN (new, rspamd_http_message_free);

@@ -468,18 +469,16 @@ rspamd_http_message_storage_cleanup (struct rspamd_http_message *msg)
void
rspamd_http_message_free (struct rspamd_http_message *msg)
{
struct rspamd_http_header *hdr, *htmp, *hcur, *hcurtmp;


HASH_ITER (hh, msg->headers, hdr, htmp) {
HASH_DEL (msg->headers, hdr);
struct rspamd_http_header *hdr, *hcur, *hcurtmp;

kh_foreach_value (msg->headers, hdr, {
DL_FOREACH_SAFE (hdr, hcur, hcurtmp) {
rspamd_fstring_free (hcur->combined);
g_free (hcur);
}
}
});

kh_destroy (rspamd_http_headers_hash, msg->headers);
rspamd_http_message_storage_cleanup (msg);

if (msg->url != NULL) {
@@ -520,8 +519,10 @@ rspamd_http_message_add_header_len (struct rspamd_http_message *msg,
const gchar *value,
gsize len)
{
struct rspamd_http_header *hdr, *found = NULL;
struct rspamd_http_header *hdr, *found;
guint nlen, vlen;
khiter_t k;
gint r;

if (msg != NULL && name != NULL && value != NULL) {
hdr = g_malloc0 (sizeof (struct rspamd_http_header));
@@ -535,12 +536,15 @@ rspamd_http_message_add_header_len (struct rspamd_http_message *msg,
hdr->value.begin = hdr->combined->str + nlen + 2;
hdr->value.len = vlen;

HASH_FIND (hh, msg->headers, hdr->name.begin,
hdr->name.len, found);
k = kh_put (rspamd_http_headers_hash, msg->headers, &hdr->name,
&r);

if (found == NULL) {
HASH_ADD_KEYPTR (hh, msg->headers, hdr->name.begin,
hdr->name.len, hdr);
if (r != 0) {
kh_value (msg->headers, k) = hdr;
found = NULL;
}
else {
found = kh_value (msg->headers, k);
}

DL_APPEND (found, hdr);
@@ -564,6 +568,8 @@ rspamd_http_message_add_header_fstr (struct rspamd_http_message *msg,
{
struct rspamd_http_header *hdr, *found = NULL;
guint nlen, vlen;
khiter_t k;
gint r;

if (msg != NULL && name != NULL && value != NULL) {
hdr = g_malloc0 (sizeof (struct rspamd_http_header));
@@ -576,12 +582,15 @@ rspamd_http_message_add_header_fstr (struct rspamd_http_message *msg,
hdr->value.begin = hdr->combined->str + nlen + 2;
hdr->value.len = vlen;

HASH_FIND (hh, msg->headers, hdr->name.begin,
hdr->name.len, found);
k = kh_put (rspamd_http_headers_hash, msg->headers, &hdr->name,
&r);

if (found == NULL) {
HASH_ADD_KEYPTR (hh, msg->headers, hdr->name.begin,
hdr->name.len, hdr);
if (r != 0) {
kh_value (msg->headers, k) = hdr;
found = NULL;
}
else {
found = kh_value (msg->headers, k);
}

DL_APPEND (found, hdr);
@@ -592,15 +601,19 @@ const rspamd_ftok_t *
rspamd_http_message_find_header (struct rspamd_http_message *msg,
const gchar *name)
{
struct rspamd_http_header *hdr;
const rspamd_ftok_t *res = NULL;
rspamd_ftok_t srch;
guint slen = strlen (name);
khiter_t k;

if (msg != NULL) {
HASH_FIND (hh, msg->headers, name, slen, hdr);
srch.begin = name;
srch.len = slen;

k = kh_get (rspamd_http_headers_hash, msg->headers, &srch);

if (hdr) {
res = &hdr->value;
if (k != kh_end (msg->headers)) {
res = &(kh_value (msg->headers, k)->value);
}
}

@@ -614,14 +627,23 @@ rspamd_http_message_find_header_multiple (
{
GPtrArray *res = NULL;
struct rspamd_http_header *hdr, *cur;
rspamd_ftok_t srch;
khiter_t k;
guint cnt = 0;

guint slen = strlen (name);

if (msg != NULL) {
HASH_FIND (hh, msg->headers, name, slen, hdr);
srch.begin = name;
srch.len = slen;

if (hdr) {
res = g_ptr_array_sized_new (4);
k = kh_get (rspamd_http_headers_hash, msg->headers, &srch);

if (k != kh_end (msg->headers)) {
hdr = kh_value (msg->headers, k);

LL_COUNT (hdr, cur, cnt);
res = g_ptr_array_sized_new (cnt);

LL_FOREACH (hdr, cur) {
g_ptr_array_add (res, &cur->value);
@@ -641,12 +663,18 @@ rspamd_http_message_remove_header (struct rspamd_http_message *msg,
struct rspamd_http_header *hdr, *hcur, *hcurtmp;
gboolean res = FALSE;
guint slen = strlen (name);
rspamd_ftok_t srch;
khiter_t k;

if (msg != NULL) {
HASH_FIND (hh, msg->headers, name, slen, hdr);
srch.begin = name;
srch.len = slen;

k = kh_get (rspamd_http_headers_hash, msg->headers, &srch);

if (hdr) {
HASH_DEL (msg->headers, hdr);
if (k != kh_end (msg->headers)) {
hdr = kh_value (msg->headers, k);
kh_del (rspamd_http_headers_hash, msg->headers, k);
res = TRUE;

DL_FOREACH_SAFE (hdr, hcur, hcurtmp) {

+ 5
- 4
src/libutil/http_private.h View File

@@ -24,8 +24,6 @@
#include "ref.h"
#include "upstream.h"
#include "khash.h"
#define HASH_CASELESS
#include "uthash_strcase.h"

#ifdef __cplusplus
extern "C" {
@@ -38,10 +36,13 @@ struct rspamd_http_header {
rspamd_fstring_t *combined;
rspamd_ftok_t name;
rspamd_ftok_t value;
UT_hash_handle hh;
struct rspamd_http_header *prev, *next;
};

KHASH_INIT (rspamd_http_headers_hash, rspamd_ftok_t *,
struct rspamd_http_header *, 1,
rspamd_ftok_icase_hash, rspamd_ftok_icase_equal);

/**
* HTTP message structure, used for requests and replies
*/
@@ -49,7 +50,7 @@ struct rspamd_http_message {
rspamd_fstring_t *url;
GString *host;
rspamd_fstring_t *status;
struct rspamd_http_header *headers;
khash_t (rspamd_http_headers_hash) *headers;

struct _rspamd_body_buf_s {
/* Data start */

+ 6
- 6
src/lua/lua_http.c View File

@@ -221,7 +221,7 @@ lua_http_finish_handler (struct rspamd_http_connection *conn,
struct rspamd_http_message *msg)
{
struct lua_http_cbdata *cbd = (struct lua_http_cbdata *)conn->ud;
struct rspamd_http_header *h, *htmp;
struct rspamd_http_header *h;
const gchar *body;
gsize body_len;

@@ -275,7 +275,7 @@ lua_http_finish_handler (struct rspamd_http_connection *conn,
/* Headers */
lua_newtable (L);

HASH_ITER (hh, msg->headers, h, htmp) {
kh_foreach_value (msg->headers, h, {
/*
* Lowercase header name, as Lua cannot search in caseless matter
*/
@@ -283,7 +283,7 @@ lua_http_finish_handler (struct rspamd_http_connection *conn,
lua_pushlstring (L, h->name.begin, h->name.len);
lua_pushlstring (L, h->value.begin, h->value.len);
lua_settable (L, -3);
}
});

if (cbd->item) {
/* Replace watcher to deal with nested calls */
@@ -313,7 +313,7 @@ lua_http_resume_handler (struct rspamd_http_connection *conn,
lua_State *L = cbd->thread->lua_state;
const gchar *body;
gsize body_len;
struct rspamd_http_header *h, *htmp;
struct rspamd_http_header *h;

if (err) {
lua_pushstring (L, err);
@@ -363,7 +363,7 @@ lua_http_resume_handler (struct rspamd_http_connection *conn,
lua_pushliteral (L, "headers");
lua_newtable (L);

HASH_ITER (hh, msg->headers, h, htmp) {
kh_foreach_value (msg->headers, h, {
/*
* Lowercase header name, as Lua cannot search in caseless matter
*/
@@ -371,7 +371,7 @@ lua_http_resume_handler (struct rspamd_http_connection *conn,
lua_pushlstring (L, h->name.begin, h->name.len);
lua_pushlstring (L, h->value.begin, h->value.len);
lua_settable (L, -3);
}
});

lua_settable (L, -3);
}

Loading…
Cancel
Save