]> source.dussan.org Git - rspamd.git/commitdiff
[Fix] Fix HTTP(s) client timeout
authorVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 5 Jan 2022 21:36:58 +0000 (21:36 +0000)
committerVsevolod Stakhov <vsevolod@highsecure.ru>
Wed, 5 Jan 2022 21:36:58 +0000 (21:36 +0000)
src/libserver/http/http_connection.c
src/libserver/ssl_util.c
src/libserver/ssl_util.h

index afd685ae08639f7422d715824a4ff7c7f381ed84..d247328197cfcb0b7a36ad77b0f771a2dec21718 100644 (file)
@@ -91,6 +91,8 @@ static const rspamd_ftok_t last_modified_header = {
                .len = 13
 };
 
+static void rspamd_http_event_handler (int fd, short what, gpointer ud);
+static void rspamd_http_ssl_err_handler (gpointer ud, GError *err);
 
 
 #define HTTP_ERROR http_error_quark ()
@@ -1030,54 +1032,48 @@ rspamd_http_event_handler (int fd, short what, gpointer ud)
                }
        }
        else if (what == EV_TIMEOUT) {
-               /* Let's try to read from the socket first */
-               r = rspamd_http_try_read (fd, conn, priv, pbuf, &d);
+               if (!priv->ssl) {
+                       /* Let's try to read from the socket first */
+                       r = rspamd_http_try_read(fd, conn, priv, pbuf, &d);
+
+                       if (r > 0) {
+                               if (http_parser_execute(&priv->parser, &priv->parser_cb,
+                                               d, r) != (size_t) r || priv->parser.http_errno != 0) {
+                                       err = g_error_new(HTTP_ERROR, 400,
+                                                       "HTTP parser error: %s",
+                                                       http_errno_description(priv->parser.http_errno));
+
+                                       if (!conn->finished) {
+                                               conn->error_handler(conn, err);
+                                       }
+                                       else {
+                                               msg_err ("got error after HTTP request is finished: %e", err);
+                                       }
 
-               if (r > 0) {
-                       if (http_parser_execute (&priv->parser, &priv->parser_cb,
-                                       d, r) != (size_t)r || priv->parser.http_errno != 0) {
-                               err = g_error_new (HTTP_ERROR, 400,
-                                               "HTTP parser error: %s",
-                                               http_errno_description (priv->parser.http_errno));
+                                       g_error_free(err);
 
-                               if (!conn->finished) {
-                                       conn->error_handler (conn, err);
-                               }
-                               else {
-                                       msg_err ("got error after HTTP request is finished: %e", err);
-                               }
+                                       REF_RELEASE (pbuf);
+                                       rspamd_http_connection_unref(conn);
 
-                               g_error_free (err);
+                                       return;
+                               }
+                       }
+                       else {
+                               err = g_error_new(HTTP_ERROR, 408,
+                                               "IO timeout");
+                               conn->error_handler(conn, err);
+                               g_error_free(err);
 
                                REF_RELEASE (pbuf);
-                               rspamd_http_connection_unref (conn);
+                               rspamd_http_connection_unref(conn);
 
                                return;
                        }
                }
-               else if (r == 0) {
-                       if (!conn->finished && !priv->ssl) {
-                               err = g_error_new (HTTP_ERROR, 408,
-                                               "IO timeout");
-                               conn->error_handler (conn, err);
-                               g_error_free (err);
-
-                       }
-                       REF_RELEASE (pbuf);
-                       rspamd_http_connection_unref (conn);
-
-                       return;
-               }
                else {
-                       if (!priv->ssl) {
-                               err = g_error_new(HTTP_ERROR, 408,
-                                               "IO timeout");
-                               conn->error_handler(conn, err);
-                               g_error_free(err);
-                       }
-
+                       /* In case of SSL we disable this logic as we already came from SSL handler */
                        REF_RELEASE (pbuf);
-                       rspamd_http_connection_unref (conn);
+                       rspamd_http_connection_unref(conn);
 
                        return;
                }
@@ -1536,9 +1532,18 @@ rspamd_http_connection_read_message_common (struct rspamd_http_connection *conn,
        priv->buf->data = rspamd_fstring_sized_new (8192);
        priv->flags |= RSPAMD_HTTP_CONN_FLAG_NEW_HEADER;
 
-       rspamd_ev_watcher_init (&priv->ev, conn->fd, EV_READ,
-                       rspamd_http_event_handler, conn);
-       rspamd_ev_watcher_start (priv->ctx->event_loop, &priv->ev, priv->timeout);
+       if (!priv->ssl) {
+               rspamd_ev_watcher_init(&priv->ev, conn->fd, EV_READ,
+                               rspamd_http_event_handler, conn);
+               rspamd_ev_watcher_start(priv->ctx->event_loop, &priv->ev, priv->timeout);
+       }
+       else {
+               rspamd_ssl_connection_restore_handlers (priv->ssl,
+                               rspamd_http_event_handler,
+                               rspamd_http_ssl_err_handler,
+                               conn,
+                               EV_READ);
+       }
 
        priv->flags &= ~RSPAMD_HTTP_CONN_FLAG_RESETED;
 }
@@ -2351,7 +2356,8 @@ rspamd_http_connection_write_message_common (struct rspamd_http_connection *conn
                                rspamd_ssl_connection_restore_handlers (priv->ssl,
                                                rspamd_http_event_handler,
                                                rspamd_http_ssl_err_handler,
-                                               conn);
+                                               conn,
+                                               EV_WRITE);
                        }
                }
        }
index 319e87a0498c30ea783a3abb835608cee02c2f35..0aa859dbfcf68ef07130a9c36d02dd638dd0cb91 100644 (file)
@@ -760,14 +760,15 @@ void
 rspamd_ssl_connection_restore_handlers (struct rspamd_ssl_connection *conn,
                                                                                rspamd_ssl_handler_t handler,
                                                                                rspamd_ssl_error_handler_t err_handler,
-                                                                               gpointer handler_data)
+                                                                               gpointer handler_data,
+                                                                               short ev_what)
 {
        conn->handler = handler;
        conn->err_handler = err_handler;
        conn->handler_data = handler_data;
 
        rspamd_ev_watcher_stop (conn->event_loop, conn->ev);
-       rspamd_ev_watcher_init (conn->ev, conn->fd, EV_WRITE, rspamd_ssl_event_handler, conn);
+       rspamd_ev_watcher_init (conn->ev, conn->fd, ev_what, rspamd_ssl_event_handler, conn);
        rspamd_ev_watcher_start (conn->event_loop, conn->ev, conn->ev->timeout);
 }
 
index f2d591b563c7b2f06ebceac0e1e876f8380c6b4f..7c804421fd9c28ac4cdb81e2e1361abae0ec0737 100644 (file)
@@ -66,7 +66,8 @@ gboolean rspamd_ssl_connect_fd (struct rspamd_ssl_connection *conn, gint fd,
 void rspamd_ssl_connection_restore_handlers (struct rspamd_ssl_connection *conn,
                                                                                         rspamd_ssl_handler_t handler,
                                                                                         rspamd_ssl_error_handler_t err_handler,
-                                                                                        gpointer handler_data);
+                                                                                        gpointer handler_data,
+                                                                                        short ev_what);
 
 /**
  * Perform async read from SSL socket