diff options
Diffstat (limited to 'src/libserver/protocol.c')
-rw-r--r-- | src/libserver/protocol.c | 127 |
1 files changed, 58 insertions, 69 deletions
diff --git a/src/libserver/protocol.c b/src/libserver/protocol.c index 221db1513..74b229c83 100644 --- a/src/libserver/protocol.c +++ b/src/libserver/protocol.c @@ -112,7 +112,7 @@ rspamd_protocol_quark (void) * Remove <> from the fixed string and copy it to the pool */ static gchar * -rspamd_protocol_escape_braces (struct rspamd_task *task, GString *in) +rspamd_protocol_escape_braces (struct rspamd_task *task, rspamd_fstring_t *in) { gint len = 0; gchar *orig, *p, *res; @@ -155,7 +155,7 @@ rspamd_protocol_handle_url (struct rspamd_task *task, struct http_parser_url u; const gchar *p; gsize pathlen; - GString lookup, *res, *key, *value; + rspamd_ftok_t *key, *value; gpointer k, v; if (msg->url == NULL || msg->url->len == 0) { @@ -257,29 +257,6 @@ rspamd_protocol_handle_url (struct rspamd_task *task, /* In case if we have a query, we need to store it somewhere */ query_args = rspamd_http_message_parse_query (msg); - lookup.str = (gchar *)"file"; - lookup.len = sizeof ("file") - 1; - - res = g_hash_table_lookup (query_args, &lookup); - - if (res == NULL) { - lookup.str = (gchar *)"path"; - lookup.len = sizeof ("path") - 1; - res = g_hash_table_lookup (query_args, &lookup); - } - - if (res == NULL) { - /* Treat the whole query as path */ - task->msg.begin = msg->url->str + u.field_data[UF_QUERY].off; - task->msg.len = u.field_data[UF_QUERY].len; - } - else { - task->msg.begin = rspamd_mempool_strdup (task->task_pool, res->str); - task->msg.len = res->len; - } - - task->flags |= RSPAMD_TASK_FLAG_FILE; - /* Insert the rest of query params as HTTP headers */ g_hash_table_iter_init (&it, query_args); @@ -308,20 +285,24 @@ rspamd_protocol_handle_headers (struct rspamd_task *task, struct rspamd_http_message *msg) { gchar *headern; - GString *hn, *hv; + rspamd_fstring_t *hn, *hv; + rspamd_ftok_t *hn_tok, *hv_tok; gboolean res = TRUE, validh, fl, has_ip = FALSE; gsize hlen; struct rspamd_http_header *h; LL_FOREACH (msg->headers, h) { - hn = g_string_new_len (h->name->str, h->name->len); - hv = g_string_new_len (h->value->str, h->value->len); + hn = rspamd_fstring_new_init (h->name->begin, h->name->len); + hv = rspamd_fstring_new_init (h->value->begin, h->value->len); + hn_tok = rspamd_ftok_map (hn); + hv_tok = rspamd_ftok_map (hv); + headern = hn->str; hlen = hn->len; validh = TRUE; - g_hash_table_insert (task->request_headers, hn, hv); + g_hash_table_insert (task->request_headers, hn_tok, hv_tok); switch (headern[0]) { case 'd': @@ -657,7 +638,7 @@ rspamd_protocol_handle_request (struct rspamd_task *task, } static void -write_hashes_to_log (struct rspamd_task *task, GString *logbuf) +write_hashes_to_log (struct rspamd_task *task, rspamd_fstring_t **logbuf) { struct mime_text_part *text_part; guint i; @@ -838,13 +819,13 @@ rspamd_str_list_ucl (GList *str_list) static ucl_object_t * rspamd_metric_symbol_ucl (struct rspamd_task *task, struct metric *m, - struct symbol *sym, GString *logbuf) + struct symbol *sym, rspamd_fstring_t **logbuf) { ucl_object_t *obj = NULL; const gchar *description = NULL; if (logbuf != NULL) { - rspamd_printf_gstring (logbuf, "%s,", sym->name); + rspamd_printf_fstring (logbuf, "%s,", sym->name); } if (sym->def != NULL) { @@ -871,7 +852,7 @@ rspamd_metric_symbol_ucl (struct rspamd_task *task, struct metric *m, static ucl_object_t * rspamd_metric_result_ucl (struct rspamd_task *task, struct metric_result *mres, - GString *logbuf) + rspamd_fstring_t **logbuf) { GHashTableIter hiter; struct symbol *sym; @@ -902,7 +883,7 @@ rspamd_metric_result_ucl (struct rspamd_task *task, } if (logbuf != NULL) { - rspamd_printf_gstring (logbuf, "(%s: %c (%s): [%.2f/%.2f] [", + rspamd_printf_fstring (logbuf, "(%s: %c (%s): [%.2f/%.2f] [", m->name, action_char, rspamd_action_to_str (action), mres->score, required_score); @@ -936,11 +917,13 @@ rspamd_metric_result_ucl (struct rspamd_task *task, if (logbuf != NULL) { /* Cut the trailing comma if needed */ - if (logbuf->str[logbuf->len - 1] == ',') { - logbuf->len--; + rspamd_fstring_t *log = *logbuf; + + if (log->str[log->len - 1] == ',') { + log->len--; } - rspamd_printf_gstring (logbuf, "]), len: %z, time: %s, dns req: %d,", + rspamd_printf_fstring (logbuf, "]), len: %z, time: %s, dns req: %d,", task->msg.len, rspamd_log_check_time (task->time_real, task->time_virtual, @@ -954,7 +937,7 @@ rspamd_metric_result_ucl (struct rspamd_task *task, static void rspamd_ucl_torspamc_output (struct rspamd_task *task, ucl_object_t *top, - GString *out) + rspamd_fstring_t **out) { const ucl_object_t *metric, *score, *required_score, *is_spam, *elt, *cur; @@ -965,14 +948,14 @@ rspamd_ucl_torspamc_output (struct rspamd_task *task, score = ucl_object_find_key (metric, "score"); required_score = ucl_object_find_key (metric, "required_score"); is_spam = ucl_object_find_key (metric, "is_spam"); - g_string_append_printf (out, + rspamd_printf_fstring (out, "Metric: default; %s; %.2f / %.2f / 0.0\r\n", ucl_object_toboolean (is_spam) ? "True" : "False", ucl_object_todouble (score), ucl_object_todouble (required_score)); elt = ucl_object_find_key (metric, "action"); if (elt != NULL) { - g_string_append_printf (out, "Action: %s\r\n", + rspamd_printf_fstring (out, "Action: %s\r\n", ucl_object_tostring (elt)); } @@ -981,7 +964,7 @@ rspamd_ucl_torspamc_output (struct rspamd_task *task, if (elt->type == UCL_OBJECT) { const ucl_object_t *sym_score; sym_score = ucl_object_find_key (elt, "score"); - g_string_append_printf (out, "Symbol: %s(%.2f)\r\n", + rspamd_printf_fstring (out, "Symbol: %s(%.2f)\r\n", ucl_object_key (elt), ucl_object_todouble (sym_score)); } @@ -989,7 +972,7 @@ rspamd_ucl_torspamc_output (struct rspamd_task *task, elt = ucl_object_find_key (metric, "subject"); if (elt != NULL) { - g_string_append_printf (out, "Subject: %s\r\n", + rspamd_printf_fstring (out, "Subject: %s\r\n", ucl_object_tostring (elt)); } } @@ -999,30 +982,31 @@ rspamd_ucl_torspamc_output (struct rspamd_task *task, iter = NULL; while ((cur = ucl_iterate_object (elt, &iter, true)) != NULL) { if (cur->type == UCL_STRING) { - g_string_append_printf (out, "Message: %s\r\n", + rspamd_printf_fstring (out, "Message: %s\r\n", ucl_object_tostring (cur)); } } } - g_string_append_printf (out, "Message-ID: %s\r\n", task->message_id); + rspamd_printf_fstring (out, "Message-ID: %s\r\n", task->message_id); } static void rspamd_ucl_tospamc_output (struct rspamd_task *task, ucl_object_t *top, - GString *out) + rspamd_fstring_t **out) { const ucl_object_t *metric, *score, *required_score, *is_spam, *elt; ucl_object_iter_t iter = NULL; + rspamd_fstring_t *f; metric = ucl_object_find_key (top, DEFAULT_METRIC); if (metric != NULL) { score = ucl_object_find_key (metric, "score"); required_score = ucl_object_find_key (metric, "required_score"); is_spam = ucl_object_find_key (metric, "is_spam"); - g_string_append_printf (out, + rspamd_printf_fstring (out, "Spam: %s ; %.2f / %.2f\r\n\r\n", ucl_object_toboolean (is_spam) ? "True" : "False", ucl_object_todouble (score), @@ -1030,20 +1014,22 @@ rspamd_ucl_tospamc_output (struct rspamd_task *task, while ((elt = ucl_iterate_object (metric, &iter, true)) != NULL) { if (elt->type == UCL_OBJECT) { - g_string_append_printf (out, "%s,", + rspamd_printf_fstring (out, "%s,", ucl_object_key (elt)); } } /* Ugly hack, but the whole spamc is ugly */ - if (out->str[out->len - 1] == ',') { - g_string_truncate (out, out->len - 1); - g_string_append (out, CRLF); + f = *out; + if (f->str[f->len - 1] == ',') { + f->len --; + + *out = rspamd_fstring_append (*out, CRLF, 2); } } } ucl_object_t * -rspamd_protocol_write_ucl (struct rspamd_task *task, GString *logbuf) +rspamd_protocol_write_ucl (struct rspamd_task *task, rspamd_fstring_t **logbuf) { struct metric_result *metric_res; ucl_object_t *top = NULL, *obj; @@ -1051,14 +1037,14 @@ rspamd_protocol_write_ucl (struct rspamd_task *task, GString *logbuf) gpointer h, v; if (logbuf != NULL) { - rspamd_printf_gstring (logbuf, + rspamd_printf_fstring (logbuf, "id: <%s>, qid: <%s>, ip: %s, ", task->message_id, task->queue_id, rspamd_inet_address_to_string (task->from_addr)); if (task->user) { - rspamd_printf_gstring (logbuf, "user: %s, ", task->user); + rspamd_printf_fstring (logbuf, "user: %s, ", task->user); } else if (task->from_envelope) { InternetAddress *ia; @@ -1068,7 +1054,7 @@ rspamd_protocol_write_ucl (struct rspamd_task *task, GString *logbuf) if (ia && INTERNET_ADDRESS_IS_MAILBOX (ia)) { InternetAddressMailbox *iamb = INTERNET_ADDRESS_MAILBOX (ia); - rspamd_printf_gstring (logbuf, "from: %s, ", iamb->addr); + rspamd_printf_fstring (logbuf, "from: %s, ", iamb->addr); } } } @@ -1109,7 +1095,7 @@ void rspamd_protocol_http_reply (struct rspamd_http_message *msg, struct rspamd_task *task) { - GString *logbuf; + rspamd_fstring_t *logbuf; struct metric_result *metric_res; GHashTableIter hiter; gpointer h, v; @@ -1118,40 +1104,42 @@ rspamd_protocol_http_reply (struct rspamd_http_message *msg, gint action; /* Output the first line - check status */ - logbuf = g_string_sized_new (BUFSIZ); + logbuf = rspamd_fstring_sized_new (1000); /* Write custom headers */ g_hash_table_iter_init (&hiter, task->reply_headers); while (g_hash_table_iter_next (&hiter, &h, &v)) { - GString *hn = (GString *)h, *hv = (GString *)v; + rspamd_ftok_t *hn = h, *hv = v; - rspamd_http_message_add_header (msg, hn->str, hv->str); + rspamd_http_message_add_header (msg, hn->begin, hv->begin); } - top = rspamd_protocol_write_ucl (task, logbuf); + top = rspamd_protocol_write_ucl (task, &logbuf); if (!(task->flags & RSPAMD_TASK_FLAG_NO_LOG)) { rspamd_roll_history_update (task->worker->srv->history, task); } if (!(task->flags & RSPAMD_TASK_FLAG_NO_LOG)) { - msg_info_task ("%v", logbuf); + msg_info_task ("%V", logbuf); } - g_string_free (logbuf, TRUE); - msg->body = g_string_sized_new (BUFSIZ); + rspamd_fstring_free (logbuf); + + msg->body = rspamd_fstring_sized_new (1000); if (msg->method < HTTP_SYMBOLS && !RSPAMD_TASK_IS_SPAMC (task)) { - rspamd_ucl_emit_gstring (top, UCL_EMIT_JSON_COMPACT, msg->body); + rspamd_ucl_emit_fstring (top, UCL_EMIT_JSON_COMPACT, &msg->body); } else { if (RSPAMD_TASK_IS_SPAMC (task)) { - rspamd_ucl_tospamc_output (task, top, msg->body); + rspamd_ucl_tospamc_output (task, top, &msg->body); } else { - rspamd_ucl_torspamc_output (task, top, msg->body); + rspamd_ucl_torspamc_output (task, top, &msg->body); } } + ucl_object_unref (top); if (!(task->flags & RSPAMD_TASK_FLAG_NO_STAT)) { @@ -1200,14 +1188,15 @@ rspamd_protocol_write_reply (struct rspamd_task *task) top = ucl_object_typed_new (UCL_OBJECT); msg->code = 500 + task->err->code % 100; - msg->status = g_string_new (task->err->message); + msg->status = rspamd_fstring_new_init (task->err->message, + strlen (task->err->message)); ucl_object_insert_key (top, ucl_object_fromstring (task->err->message), "error", 0, false); ucl_object_insert_key (top, ucl_object_fromstring (g_quark_to_string (task->err->domain)), "error_domain", 0, false); - msg->body = g_string_sized_new (256); - rspamd_ucl_emit_gstring (top, UCL_EMIT_JSON_COMPACT, msg->body); + msg->body = rspamd_fstring_sized_new (256); + rspamd_ucl_emit_fstring (top, UCL_EMIT_JSON_COMPACT, &msg->body); ucl_object_unref (top); } else { @@ -1221,7 +1210,7 @@ rspamd_protocol_write_reply (struct rspamd_task *task) rspamd_protocol_http_reply (msg, task); break; case CMD_PING: - msg->body = g_string_new ("pong" CRLF); + msg->body = rspamd_fstring_new_init ("pong" CRLF, 6); ctype = "text/plain"; break; case CMD_OTHER: |