aboutsummaryrefslogtreecommitdiffstats
path: root/src/libutil
diff options
context:
space:
mode:
authorVsevolod Stakhov <vsevolod@highsecure.ru>2016-10-18 15:17:42 +0100
committerVsevolod Stakhov <vsevolod@highsecure.ru>2016-10-18 15:17:42 +0100
commit6fd9dcb0d8419b07460a174c6bd7baf78f6f3ebe (patch)
tree37027efcd366604c5e57c780bde462dd92d1c174 /src/libutil
parentf59abfc9be6018ceab2ea59a819ac22b8802eeac (diff)
downloadrspamd-6fd9dcb0d8419b07460a174c6bd7baf78f6f3ebe.tar.gz
rspamd-6fd9dcb0d8419b07460a174c6bd7baf78f6f3ebe.zip
[Fix] Fix handling of HTTP HEAD methods
Diffstat (limited to 'src/libutil')
-rw-r--r--src/libutil/http.c40
-rw-r--r--src/libutil/map.c2
-rw-r--r--src/libutil/ssl_util.c18
3 files changed, 54 insertions, 6 deletions
diff --git a/src/libutil/http.c b/src/libutil/http.c
index 0df6f190d..dedf8572d 100644
--- a/src/libutil/http.c
+++ b/src/libutil/http.c
@@ -617,6 +617,7 @@ rspamd_http_on_headers_complete (http_parser * parser)
(struct rspamd_http_connection *)parser->data;
struct rspamd_http_connection_private *priv;
struct rspamd_http_message *msg;
+ int ret;
priv = conn->priv;
msg = priv->msg;
@@ -628,6 +629,21 @@ rspamd_http_on_headers_complete (http_parser * parser)
priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
}
+ if (msg->method == HTTP_HEAD) {
+ /* We don't care about the rest */
+ if (event_pending (&priv->ev, EV_READ, NULL)) {
+ event_del (&priv->ev);
+ }
+
+ msg->code = parser->status_code;
+ rspamd_http_connection_ref (conn);
+ ret = conn->finish_handler (conn, msg);
+ conn->finished = TRUE;
+ rspamd_http_connection_unref (conn);
+
+ return ret;
+ }
+
/*
* HTTP parser sets content length to (-1) when it doesn't know the real
* length, for example, in case of chunked encoding.
@@ -758,8 +774,11 @@ rspamd_http_on_headers_complete_decrypted (http_parser *parser)
struct rspamd_http_connection *conn =
(struct rspamd_http_connection *) parser->data;
struct rspamd_http_connection_private *priv;
+ struct rspamd_http_message *msg;
+ int ret;
priv = conn->priv;
+ msg = priv->msg;
if (priv->header != NULL) {
rspamd_http_finish_header (conn, priv);
@@ -772,6 +791,21 @@ rspamd_http_on_headers_complete_decrypted (http_parser *parser)
priv->msg->flags |= RSPAMD_HTTP_FLAG_SPAMC;
}
+ if (msg->method == HTTP_HEAD) {
+ /* We don't care about the rest */
+ if (event_pending (&priv->ev, EV_READ, NULL)) {
+ event_del (&priv->ev);
+ }
+
+ msg->code = parser->status_code;
+ rspamd_http_connection_ref (conn);
+ ret = conn->finish_handler (conn, msg);
+ conn->finished = TRUE;
+ rspamd_http_connection_unref (conn);
+
+ return ret;
+ }
+
priv->msg->method = parser->method;
priv->msg->code = parser->status_code;
@@ -920,11 +954,13 @@ rspamd_http_simple_client_helper (struct rspamd_http_connection *conn)
struct event_base *base;
struct rspamd_http_connection_private *priv;
gpointer ssl;
+ gint request_method;
priv = conn->priv;
base = conn->priv->ev.ev_base;
ssl = priv->ssl;
priv->ssl = NULL;
+ request_method = priv->msg->method;
rspamd_http_connection_reset (conn);
priv->ssl = ssl;
/* Plan read message */
@@ -937,6 +973,8 @@ rspamd_http_simple_client_helper (struct rspamd_http_connection *conn)
rspamd_http_connection_read_message (conn, conn->ud, conn->fd,
conn->priv->ptv, base);
}
+
+ priv->msg->method = request_method;
}
static void
@@ -1148,8 +1186,6 @@ rspamd_http_event_handler (int fd, short what, gpointer ud)
"IO read error: unexpected EOF");
conn->error_handler (conn, err);
g_error_free (err);
-
-
}
REF_RELEASE (pbuf);
rspamd_http_connection_unref (conn);
diff --git a/src/libutil/map.c b/src/libutil/map.c
index 11c3ad32a..689f1b0c4 100644
--- a/src/libutil/map.c
+++ b/src/libutil/map.c
@@ -477,8 +477,8 @@ read_data:
goto err;
}
- map->read_callback (in, cbd->data_len, &cbd->periodic->cbdata, TRUE);
msg_info_map ("read map data from %s", cbd->data->host);
+ map->read_callback (in, cbd->data_len, &cbd->periodic->cbdata, TRUE);
/*
* We know that a map is in the locked state
diff --git a/src/libutil/ssl_util.c b/src/libutil/ssl_util.c
index 55d5a1ad4..c320dfd29 100644
--- a/src/libutil/ssl_util.c
+++ b/src/libutil/ssl_util.c
@@ -520,6 +520,11 @@ rspamd_ssl_read (struct rspamd_ssl_connection *conn, gpointer buf,
if (conn->state != ssl_conn_connected && conn->state != ssl_next_read) {
errno = EINVAL;
+ g_set_error (&err, rspamd_ssl_quark (), ECONNRESET,
+ "ssl state error: cannot read data");
+ conn->err_handler (conn->handler_data, err);
+ g_error_free (err);
+
return -1;
}
@@ -549,12 +554,13 @@ rspamd_ssl_read (struct rspamd_ssl_connection *conn, gpointer buf,
else {
ret = SSL_get_error (conn->ssl, ret);
conn->state = ssl_next_read;
+ what = 0;
if (ret == SSL_ERROR_WANT_READ) {
- what = EV_READ;
+ what |= EV_READ;
}
else if (ret == SSL_ERROR_WANT_WRITE) {
- what = EV_WRITE;
+ what |= EV_WRITE;
}
else {
g_set_error (&err, rspamd_ssl_quark (), ret,
@@ -603,8 +609,14 @@ rspamd_ssl_write (struct rspamd_ssl_connection *conn, gconstpointer buf,
ret = SSL_get_error (conn->ssl, ret);
if (ret == SSL_ERROR_ZERO_RETURN) {
+ g_set_error (&err, rspamd_ssl_quark (), ret,
+ "ssl write error: %s", ERR_error_string (ret, NULL));
+ conn->err_handler (conn->handler_data, err);
+ g_error_free (err);
+ errno = ECONNRESET;
conn->state = ssl_conn_reset;
- return 0;
+
+ return -1;
}
else {
g_set_error (&err, rspamd_ssl_quark (), ret,