aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2014-08-21 15:28:54 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2014-08-21 15:28:54 +0100
commit7b4f90b2919c85fcafa663c96c754eb10c3595b8 (patch)
tree908fb3f62629a1b96d86162b2f3e68fa98247d65 /src/libutil
parent0481887fdf5ecfccca2b703efadf84823b245f13 (diff)
downloadrspamd-7b4f90b2919c85fcafa663c96c754eb10c3595b8.tar.gz
rspamd-7b4f90b2919c85fcafa663c96c754eb10c3595b8.zip
Add URL parsing utility.
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/http.c68
-rw-r--r--src/libutil/http.h15
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