]> granicus.if.org Git - libevent/commitdiff
http: fix EVHTTP_CON_READ_ON_WRITE_ERROR when it doesn't supported by OS
authorAzat Khuzhin <a3at.mail@gmail.com>
Fri, 11 Mar 2016 16:58:05 +0000 (19:58 +0300)
committerAzat Khuzhin <a3at.mail@gmail.com>
Fri, 11 Mar 2016 17:59:58 +0000 (20:59 +0300)
For example win32 doesn't accept such things (maybe via overloaded IO, I'm not
sure), also I looked into curl and seems that the behaviour is the same (IOW
like with EVHTTP_CON_READ_ON_WRITE_ERROR on linux/win32).

Fixes: https://ci.appveyor.com/project/nmathewson/libevent/build/2.1.5.216#L499 (win32)
Fixes: 680742e1665b85487f10c0ef3df021e3b8e98634 ("http: read server response
even after server closed the connection")
v2: v0 was just removing that flag, i.e. make it deprecated and set_flags() will return -1

http-internal.h
http.c

index 9647347c3eb085e481dce382b8e0560e9d7ebace..ae01f386aed96773b5d89edeb1d2172cc6ffbe13 100644 (file)
@@ -76,6 +76,9 @@ struct evhttp_connection {
 #define EVHTTP_CON_CLOSEDETECT 0x0004   /* detecting if persistent close */
 /* set when we want to auto free the connection */
 #define EVHTTP_CON_AUTOFREE    EVHTTP_CON_PUBLIC_FLAGS_END
+/* Installed when attempt to read HTTP error after write failed, see
+ * EVHTTP_CON_READ_ON_WRITE_ERROR */
+#define EVHTTP_CON_READING_ERROR       (EVHTTP_CON_AUTOFREE << 1)
 
        struct timeval timeout;         /* timeout for events */
        int retry_cnt;                  /* retry count */
diff --git a/http.c b/http.c
index 4849ff116dd56517cb8d97fe9dfb4207914fefad..cdadf48308791337422743a9adf3cbe5f4613e2b 100644 (file)
--- a/http.c
+++ b/http.c
@@ -1449,6 +1449,7 @@ evhttp_connection_read_on_write_error(struct evhttp_connection *evcon,
                evhttp_error_cb,
                evcon);
        evhttp_connection_start_detectclose(evcon);
+       evcon->flags |= EVHTTP_CON_READING_ERROR;
 }
 
 static void
@@ -1496,6 +1497,12 @@ evhttp_error_cb(struct bufferevent *bufev, short what, void *arg)
         */
        if (evcon->flags & EVHTTP_CON_CLOSEDETECT) {
                evcon->flags &= ~EVHTTP_CON_CLOSEDETECT;
+               if (evcon->flags & EVHTTP_CON_READING_ERROR) {
+                       evcon->flags &= ~EVHTTP_CON_READING_ERROR;
+                       evhttp_connection_fail_(evcon, EVREQ_HTTP_EOF);
+                       return;
+               }
+
                EVUTIL_ASSERT(evcon->http_server == NULL);
                /* For connections from the client, we just
                 * reset the connection so that it becomes