http.c


Log

Author Commit Date CI Message
Azat Khuzhin 97e28f09 2020-06-25T09:08:31 Check error code of evhttp_add_header_internal() in evhttp_parse_query_impl() (cherry picked from commit 4528d8e98781be794cbce13394f8442dd466684b)
Azat Khuzhin 1be25938 2020-05-19T11:45:43 http: fix EVHTTP_CON_AUTOFREE in case of timeout (and some else) Refs: #182 (cherry picked from commit eee26deed38fc7a6b6780b54628b007a2810efcd)
Azat Khuzhin e2424229 2020-01-12T15:34:51 Merge branch 'http-connect' After this patchset http-connect works with pproxy [1]: $ pproxy -l http://:8000/ -vvv & $ http-connect //127.1:8000 http://kernel.org:80/ [1]: https://pypi.org/project/pproxy/ * http-connect: http-connect: do not check connection on GET cb http-connect: set Host header (for CONNECT and GET) (like curl) http-connect: cleanup and helpers http: do not close connection for CONNECT http: do not assume body for CONNECT Fixes: #946 (cherry picked from commit 462f2e97660cc2b6af563ab631050a83c3e0935b)
Azat Khuzhin 1b42270b 2020-01-12T13:43:18 http: do not assume body for CONNECT (cherry picked from commit 998e68340e5cd289a16f340cc5c625e984e1f762)
yuangongji c169bdcb 2019-09-18T23:12:59 http: rename bind_socket_ai() to create_bind_socket_nonblock() (cherry picked from commit 0cd536b0b33d2aa59cee3805846f81cf4e4a5ce9)
Azat Khuzhin e2790a7f 2019-05-25T23:41:38 http: do not name variable "sun" since this breaks solaris builds -bash-3.2$ /opt/csw/bin/gcc -xc /dev/null -dM -E | grep '#define sun' #define sun 1 (cherry picked from commit 1c573ab3a9037c560981ea325170ca6044c2dff6)
Azat Khuzhin 7c4da937 2019-05-12T19:06:43 Merge branch 'issue-807-accept4-getnameinfo-AF_UNIX' * issue-807-accept4-getnameinfo-AF_UNIX: http-server: add usage/help dialog http: avoid use of uninitialized value for AF_UNIX/AF_LOCAL sockaddr http-server: add ability to bind to unix-socket build: struct sockaddr_un detection (sys/un.h, afunix.h) Fixes: #807 (cherry picked from commit 76eded24d3b0c3fc48c5a888906cc9043223101b)
Azat Khuzhin eb7b472b 2019-01-29T01:18:39 Merge branch 'http-EVHTTP_CON_READ_ON_WRITE_ERROR-fixes-v2' * http-EVHTTP_CON_READ_ON_WRITE_ERROR-fixes-v2: http: try to read existing data in buffer under EVHTTP_CON_READ_ON_WRITE_ERROR test: add logging for http/read_on_write_error and rearrange code http: do not call deferred readcb if readcb is not set Refs: #749 (cherry picked from commit 7bfe93886d7fccad2d9a6c76cf47c47d3668f9d1)
Luke Dashjr 2ccd00a6 2018-12-28T04:42:20 http: Preserve socket error from listen across closesocket cleanup Closes: #738 (cherry-picked) (cherry picked from commit 28d7221b851093611c65b5961e138403dd7332b6)
Azat Khuzhin d30e7bba 2018-12-07T21:46:27 http: fix connection retries when there more then one request for connection We should not attemp to establishe the connection if there is retry timer active, since otherwise there will be a bug. Imagine next situation: con = evhttp_connection_base_new() evhttp_connection_set_retries(con, 2) req = evhttp_request_new() evhttp_make_request(con, req, ...) # failed during connecting, and timer for 2 second scheduler (retry_ev) Then another request scheduled for this evcon: evhttp_make_request(con, req, ...) # got request from server, # and now it tries to read the response from the server # (req.kind == EVHTTP_RESPONSE) # # but at this point retry_ev scheduled, # and it schedules the connect again, # and after the connect will succeeed, it will pick request with # EVHTTP_RESPONSE for sending and this is completelly wrong and will # fail in evhttp_make_header_response() since there is no # "http_server" for this evcon This was a long standing issue, that I came across few years ago firstly, bad only now I had time to dig into it (but right now it was pretty simple, by limiting amount of CPU for the process and using rr for debug to go back and forth). (cherry picked from commit f3f7aa5afff2c0be4a1a299a1a7d0a64558abc23)
Azat Khuzhin a8cc449e 2018-11-14T00:20:20 http: improve error path for bufferevent_{setfd,enable,disable}() We have calls to the next functions but do not check return values, though they can be invalid and it is better to show this somehow. Also do bufferevent_setfd() first and only after it bufferevent_enable()/bufferevent_disable() since: a) it is more natural b) it will avoid extra operations c) it will not fail first bufferevent_enable() (this is the case for buffbufferevent_async at least) In this case we could add more information for issues like #709 (cherry picked from commit b98d32d0c90864ff60bc689f3bcf738af58ca79c)
Azat Khuzhin 6ac2ec25 2018-11-13T21:26:12 Fix conceivable UAF of the bufferevent in evhttp_connection_free() Although this is not a problem, since bufferevent uses finalizers and will free itself only from the loop (well this is not a problem if you do not play games with various event_base in different threads) it generates questions, so rewrite it in more reliable way. Fixes: #712 (cherry picked from commit 5dc88b387f7baa4bcd528832e94987a85be3b263)
Azat Khuzhin cdcfbafe 2018-10-23T00:12:23 Merge branch 'http-request-line-parsing' * http-request-line-parsing: Fix http https_basic/https_filter_basic under valgrind (increase timeout) http: cover various non RFC3986 conformant URIs http: allow non RFC3986 conformant during parsing request-line (http server) http: do not try to parse request-line if we do not have enough bytes http: allow trailing spaces (and only them) in request-line (like nginx) http: cleanup of the request-line parsing (cherry picked from commit 0ec12bc84cf09307e01dc3b00d08ac1f816b6ff7)
Nathan French 0d5dde53 2018-07-05T12:46:51 [http] fix C90 warnings (cherry picked from commit 514dc7579c43e673bdf613e01690371438661260)
Greg Hazel 4215c003 2018-02-11T16:28:58 Fix evhttp_connection_get_addr() fox incomming http connections Install conn_address of the bufferevent on incomping http connections (even though this is kind of subsytem violation, so let's fix it in a simplest way and thinkg about long-term solution). Fixes: #510 Closes: #595 (pick) (cherry picked from commit 367cd9e5c2b8e3f9b8dbed40bfe8a0ed79285c36)
Azat Khuzhin 0dfabd34 2018-02-13T17:43:02 http: remove message in case !Content-Length and Connection!=close Since [1] GET can have body, and hence for every incomming connection it will print this error. [1] db483e3b002b33890fc88cadd77f6fd1fccad2d2 ("Allow bodies for GET/DELETE/OPTIONS/CONNECT") Noticed-by: BotoX (irc) Refs: #408 (cherry picked from commit cd57e38c3f77d0f6a718d9c1f2e3ead78a98bd06)
Azat Khuzhin 123362e9 2018-01-09T21:44:57 http: fix leaks in evhttp_uriencode() Fixes: #584 (cherry picked from commit 61c21492680505706cad9240c39666ee3b56a89c)
Greg Hazel 7d1ffe64 2017-12-02T12:53:57 CONNECT method only takes an authority (cherry picked from commit 65eb529a9f4dd886d01a9d77ce6d971de9fb1b97)
Azat Khuzhin b2581380 2017-11-04T19:13:28 Fix crashing http server when callback do not reply in place from *gencb* This is the second hunk of the first patch 5ff8eb26371c4dc56f384b2de35bea2d87814779 ("Fix crashing http server when callback do not reply in place") Fixes: #567 (cherry picked from commit 306747e51c1f0de679a3b165b9429418c89f8d6a)
Azat Khuzhin 23eb38b9 2017-10-29T22:53:41 Allow bodies for GET/DELETE/OPTIONS/CONNECT I checked with nginx, and via it's lua bindings it allows body for all this methods. Also everybody knows that some of web-servers allows body for GET even though this is not RFC conformant. Refs: #408 (cherry picked from commit db483e3b002b33890fc88cadd77f6fd1fccad2d2)
Andreas Gustafsson 826f1134 2017-09-26T19:23:29 Do not crash when evhttp_send_reply_start() is called after a timeout. This fixes the crash reported in issue #509. The "would be nice" items discussed in #509 can be addressed separately. (cherry picked from commit 99d0a952dada771b91acf63f5208b994e80a2986)
Azat Khuzhin 5b40744d 2017-10-23T00:13:37 Fix crashing http server when callback do not reply in place General http callback looks like: static void http_cb(struct evhttp_request *req, void *arg) { evhttp_send_reply(req, HTTP_OK, "Everything is fine", NULL); } And they will work fine becuase in this case http will write request first, and during write preparation it will disable *read callback* (in evhttp_write_buffer()), but if we don't reply immediately, for example: static void http_cb(struct evhttp_request *req, void *arg) { return; } This will leave connection in incorrect state, and if another request will be written to the same connection libevent will abort with: [err] ../http.c: illegal connection state 7 Because it thinks that read for now is not possible, since there were no write. Fix this by disabling EV_READ entirely. We couldn't just reset callbacks because this will leave EOF detection, which we don't need, since user hasn't replied to callback yet. Reported-by: Cory Fields <cory@coryfields.com> (cherry picked from commit 5ff8eb26371c4dc56f384b2de35bea2d87814779)
Azat Khuzhin 7e91622b 2017-09-13T21:39:32 fix handling of close_notify (ssl) in http with openssl bufferevents Since it can arrive after we disabled events in that bufferevent and reseted fd, hence evhttp_error_cb() could be called after SSL_RECEIVED_SHUTDOWN. Closes: #557 (cherry picked from commit da3f2ba22adcabaf7355a90d537b4928d0c168d2)
Vis Virial db60ade8 2016-11-10T21:58:15 http: do not use local settings for Date header
Azat Khuzhin 1cbf26f6 2016-12-06T11:51:18 http: fix formatter for pritnf for req->ntoread (osx)
Thomas Bernard e9837124 2014-12-13T19:42:42 use ev_uint16_t instead of unsigned short for port Like in `sockaddr_in` structure in /usr/include/netinet/in.h @azat: convert all other users (bench, compat, ..) and tweak message Fixes: #178 Fixes: #196 Refs: 6bf1ca78 Link: https://codereview.appspot.com/156040043/#msg4
Zonr Chang c6b1ec12 2016-08-24T17:16:32 Fix evhttp_uriencode() regression. http_uriencode_test() (in test/regress_http.c) has been failed after 72afe4c as "hello\0world" is encoded to "hello" instead of "hello%00world". This is because of a misplaced overflow check which causes the non-negative "size" specified in parameter being ignored in within-bound URI. Fixes: #392
Mark Ellzey e94250c8 2016-08-14T14:03:56 removed unused vars
Mark Ellzey 72afe4c9 2016-08-14T14:00:02 pointer overflow checks for evhttp_uriencode Check to make sure pointer math is all OK.
Mark Ellzey 17cc6362 2016-06-24T18:07:39 [Issue #313] set method to ASCII "NULL" if evhttp_method() returns NULL
Azat Khuzhin 24b52149 2016-03-25T10:21:48 evhttp_have_expect(): fix -Wlogical-not-parentheses ../http.c:589:6: warning: logical not is only applied to the left hand side of this comparison [-Wlogical-not-parentheses] if (!req->kind == EVHTTP_REQUEST || !REQ_VERSION_ATLEAST(req, 1, 1)) ^ ~~
Azat Khuzhin 7a4b4729 2016-03-24T13:38:05 http: set fd to -1 unconditioally, to avoid leaking of DNS requests Otherwise: http/cancel_by_host_ns_timeout_inactive_server: [msg] Nameserver 127.0.0.1:37035 has failed: request timed out. [msg] All nameservers have failed OK 1 tests ok. (0 skipped) ==26211== ==26211== FILE DESCRIPTORS: 3 open at exit. ==26211== Open file descriptor 2: /dev/pts/47 ==26211== <inherited from parent> ==26211== ==26211== Open file descriptor 1: /dev/pts/47 ==26211== <inherited from parent> ==26211== ==26211== Open file descriptor 0: /dev/pts/47 ==26211== <inherited from parent> ==26211== ==26211== ==26211== HEAP SUMMARY: ==26211== in use at exit: 1,112 bytes in 5 blocks ==26211== total heap usage: 149 allocs, 144 frees, 18,826 bytes allocated ==26211== ==26211== 40 bytes in 1 blocks are indirectly lost in loss record 1 of 5 ==26211== at 0x4C2BBD5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26211== by 0x4AAEB2: event_mm_calloc_ (event.c:3459) ==26211== by 0x498F5B: evbuffer_add_cb (buffer.c:3309) ==26211== by 0x4A0EF5: bufferevent_socket_new (bufferevent_sock.c:366) ==26211== by 0x4BFADF: evhttp_connection_base_bufferevent_new (http.c:2375) ==26211== by 0x4BFC8F: evhttp_connection_base_new (http.c:2427) ==26211== by 0x460DAA: http_cancel_test (regress_http.c:1417) ==26211== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==26211== by 0x490D5A: testcase_run_one (tinytest.c:252) ==26211== by 0x491699: tinytest_main (tinytest.c:434) ==26211== by 0x47E0E0: main (regress_main.c:461) ==26211== ==26211== 136 bytes in 1 blocks are indirectly lost in loss record 2 of 5 ==26211== at 0x4C2BBD5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26211== by 0x4AAEB2: event_mm_calloc_ (event.c:3459) ==26211== by 0x491FF0: evbuffer_new (buffer.c:365) ==26211== by 0x49A1BE: bufferevent_init_common_ (bufferevent.c:300) ==26211== by 0x4A0E44: bufferevent_socket_new (bufferevent_sock.c:353) ==26211== by 0x4BFADF: evhttp_connection_base_bufferevent_new (http.c:2375) ==26211== by 0x4BFC8F: evhttp_connection_base_new (http.c:2427) ==26211== by 0x460DAA: http_cancel_test (regress_http.c:1417) ==26211== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==26211== by 0x490D5A: testcase_run_one (tinytest.c:252) ==26211== by 0x491699: tinytest_main (tinytest.c:434) ==26211== by 0x47E0E0: main (regress_main.c:461) ==26211== ==26211== 136 bytes in 1 blocks are indirectly lost in loss record 3 of 5 ==26211== at 0x4C2BBD5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26211== by 0x4AAEB2: event_mm_calloc_ (event.c:3459) ==26211== by 0x491FF0: evbuffer_new (buffer.c:365) ==26211== by 0x49A1FB: bufferevent_init_common_ (bufferevent.c:305) ==26211== by 0x4A0E44: bufferevent_socket_new (bufferevent_sock.c:353) ==26211== by 0x4BFADF: evhttp_connection_base_bufferevent_new (http.c:2375) ==26211== by 0x4BFC8F: evhttp_connection_base_new (http.c:2427) ==26211== by 0x460DAA: http_cancel_test (regress_http.c:1417) ==26211== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==26211== by 0x490D5A: testcase_run_one (tinytest.c:252) ==26211== by 0x491699: tinytest_main (tinytest.c:434) ==26211== by 0x47E0E0: main (regress_main.c:461) ==26211== ==26211== 536 bytes in 1 blocks are indirectly lost in loss record 4 of 5 ==26211== at 0x4C2BBD5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26211== by 0x4AAEB2: event_mm_calloc_ (event.c:3459) ==26211== by 0x4A0E15: bufferevent_socket_new (bufferevent_sock.c:350) ==26211== by 0x4BFADF: evhttp_connection_base_bufferevent_new (http.c:2375) ==26211== by 0x4BFC8F: evhttp_connection_base_new (http.c:2427) ==26211== by 0x460DAA: http_cancel_test (regress_http.c:1417) ==26211== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==26211== by 0x490D5A: testcase_run_one (tinytest.c:252) ==26211== by 0x491699: tinytest_main (tinytest.c:434) ==26211== by 0x47E0E0: main (regress_main.c:461) ==26211== ==26211== 1,112 (264 direct, 848 indirect) bytes in 1 blocks are definitely lost in loss record 5 of 5 ==26211== at 0x4C2BBD5: calloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==26211== by 0x4AAEB2: event_mm_calloc_ (event.c:3459) ==26211== by 0x4D0564: evdns_getaddrinfo (evdns.c:4685) ==26211== by 0x4B13BA: evutil_getaddrinfo_async_ (evutil.c:1575) ==26211== by 0x4A139E: bufferevent_socket_connect_hostname (bufferevent_sock.c:524) ==26211== by 0x4C02DB: evhttp_connection_connect_ (http.c:2588) ==26211== by 0x4C04DD: evhttp_make_request (http.c:2643) ==26211== by 0x4615FF: http_cancel_test (regress_http.c:1504) ==26211== by 0x490A78: testcase_run_bare_ (tinytest.c:105) ==26211== by 0x490D5A: testcase_run_one (tinytest.c:252) ==26211== by 0x491699: tinytest_main (tinytest.c:434) ==26211== by 0x47E0E0: main (regress_main.c:461) ==26211== ==26211== LEAK SUMMARY: ==26211== definitely lost: 264 bytes in 1 blocks ==26211== indirectly lost: 848 bytes in 4 blocks ==26211== possibly lost: 0 bytes in 0 blocks ==26211== still reachable: 0 bytes in 0 blocks ==26211== suppressed: 0 bytes in 0 blocks
Azat Khuzhin f0e13411 2016-03-22T23:36:19 http: avoid leaking of fd in evhttp_connection_free() Since we do close fd there if we don't have BEV_OPT_CLOSE_ON_FREE, and evcon->fd can be incorrect (non -1), so just get it from the underlying bufferevent to fix this. And after this patch the following tests report 0 instead of 2307 fd leaks: $ valgrind --leak-check=full --show-reachable=yes --track-fds=yes --error-exitcode=1 regress --no-fork http/cancel.. ==11299== FILE DESCRIPTORS: 3 open at exit. And this is stdin/stderr/stdout.
Azat Khuzhin 4a53c54b 2016-03-22T19:29:50 http: get fd from be layer during connection reset Since it can be non -1, and we must close it, otherwise we will have problems. And after this patch the following tests report fd 2307 instead of 2309 fd leaks: $ valgrind --leak-check=full --show-reachable=yes --track-fds=yes --error-exitcode=1 regress --no-fork http/cancel.. ==10853== FILE DESCRIPTORS: 2307 open at exit.
Azat Khuzhin d4054928 2016-03-11T20:17:51 http: make fallback for EVHTTP_CON_READ_ON_WRITE_ERROR more cleaner
Azat Khuzhin 2ff164ab 2016-03-11T19:58:05 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
Azat Khuzhin 7c899995 2016-03-11T19:52:32 http: do not do function calls under EVUTIL_ASSERT() to fix NDEBUG builds Fixes: 2185e639210f072f37e9d19aff7dba382db84529 ("http: assert's that evbuffer_drain() success on connection reset") Fixes: http/data_length_constraints FAIL ../test/regress_http.c:3775: assert(evhttp_request_get_response_code(req) == HTTP_ENTITYTOOLARGE): 501 vs 413
Azat Khuzhin 8f18a626 2016-03-11T20:40:52 http: fix leaking of response_code_line Since now evhttp_parse_response_line() can be called twice because after "HTTP/1.1 100 Continue" we can have "HTTP/1.1 200" ==29162== 9 bytes in 1 blocks are definitely lost in loss record 1 of 1 ==29162== at 0x4C29C0F: malloc (in /usr/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==29162== by 0x5CBF0A9: strdup (in /lib/x86_64-linux-gnu/libc-2.21.so) ==29162== by 0x4AA3AC: event_mm_strdup_ (event.c:3493) ==29162== by 0x4BD843: evhttp_parse_response_line (http.c:1680) ==29162== by 0x4BE333: evhttp_parse_firstline_ (http.c:2013) ==29162== by 0x4BEA4F: evhttp_read_firstline (http.c:2243) ==29162== by 0x4BC5F8: evhttp_read_cb (http.c:1136) ==29162== by 0x4993F1: bufferevent_run_readcb_ (bufferevent.c:233) ==29162== by 0x49FBC0: bufferevent_trigger_nolock_ (bufferevent-internal.h:392) ==29162== by 0x49FF10: bufferevent_readcb (bufferevent_sock.c:208) ==29162== by 0x4A474A: event_persist_closure (event.c:1580) ==29162== by 0x4A49F5: event_process_active_single_queue (event.c:1639) Fixes: 0b46b39e95ad77951176f09782138305ba34edf3 ("http: fix "Expect: 100-continue" client side")
Azat Khuzhin 0b46b39e 2016-03-11T13:08:28 http: fix "Expect: 100-continue" client side Instead of sending data always at the beginning of the request wait until the server will respond with "HTTP/1.1 100 Continue". Before this patch server do send "HTTP/1.1 100 Continue" but client always send post data even without waiting server response. P.S. this patch also touches some not 100% related tab-align issues. Covered-by: http/data_length_constraints Covered-by: http/read_on_write_error
Azat Khuzhin 2185e639 2016-03-11T14:02:13 http: assert's that evbuffer_drain() success on connection reset Since otherwise we can have nasty bugs with part of previous *request* in current *request* and hence some parsing errors. And now we have failures: http/non_lingering_close: [forking] [err] ../http.c:1326: Assertion !evbuffer_drain(tmp, -1) failed in ../http.c
Azat Khuzhin ac448a74 2016-02-15T03:26:40 http: take EVHTTP_CON_LINGERING_CLOSE into account for "Expect: 100-Continue" Also since after this patch code became more generic, we now respond with HTTP_ENTITYTOOLARGE even without "Expect: 100-Continue", which is correct by RFC. Refs: #321 v2: remove EVHTTP_CON_ABOUT_TO_CLOSE
Azat Khuzhin 9fde5189 2016-02-15T00:12:54 http: lingering close (like nginx have) for entity-too-large By lingering close I mean something what nginx have for this name, by this term I mean that we need to read all the body even if it's size greater then `max_body_size`, otherwise browsers on win32 (including chrome) failed read the http status - entity-too-large (while on linux chrome for instance are good), and also this includes badly written http clients. Refs: #321 v2: do this only under EVHTTP_SERVER_LINGERING_CLOSE
Azat Khuzhin 680742e1 2016-02-10T14:43:18 http: read server response even after server closed the connection Otherwise if we will try to write more data than server can accept (see `evhttp_set_max_body_size()` for libevent server) we will get `EPIPE` and will not try to read server's response which must contain 400 error for now (which is not strictly correct though, it must 413). ``` $ strace regress --no-fork http/data_length_constraints ... connect(10, {sa_family=AF_INET, sin_port=htons(43988), sin_addr=inet_addr("127.0.0.1")}, 16) = -1 EINPROGRESS (Operation now in progress) ... writev(10, [{"POST / HTTP/1.1\r\nHost: somehost\r"..., 60}, {"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 16324}], 2) = 16384 epoll_wait(5, [{EPOLLOUT, {u32=10, u64=10}}, {EPOLLIN, {u32=11, u64=11}}], 32, 50000) = 2 writev(10, [{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 16384}], 1) = 16384 ioctl(11, FIONREAD, [32768]) = 0 readv(11, [{"POST / HTTP/1.1\r\nHost: somehost\r"..., 4096}], 1) = 4096 epoll_ctl(5, EPOLL_CTL_DEL, 11, 0x7fff09d41e50) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 11, {EPOLLOUT, {u32=11, u64=11}}) = 0 epoll_wait(5, [{EPOLLOUT, {u32=10, u64=10}}, {EPOLLOUT, {u32=11, u64=11}}], 32, 50000) = 2 writev(10, [{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 16384}], 1) = 16384 writev(11, [{"HTTP/1.1 400 Bad Request\r\nConten"..., 129}, {"<HTML><HEAD>\n<TITLE>400 Bad Requ"..., 94}], 2) = 223 epoll_ctl(5, EPOLL_CTL_DEL, 11, 0x7fff09d42080) = 0 shutdown(11, SHUT_WR) = 0 close(11) = 0 epoll_wait(5, [{EPOLLOUT|EPOLLERR|EPOLLHUP, {u32=10, u64=10}}], 32, 50000) = 1 writev(10, [{"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"..., 16384}], 1) = -1 EPIPE (Broken pipe) --- SIGPIPE {si_signo=SIGPIPE, si_code=SI_USER, si_pid=13954, si_uid=1000} --- epoll_ctl(5, EPOLL_CTL_DEL, 10, 0x7fff09d42010) = 0 shutdown(10, SHUT_WR) = -1 ENOTCONN (Transport endpoint is not connected) close(10) = 0 write(1, "\n FAIL ../test/regress_http.c:3"..., 37 ``` Careful reader can ask why it send error even when it didn't read `evcon->max_body_size`, and the answer will be checks for `evcon->max_body_size against `Content-Length` header, which contains ~8MB (-2 bytes). And also if we will not drain the output buffer than we will send buffer that we didn't send in previous request and instead of sending method via `evhttp_make_header()`. Fixes: http/data_length_constraints Refs: #321 v2: do this only under EVHTTP_CON_READ_ON_WRITE_ERROR flag
Azat Khuzhin 4dc09795 2016-02-15T02:59:40 http: fix conflicts EVHTTP_CON_AUTOFREE and EVHTTP_CON_REUSE_CONNECTED_ADDR And we can't make them continuous, since the latest is a public API, and otherwise we will break binary compatibility. Also extra check for EVHTTP_CON_PUBLIC_FLAGS_END, in case somebody forgot about this (implementer I mean). Refs: #182
Azat Khuzhin 365f181a 2016-02-15T03:53:25 http: coding style issue
Azat Khuzhin ab3bc69f 2015-11-20T01:37:46 http: avoid epoll_ctl() on already closed fd (triggers by http/chunk_out) Before: $ strace -eepoll_ctl,close regress --verbose --no-fork +http/chunk_out close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 close(3) = 0 http/chunk_out: epoll_ctl(5, EPOLL_CTL_ADD, 8, {EPOLLIN, {u32=8, u64=8}}) = 0 close(10) = 0 close(9) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 9, {EPOLLIN, {u32=9, u64=9}}) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 10, {EPOLLOUT, {u32=10, u64=10}}) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 11, {EPOLLIN, {u32=11, u64=11}}) = 0 epoll_ctl(5, EPOLL_CTL_DEL, 10, 7ffffb10b870) = 0 epoll_ctl(5, EPOLL_CTL_ADD, 10, {EPOLLIN, {u32=10, u64=10}}) = 0 close(12) = 0 epoll_ctl(5, EPOLL_CTL_MOD, 11, {EPOLLIN|EPOLLOUT, {u32=11, u64=11}}) = 0 epoll_ctl(5, EPOLL_CTL_MOD, 11, {EPOLLIN, {u32=11, u64=11}}) = 0 close(11) = 0 epoll_ctl(5, EPOLL_CTL_DEL, 11, 7ffffb10b770) = -1 EBADF (Bad file descriptor) ... And trace for latest: close(11) = 0 > regress(evutil_closesocket+0x15) [0xadac4] > regress(evhttp_connection_free+0x19d) [0xbada2] > regress(evhttp_send_done+0x14d) [0xbde43] > regress(evhttp_write_cb+0x4a) [0xba1a1] > regress(bufferevent_run_writecb_+0xa2) [0x97bba] > regress(bufferevent_trigger_nolock_+0xb1) [0x9e330] > regress(bufferevent_writecb+0x2a3) [0x9e91a] > regress(event_persist_closure+0x2bb) [0xa2e09] > regress(event_process_active_single_queue+0x2a8) [0xa30b4] > regress(event_process_active+0x13f) [0xa3696] > regress(event_base_loop+0x2ab) [0xa3d97] > regress(event_base_dispatch+0x1d) [0xa371e] > regress(http_chunk_out_test_impl+0x132) [0x74940] epoll_ctl(5, EPOLL_CTL_DEL, 11, 7fff09439fe0) = -1 EBADF (Bad file descriptor) > regress(epoll_ctl+0x36) [0xb49a3] > regress(epoll_apply_one_change+0x14e) [0xb4cd4] > regress(epoll_nochangelist_del+0x87) [0xb51e4] > regress(evmap_io_del_+0x247) [0xaab04] > regress(event_del_nolock_+0x2f7) [0xa6aa8] > regress(event_callback_cancel_nolock_+0x6e) [0xa747e] > regress(event_callback_finalize_many_+0xeb) [0xa4dd6] > regress(bufferevent_decref_and_unlock_+0x21d) [0x98da7] > regress(bufferevent_writecb+0x312) [0x9e989] > regress(event_persist_closure+0x2bb) [0xa2e09] > regress(event_process_active_single_queue+0x2a8) [0xa30b4] > regress(event_process_active+0x13f) [0xa3696] > regress(event_base_loop+0x2ab) [0xa3d97] > regress(event_base_dispatch+0x1d) [0xa371e] > regress(http_chunk_out_test_impl+0x132) [0x74940] ...
Azat Khuzhin 040000d7 2015-11-16T00:55:30 http: install timeout for read too during connect for ssl Since during ssl handshake we can read too, and if something nasty will happens during this handshake (because of too many events in the loop of something like this) we can wait forever since there is no read timeout: (gdb) p *$2.task.connection.bufev $11 = { ... be_ops = 0x7f78c2864b00 <bufferevent_ops_openssl>, ev_read = { ... ev_ = { ev_io = { ... ev_timeout = { tv_sec = 0, tv_usec = 0 } }, ev_signal = { ... } }, ev_events = 82, ev_res = 2, ev_timeout = { tv_sec = 10889976, tv_usec = 418753 } }, ev_write = { ... ev_ = { ev_io = { ... ev_timeout = { tv_sec = 20, tv_usec = 0 } }, ev_signal = { ... } }, ev_events = 84, ev_res = 4, ev_timeout = { tv_sec = 10889977, tv_usec = 598753 } }, ... errorcb = 0x7f78c287de70 <evhttp_connection_cb>, ... timeout_read = { tv_sec = 0, tv_usec = 0 }, timeout_write = { tv_sec = 20, tv_usec = 0 }, enabled = 4 } (gdb) bt #0 0x00007f78c17c3633 in __epoll_wait_nocancel () at syscall-template.S:81 #1 0x00007f78c2aaf508 in epoll_dispatch (base=0x18f76d0, tv=<optimized out>) at epoll.c:463 ... Found-with: massive crawling Tested-with: massive crawling
Ed Schouten c1404b56 2015-08-26T10:06:09 Include <sys/ioctl.h>, <sys/resource.h> and <sys/wait.h> optionally. Though CloudABI implements a very large part of POSIX, it does not provide these header files, for the reason that there is no raw device access, no resource limiting and no access to the global process table through wait(). It looks like these header files are not actually needed in theory. There don't seem to be any constructs in these source files that use these features, but I suspect they might still be required on some systems.
Azat Khuzhin b0d3964f 2015-09-09T19:21:51 http: fix evhttp_request_own() by checking EVHTTP_USER_OWNED in more cases Suggested-by: @ellzey Fixes: http/request_own Fixes: #68
Azat Khuzhin 7ed02ac1 2015-09-08T16:40:55 http: fix detecting EOF without write Before this patch http server don't knows when client disconnected until it will try to write to it, IOW to detect is client still alive you need to write something to client socket, however it is not convenient since it requires to store all clients somewhere and poll them periodically, and I don't see any regressions if we will leave EV_READ always (like libevhtp do), since we already reset read callback in evhttp_write_buffer() (see http/write_during_read). Also since we don't disable EV_READ anymore we don't need some enable EV_READ, so we will reduce number of epoll_ctl() calls. Covered-by: http/terminate_chunked_oneshot Covered-by: http/write_during_read Fixes: #78
Azat Khuzhin dfad1a46 2015-08-19T23:00:49 http: eliminate warning about "socklen" in evhttp_connection_connect_()
Azat Khuzhin a50f5f0a 2015-01-01T06:27:31 http: reuse connected address only with EVHTTP_CON_REUSE_CONNECTED_ADDR
Azat Khuzhin 54c887d8 2014-11-12T20:23:46 http: use IP address that we got before (if any) during retrying Before this patch every time we are retrying our request we resolve domain, but we could optimize this (since UDP is slow) by using cached conn_address value, so do this.
Azat Khuzhin 8bb38425 2014-11-15T21:46:11 bufferevent: move conn_address out from http into bufferevent In http the only case when when we could store it is when we already connected, *but* if we are doing request using domain name, then we need to do request to nameserver to get IP address, and this is handled by bufferevent. So when we have IP address (from nameserver) and don't have connection to this IP address, we could already cache it to avoid extra DNS requests (since UDP is slow), and we can't do this from http layer, only from bufferevent.
Azat Khuzhin 22061ac1 2015-08-18T03:03:51 http: introduce evhttp_request_free_() helper
Azat Khuzhin 6540da38 2015-04-24T19:04:51 http: introduce evhttp_is_request_connection_close() helper
Mark Ellzey bdeec440 2015-06-17T08:24:52 Merge pull request #190 from JohnOhl/evhttp-post-fix evhttp: Fix failure to send all output data for POST/PUT requests
Nick Mathewson 7fd49414 2014-11-30T19:26:20 Merge remote-tracking branch 'origin/pr/182'
John Ohl 24eea0da 2014-11-24T02:32:23 evhttp: Fix failure to send all output data for POST/PUT requests
John Ohl 10fe4ef3 2014-11-16T23:40:16 Prevent duplicate event_del on fd
John Ohl 2b9ec4c1 2014-10-26T01:18:10 Implement interface that provides the ability to have an outbound evhttp_connection free itself once all requests have completed
Azat Khuzhin bc79cc5c 2014-09-27T21:29:45 http: reset connection before installing retry timer (fix http retries handling) This will fix some invalid read/write: ==556== Invalid read of size 8 ==556== at 0x4E4EEC6: event_queue_remove_timeout (minheap-internal.h:178) ==556== by 0x4E508AA: event_del_nolock_ (event.c:2764) ==556== by 0x4E53535: event_base_loop (event.c:3088) ==556== by 0x406FCFA: dispatch (libcrawl.c:271) ==556== by 0x402863: main (crawler.c:49) ==556== Address 0x68a3f18 is 152 bytes inside a block of size 400 free'd ==556== at 0x4C29C97: free (in /usr/local/lib/valgrind/vgpreload_memcheck-amd64-linux.so) ==556== by 0x406F140: renew (libcrawl.c:625) ==556== by 0x4E6CDE9: evhttp_connection_cb_cleanup (http.c:1331) ==556== by 0x4E6E2B2: evhttp_connection_cb (http.c:1424) ==556== by 0x4E4DF2D: bufferevent_writecb (bufferevent_sock.c:310) ==556== by 0x4E52D1D: event_process_active_single_queue (event.c:1584) ==556== by 0x4E53676: event_base_loop (event.c:1676) ==556== by 0x406FCFA: dispatch (libcrawl.c:271) ==556== by 0x402863: main (crawler.c:49) But this one because of some invalid write before (I guess). It is 100% reproduced during massive crawling (because this process has many different servers), but after spending some time for trying to reproduce this using some simple tests/utils I gave up for a few days (I have a lot of work to do), but I'm sending this patch as a reminder. Just in case, I've tried next tests: - mixing timeouts/retries - shutdown http server and return it back - slow dns server for first request - sleep before accept - hacking libevent sources to change the behaviour of http layer (so it will go into that function which I'm insterested in).
Nick Mathewson 73615a37 2014-09-18T11:31:52 Merge pull request #118 from azat/http-forward-family-to-bufferevent Add evhttp_connection_set_family() to set addrinfo->family for DNS requests
Azat Khuzhin 12c29b0f 2014-03-21T17:32:09 Add evhttp_connection_set_family() to set addrinfo->family for DNS requests This is useful if you want to avoid extra dns requests.
Nick Mathewson e660db6d 2014-03-18T11:39:23 Catch over-large port numbers early in http Otherwise integer overflow potentially turns the port number into garbage.
Andrew Sweeney da86dda9 2014-01-06T20:36:31 evhttp_request_set_on_complete_cb to be more specific about what the function actually does and usage
Andrew Sweeney b083ca05 2014-01-05T20:35:46 Provide on request complete callback facility This patch provides the ability to receive a callback on the completion of a request. The callback takes place immediately before the request's resources are released.
Balint Reczey b0bd7fe1 2013-11-18T16:06:16 Allow registering callback for parsing HTTP headers Slightly changed version of Espen Jürgensen's commit 548141e72312126fa6121f6a5f436đ251c7fb1251 for forked-daapd.
Julien BLACHE 8d8decf1 2009-05-02T20:40:11 Add a variant of evhttp_send_reply_chunk() with a callback on evhttp_write_buffer() evhttp_write_buffer() used by evhttp_send_reply_chunk() can take callback executed when (part of) the buffer has been written. Using this callback to schedule the next chunk avoids buffering large amounts of data in memory.
Azat Khuzhin 0c7f0405 2013-10-01T19:12:13 http: implement new evhttp_connection_get_addr() api. Basically tcp final handshake looks like this: (C - client, S - server) ACK[C] - FIN/ACK[S] - FIN/ACK[S] - ACK [C] However there are servers, that didn't close connection like this, while it is still _considered_ as valid, and using libevent http layer we can do requests to such servers. Modified handshake: (C - client, S - server) ACK[C] - RST/ACK[S] - RST/ACK[S] And in this case we can't extract IP address from socket, because it is already closed, and getpeername() will return: "transport endpoint is not connected". So we need to store address that we are connecting to, after we know it, and that is what this patch do. I have reproduced it, however it have some extra packages. (I will try to fix it) https://github.com/azat/nfq-examples/blob/master/nfqnl_rst_fin.c
Nick Mathewson 4464bd23 2013-10-10T16:10:50 Tweak indentation
Nicolas Martyanoff 5a5acd9a 2013-09-28T20:03:28 add a http default content type option
Nick Mathewson b04d13cd 2013-09-09T12:06:53 Merge remote-tracking branch 'origin/patches-2.0'
Nate Rosenblum 5eb17885 2013-09-03T14:46:47 Avoid racy bufferevent activation The evhttp_send_reply method invokes evhttp_write_buffer with a callback that may release the underlying request object and bufferevent upon completion. This cleanup callback is invoked by the underlying bufferevent's write callback. Improperly enabling write events before referencing the bufferevent could lead to use after free and memory corruption.
Nick Mathewson f22049e3 2013-08-06T19:17:08 Fix an unlikely but possible error case for http connections Found by coverity
Maxime Henrion a7f82a31 2013-07-24T20:50:05 Add evhttp_connection_get_server().
Maxime Henrion 31db8a02 2013-05-23T16:29:17 Fix a double close() bug in evhttp when the underlying bufferevent uses BEV_OPT_CLOSE_ON_FREE.
Azat Khuzhin 7b077194 2013-03-21T13:55:40 Add new error_cb for actual reporting of HTTP request errors. It is useful to know why you callback called with NULL (i.e. it failed), for example if you set max_body with evhttp_connection_set_max_body_size() you must know that it failed because of body was longer than this size. (Commit message tweaked by Nick)
Azat Khuzhin de8101a8 2013-03-01T12:00:24 Move prototype of evhttp_decode_uri_internal() to http-internal.h Make it non static, that can be called from tests
Azat Khuzhin e1903e3a 2013-02-28T23:10:02 uri decode: changed the test for the existence of the next character Fix for 64b6eceaba1a4 More info here https://github.com/azat/libevent/commit/64b6eceaba1a40ab0b175fa9fd9329d3e978ce6e#commitcomment-2714685
Azat Khuzhin 64b6ecea 2013-02-28T17:19:44 uri decode: fix for warning "use of uninitialised value" This patch add check in evhttp_decode_uri_internal() that next 2 symbols are exists in array of chars for decoding, if don't have two next 2 symbols don't try to decode '%FF'
Nick Mathewson 97094614 2013-02-14T14:13:11 Merge remote-tracking branch 'origin/patches-2.0'
Greg Hazel b6182042 2013-02-14T09:54:56 fix #73 and fix http_connection_fail_test to catch it
Nick Mathewson 2ecd8947 2013-02-04T13:49:08 Merge pull request #39 from azat/fix-http-for-ipv6 Fix ipv6 support for http. When URL contain domain, not IP address.
Azat Khuzhin 71e709c7 2013-01-23T02:45:32 Fix ipv6 support for http. When URL contain domain, not IP address. Before this patch socket created before domain was resolved, and it always create with AF_INET (ipv4), but we must create socket only after domain was resolved to understad which protocol family have domain address. Thank to Patrick Pelletier, who found this bug.
Patrick Pelletier 80e220ee 2013-01-18T20:25:41 fix some hinky indentation in evhttp_make_request
Sebastian Hahn b452a434 2012-12-31T18:29:56 Fix harmless clang enum warning
Nick Mathewson 7afbd602 2012-11-16T11:51:42 Use EVUTIL_SOCKET_ERROR() wrapper to save/restor errno in evhttp_connection_fail_
Nick Mathewson 29fea33a 2012-11-16T11:49:46 Merge remote-tracking branch 'ppelleti/preserve-errno'
Jay R. Wren 4f4d0c93 2012-10-10T13:16:02 add evhttp_request_get_response_code_line This is needed to be able to read the response code line especially when acting as an http client using evhttp_make_request. (patched by nickm to make the return value const)
Nick Mathewson 61b93af5 2012-11-16T11:41:59 Move evutil_rtrim_lws_ to evutil.c where it belongs
Nick Mathewson c6ff3812 2012-11-16T11:38:53 Remove internal ws from multiline http headers correctly According to RFC2616: All linear white space, including folding, has the same semantics as SP. A recipient MAY replace any linear white space with a single SP before interpreting the field value or forwarding the message downstream.
Nick Mathewson ac425197 2012-11-16T11:29:34 Remove trailing tabs in HTTP headers as well.
Nick Mathewson aa59d805 2012-11-16T11:13:29 Clean up rtrim implementation If I understand the C standard correctly, you can't actually point at a position immediately _before_ the start of an object; only at the position immediately after. According to J.2 in the standard, in its big list of undefined behavior: "The behavior is undefined in the following circumstances: ... — Addition or subtraction of a pointer into, or just beyond, an array object and an integer type produces a result that does not point into, or just beyond, the same array object (6.5.6)." So we've got to fix rtrim to not do that. Also, make it unit tested, and give it an evutil_*_ name.
Artem Germanov 370a2c02 2012-05-20T21:08:52 ignore LWS after field-content in headers
Patrick Pelletier 36d0ee5c 2012-11-13T21:22:39 preserve errno in evhttp_connection_fail_ for inspection by the callback
Nick Mathewson f9182d72 2012-11-02T11:46:14 Merge remote-tracking branch 'github/20_win64_compilation' into 21_win64_compilation Conflicts: http.c signal.c
Nick Mathewson 62bd2c44 2012-11-02T11:44:29 Fix compilation on mingw64 with -DUSE_DEBUG
Nick Mathewson 2e6a9850 2012-11-01T18:12:07 Merge remote-tracking branch 'github/20_win64_compilation' into 21_win64_compilation Conflicts: event.c http.c sample/event-read-fifo.c test/regress_bufferevent.c
Nick Mathewson 94866c27 2012-11-01T17:38:34 Compile without warnings on mingw64 This is mostly a matter of catching cases where we were still assuming that evutil_socket_t could be used as an int.