diff options
author | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2014-08-21 15:28:54 +0100 |
---|---|---|
committer | Vsevolod Stakhov <vsevolod@highsecure.ru> | 2014-08-21 15:28:54 +0100 |
commit | 7b4f90b2919c85fcafa663c96c754eb10c3595b8 (patch) | |
tree | 908fb3f62629a1b96d86162b2f3e68fa98247d65 /src/libutil | |
parent | 0481887fdf5ecfccca2b703efadf84823b245f13 (diff) | |
download | rspamd-7b4f90b2919c85fcafa663c96c754eb10c3595b8.tar.gz rspamd-7b4f90b2919c85fcafa663c96c754eb10c3595b8.zip |
Add URL parsing utility.
Diffstat (limited to 'src/libutil')
-rw-r--r-- | src/libutil/http.c | 68 | ||||
-rw-r--r-- | src/libutil/http.h | 15 |
2 files changed, 72 insertions, 11 deletions
diff --git a/src/libutil/http.c b/src/libutil/http.c index 7146a33c1..85e3e8540 100644 --- a/src/libutil/http.c +++ b/src/libutil/http.c @@ -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) { diff --git a/src/libutil/http.h b/src/libutil/http.h index eefadee18..c6fcf0b83 100644 --- a/src/libutil/http.h +++ b/src/libutil/http.h @@ -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,13 +213,20 @@ 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 * @param name |