]> source.dussan.org Git - rspamd.git/commitdiff
Add URL parsing utility.
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 21 Aug 2014 14:28:54 +0000 (15:28 +0100)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Thu, 21 Aug 2014 14:28:54 +0000 (15:28 +0100)
src/libutil/http.c
src/libutil/http.h

index 7146a33c11008d5f0b40bbb6186e1a41c37bacaf..85e3e8540d8322b699b657974a462d4fead8ad59 100644 (file)
@@ -916,18 +916,20 @@ rspamd_http_connection_write_message (struct rspamd_http_connection *conn,
        }
        else {
                /* Format request */
-               if (host != NULL) {
+               if (host == NULL && msg->host == NULL) {
+                       /* Fallback to HTTP/1.0 */
+                       rspamd_printf_gstring (priv->buf, "%s %v HTTP/1.0\r\n"
+                                       "Content-Length: %z\r\n",
+                                       http_method_str (msg->method), msg->url, bodylen);
+               }
+               else {
                        rspamd_printf_gstring (priv->buf, "%s %v HTTP/1.1\r\n"
                                "Connection: close\r\n"
                                "Host: %s\r\n"
                                "Content-Length: %z\r\n",
-                               http_method_str (msg->method), msg->url, host, bodylen);
-               }
-               else {
-                       /* Fallback to HTTP/1.0 */
-                       rspamd_printf_gstring (priv->buf, "%s %v HTTP/1.0\r\n"
-                               "Content-Length: %z\r\n",
-                               http_method_str (msg->method), msg->url, bodylen);
+                               http_method_str (msg->method), msg->url,
+                               host != NULL ? host : msg->host->str,
+                               bodylen);
                }
        }
        /* Allocate iov */
@@ -993,12 +995,62 @@ rspamd_http_new_message (enum http_parser_type type)
        new->date = 0;
        new->body = NULL;
        new->status = NULL;
+       new->host = NULL;
+       new->port = 80;
        new->type = type;
        new->method = HTTP_GET;
 
        return new;
 }
 
+struct rspamd_http_message*
+rspamd_http_message_from_url (const gchar *url)
+{
+       struct http_parser_url pu;
+       struct rspamd_http_message *msg;
+       const gchar *host, *path;
+       size_t pathlen;
+
+       if (url == NULL) {
+               return NULL;
+       }
+
+       memset (&pu, 0, sizeof (pu));
+       if (http_parser_parse_url (url, strlen (url), TRUE, &pu) != 0) {
+               msg_warn ("cannot parse URL: %s", url);
+               return NULL;
+       }
+
+       if ((pu.field_set & (1 << UF_HOST)) == 0) {
+               msg_warn ("no host argument in URL: %s", url);
+               return NULL;
+       }
+       if ((pu.field_set & (1 << UF_PATH)) == 0) {
+               path = "/";
+               pathlen = 1;
+       }
+       else {
+               path = url + pu.field_data[UF_PATH].off;
+               pathlen = pu.field_data[UF_PATH].len;
+       }
+
+       msg = rspamd_http_new_message (HTTP_REQUEST);
+       host = url + pu.field_data[UF_HOST].off;
+
+       if ((pu.field_set & (1 << UF_PORT)) != 0) {
+               msg->port = pu.port;
+       }
+       else {
+               /* XXX: magic constant */
+               msg->port = 80;
+       }
+
+       msg->host = g_string_new_len (host, pu.field_data[UF_HOST].len);
+       g_string_append_len (msg->url, path, pathlen);
+
+       return msg;
+}
+
 void
 rspamd_http_message_free (struct rspamd_http_message *msg)
 {
index eefadee18f529e08d4ba0743666b63b462f8e767..c6fcf0b83ff704ab5f9f7451642b8325711dfa78 100644 (file)
@@ -53,6 +53,8 @@ struct rspamd_http_header {
  */
 struct rspamd_http_message {
        GString *url;
+       GString *host;
+       unsigned port;
        GString *status;
        struct rspamd_http_header *headers;
        GString *body;
@@ -211,12 +213,19 @@ rspamd_http_connection_unref (struct rspamd_http_connection *conn)
 void rspamd_http_connection_reset (struct rspamd_http_connection *conn);
 
 /**
- * Create new HTTP reply
- * @param code code to pass
- * @return new reply object
+ * Create new HTTP message
+ * @param type request or response
+ * @return new http message
  */
 struct rspamd_http_message * rspamd_http_new_message (enum http_parser_type type);
 
+/**
+ * Create HTTP message from URL
+ * @param url
+ * @return new message or NULL
+ */
+struct rspamd_http_message* rspamd_http_message_from_url (const gchar *url);
+
 /**
  * Append a header to reply
  * @param rep