|
24 | 24 |
|
25 | 25 | #include <event2/thread.h>
|
26 | 26 | #include <event2/buffer.h>
|
| 27 | +#include <event2/bufferevent.h> |
27 | 28 | #include <event2/util.h>
|
28 | 29 | #include <event2/keyvalq_struct.h>
|
29 | 30 |
|
@@ -239,6 +240,16 @@ static std::string RequestMethodString(HTTPRequest::RequestMethod m)
|
239 | 240 | /** HTTP request callback */
|
240 | 241 | static void http_request_cb(struct evhttp_request* req, void* arg)
|
241 | 242 | {
|
| 243 | + // Disable reading to work around a libevent bug, fixed in 2.2.0. |
| 244 | + if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) { |
| 245 | + evhttp_connection* conn = evhttp_request_get_connection(req); |
| 246 | + if (conn) { |
| 247 | + bufferevent* bev = evhttp_connection_get_bufferevent(conn); |
| 248 | + if (bev) { |
| 249 | + bufferevent_disable(bev, EV_READ); |
| 250 | + } |
| 251 | + } |
| 252 | + } |
242 | 253 | std::unique_ptr<HTTPRequest> hreq(new HTTPRequest(req));
|
243 | 254 |
|
244 | 255 | LogPrint(BCLog::HTTP, "Received a %s request for %s from %s\n",
|
@@ -601,8 +612,21 @@ void HTTPRequest::WriteReply(int nStatus, const std::string& strReply)
|
601 | 612 | struct evbuffer* evb = evhttp_request_get_output_buffer(req);
|
602 | 613 | assert(evb);
|
603 | 614 | evbuffer_add(evb, strReply.data(), strReply.size());
|
604 |
| - HTTPEvent* ev = new HTTPEvent(eventBase, true, |
605 |
| - std::bind(evhttp_send_reply, req, nStatus, (const char*)nullptr, (struct evbuffer *)nullptr)); |
| 615 | + auto req_copy = req; |
| 616 | + HTTPEvent* ev = new HTTPEvent(eventBase, true, [req_copy, nStatus]{ |
| 617 | + evhttp_send_reply(req_copy, nStatus, nullptr, nullptr); |
| 618 | + // Re-enable reading from the socket. This is the second part of the libevent |
| 619 | + // workaround above. |
| 620 | + if (event_get_version_number() >= 0x02010600 && event_get_version_number() < 0x02020001) { |
| 621 | + evhttp_connection* conn = evhttp_request_get_connection(req_copy); |
| 622 | + if (conn) { |
| 623 | + bufferevent* bev = evhttp_connection_get_bufferevent(conn); |
| 624 | + if (bev) { |
| 625 | + bufferevent_enable(bev, EV_READ | EV_WRITE); |
| 626 | + } |
| 627 | + } |
| 628 | + } |
| 629 | + }); |
606 | 630 | ev->trigger(nullptr);
|
607 | 631 | replySent = true;
|
608 | 632 | req = nullptr; // transferred back to main thread
|
|
0 commit comments