From: Vsevolod Stakhov Date: Tue, 18 Oct 2016 14:17:42 +0000 (+0100) Subject: [Fix] Fix handling of HTTP HEAD methods X-Git-Tag: 1.4.0~229 X-Git-Url: https://source.dussan.org/?a=commitdiff_plain;h=6fd9dcb0d8419b07460a174c6bd7baf78f6f3ebe;p=rspamd.git [Fix] Fix handling of HTTP HEAD methods --- diff --git a/contrib/http-parser/http_parser.c b/contrib/http-parser/http_parser.c index 33f5ed301..2984471d4 100644 --- a/contrib/http-parser/http_parser.c +++ b/contrib/http-parser/http_parser.c @@ -95,7 +95,7 @@ do { \ FOR##_mark = NULL; \ } \ } while (0) - + /* Run the data callback FOR and consume the current byte */ #define CALLBACK_DATA(FOR) \ CALLBACK_DATA_(FOR, p - FOR##_mark, p - data + 1) 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,