From 2ff164abac40d827fd35e0b4436d22137c1cc0b4 Mon Sep 17 00:00:00 2001 From: Azat Khuzhin Date: Fri, 11 Mar 2016 19:58:05 +0300 Subject: [PATCH] http: fix EVHTTP_CON_READ_ON_WRITE_ERROR when it doesn't supported by OS 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 | 3 +++ http.c | 7 +++++++ 2 files changed, 10 insertions(+) diff --git a/http-internal.h b/http-internal.h index 9647347c..ae01f386 100644 --- a/http-internal.h +++ b/http-internal.h @@ -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 4849ff11..cdadf483 100644 --- 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