|
26 | 26 | #include <event2/http.h> |
27 | 27 | #include <event2/thread.h> |
28 | 28 | #include <event2/buffer.h> |
| 29 | +#include <event2/bufferevent.h> |
29 | 30 | #include <event2/util.h> |
30 | 31 | #include <event2/keyvalq_struct.h> |
31 | 32 |
|
@@ -251,6 +252,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m) |
251 | 252 | /** HTTP request callback */ |
252 | 253 | static void http_request_cb(struct evhttp_request* req, void* arg) |
253 | 254 | { |
| 255 | + // Disable reading to work around a libevent bug, fixed in 2.2.0. |
| 256 | + if (event_get_version_number() < 0x02020001) { |
| 257 | + evhttp_connection* conn = evhttp_request_get_connection(req); |
| 258 | + if (conn) { |
| 259 | + bufferevent* bev = evhttp_connection_get_bufferevent(conn); |
| 260 | + if (bev) { |
| 261 | + bufferevent_disable(bev, EV_READ); |
| 262 | + } |
| 263 | + } |
| 264 | + } |
254 | 265 | std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req)); |
255 | 266 |
|
256 | 267 | LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n", |
@@ -615,9 +626,22 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply) |
615 | 626 | struct evbuffer* evb = evhttp_request_get_output_buffer(req); |
616 | 627 | assert(evb); |
617 | 628 | evbuffer_add(evb, strReply.data(), strReply.size()); |
618 | | - HTTPEvent* ev = new HTTPEvent(eventBase, true, |
619 | | - std::bind(evhttp_send_reply, req, nStatus, (const char*)NULL, (struct evbuffer *)NULL)); |
620 | | - ev->trigger(0); |
| 629 | + auto req_copy = req; |
| 630 | + HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{ |
| 631 | + evhttp_send_reply(req_copy, nStatus, nullptr, nullptr); |
| 632 | + // Re-enable reading from the socket. This is the second part of the libevent |
| 633 | + // workaround above. |
| 634 | + if (event_get_version_number() < 0x02020001) { |
| 635 | + evhttp_connection* conn = evhttp_request_get_connection(req_copy); |
| 636 | + if (conn) { |
| 637 | + bufferevent* bev = evhttp_connection_get_bufferevent(conn); |
| 638 | + if (bev) { |
| 639 | + bufferevent_enable(bev, EV_READ | EV_WRITE); |
| 640 | + } |
| 641 | + } |
| 642 | + } |
| 643 | + }); |
| 644 | + ev->trigger(nullptr); |
621 | 645 | replySent = true; |
622 | 646 | req = 0; // transferred back to main thread |
623 | 647 | } |
|
0 commit comments