]> git.ipfire.org Git - thirdparty/rspamd.git/commitdiff
Parse incoming request url.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 10 Jul 2015 15:57:55 +0000 (16:57 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Fri, 10 Jul 2015 15:57:55 +0000 (16:57 +0100)
src/libserver/protocol.c
src/worker.c

index 45b720383c806fbe0da25af6413dffd65956c538..323838b6d81953d5d94438da16a827776056456e 100644 (file)
@@ -149,25 +149,41 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
 {
        GList *cur;
        struct custom_command *cmd;
+       struct http_parser_url u;
        const gchar *p;
+       gsize pathlen;
 
        if (msg->url == NULL || msg->url->len == 0) {
                g_set_error (&task->err, rspamd_protocol_quark(), 400, "missing command");
                return FALSE;
        }
 
-       if (msg->url->str[0] == '/') {
-               p = &msg->url->str[1];
+       if (http_parser_parse_url (msg->url->str, msg->url->len, 0, &u) != 0) {
+               g_set_error (&task->err, rspamd_protocol_quark(), 400, "bad request URL");
+
+               return FALSE;
        }
-       else {
-               p = msg->url->str;
+
+       if (!(u.field_set & (1 << UF_PATH))) {
+               g_set_error (&task->err, rspamd_protocol_quark(), 400,
+                               "bad request URL: missing path");
+
+               return FALSE;
+       }
+
+       p = msg->url->str + u.field_data[UF_PATH].off;
+       pathlen = u.field_data[UF_PATH].len;
+
+       if (*p == '/') {
+               p ++;
+               pathlen --;
        }
 
        switch (*p) {
        case 'c':
        case 'C':
                /* check */
-               if (g_ascii_strcasecmp (p + 1, MSG_CMD_CHECK + 1) == 0) {
+               if (g_ascii_strncasecmp (p + 1, MSG_CMD_CHECK + 1, pathlen) == 0) {
                        task->cmd = CMD_CHECK;
                }
                else {
@@ -177,10 +193,10 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
        case 's':
        case 'S':
                /* symbols, skip */
-               if (g_ascii_strcasecmp (p + 1, MSG_CMD_SYMBOLS + 1) == 0) {
+               if (g_ascii_strncasecmp (p + 1, MSG_CMD_SYMBOLS + 1, pathlen) == 0) {
                        task->cmd = CMD_SYMBOLS;
                }
-               else if (g_ascii_strcasecmp (p + 1, MSG_CMD_SKIP + 1) == 0) {
+               else if (g_ascii_strncasecmp (p + 1, MSG_CMD_SKIP + 1, pathlen) == 0) {
                        task->cmd = CMD_SKIP;
                }
                else {
@@ -190,10 +206,10 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
        case 'p':
        case 'P':
                /* ping, process */
-               if (g_ascii_strcasecmp (p + 1, MSG_CMD_PING + 1) == 0) {
+               if (g_ascii_strncasecmp (p + 1, MSG_CMD_PING + 1, pathlen) == 0) {
                        task->cmd = CMD_PING;
                }
-               else if (g_ascii_strcasecmp (p + 1, MSG_CMD_PROCESS + 1) == 0) {
+               else if (g_ascii_strncasecmp (p + 1, MSG_CMD_PROCESS + 1, pathlen) == 0) {
                        task->cmd = CMD_PROCESS;
                }
                else {
@@ -203,10 +219,11 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
        case 'r':
        case 'R':
                /* report, report_ifspam */
-               if (g_ascii_strcasecmp (p + 1, MSG_CMD_REPORT + 1) == 0) {
+               if (g_ascii_strncasecmp (p + 1, MSG_CMD_REPORT + 1, pathlen) == 0) {
                        task->cmd = CMD_REPORT;
                }
-               else if (g_ascii_strcasecmp (p + 1, MSG_CMD_REPORT_IFSPAM + 1) == 0) {
+               else if (g_ascii_strncasecmp (p + 1, MSG_CMD_REPORT_IFSPAM + 1,
+                               pathlen) == 0) {
                        task->cmd = CMD_REPORT_IFSPAM;
                }
                else {
@@ -217,7 +234,7 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
                cur = custom_commands;
                while (cur) {
                        cmd = cur->data;
-                       if (g_ascii_strcasecmp (p, cmd->name) == 0) {
+                       if (g_ascii_strncasecmp (p, cmd->name, pathlen) == 0) {
                                task->cmd = CMD_OTHER;
                                task->custom_cmd = cmd;
                                break;
@@ -234,8 +251,8 @@ rspamd_protocol_handle_url (struct rspamd_task *task,
        return TRUE;
 
 err:
-       g_set_error (&task->err, rspamd_protocol_quark(), 400, "invalid command: %s",
-                       p);
+       g_set_error (&task->err, rspamd_protocol_quark(), 400, "invalid command: %*.s",
+                       (gint)pathlen, p);
 
        return FALSE;
 }
index b935accf444e90c1486c3a794c2984345ae054fc..c0f30a94469ef160c9c3f4e626c4893f4b6b846f 100644 (file)
@@ -108,15 +108,19 @@ rspamd_worker_body_handler (struct rspamd_http_connection *conn,
        ctx = task->worker->ctx;
 
        if (!rspamd_protocol_handle_request (task, msg)) {
-               return 0;
+               msg_err ("cannot handle request: %e", task->err);
+               task->flags |= RSPAMD_TASK_FLAG_SKIP;
        }
-
-       if (task->cmd == CMD_PING) {
-               return 0;
-       }
-
-       if (!rspamd_task_load_message (task, msg, chunk, len)) {
-               return 0;
+       else {
+               if (task->cmd == CMD_PING) {
+                       task->flags |= RSPAMD_TASK_FLAG_SKIP;
+               }
+               else {
+                       if (!rspamd_task_load_message (task, msg, chunk, len)) {
+                               msg_err ("cannot load message: %e", task->err);
+                               task->flags |= RSPAMD_TASK_FLAG_SKIP;
+                       }
+               }
        }
 
        rspamd_task_process (task, RSPAMD_TASK_PROCESS_ALL);