http.c

Branch


Log

Author Commit Date CI Message
Kirill Rd 98b7ca30 2024-11-02T21:39:57 http: allow passing in pre-existing connection bev (#1722) This patch adds functionality to pass a pre-existing connection as a bufferevent to `evhttp_connection_base_bufferevent_reuse_new`. When the bufferevent has an existing fd, the evcon starts in state `EVCON_IDLE` so that requests can be made immediately. Signed-off-by: Kirill Rodriguez <theoden8@tutamail.com> Signed-off-by: Kirill Rodriguez <theoden8@tutamail.com> Co-authored-by: Wladimir J. van der Laan <laanwj@gmail.com> Co-authored-by: Azat Khuzhin <a3at.mail@gmail.com>
Kirill Rodriguez cdef74fd 2024-11-01T00:10:57 remove old issue reference Signed-off-by: Kirill Rodriguez <theoden8@gmail.com>
Kirill Rodriguez e9559cd1 2024-10-29T15:20:08 fix unused variable
Kirill Rodriguez c35d406d 2024-10-29T11:43:02 fix flags definition placements in http.c
Kirill Rodriguez a92ce7e1 2024-10-29T11:26:35 moved EVHTTP_ flags to http.c
Cœur 9848df54 2024-07-26T22:53:30 http: disallow empty header names (#1690) In theory, we could be more strict, since there is only a subset of allowed characters: > ``` > tchar = "!" / "#" / "$" / "%" / "&" / "'" / "*" > / "+" / "-" / "." / "^" / "_" / "`" / "|" / "~" > / DIGIT / ALPHA > ; any VCHAR, except delimiters > ``` But I'd skip such verification, unless there is a legitimate interest (versus performances). Fixes: #1686
Cœur eec47a67 2024-04-30T15:59:58 Fix typos (#1634)
Azat Khuzhin 8feed7f1 2024-02-18T19:26:47 http: forbid chunks size with 0X prefix Co-authored-by: Ben Kallus <49924171+kenballus@users.noreply.github.com>
Azat Khuzhin 87cdcc18 2024-02-18T15:24:58 http: change error for corrupted requests to 400 Bad Request Previously it was 413 Request Entity Too Large, which was odd.
Azat Khuzhin f1632e59 2024-02-18T15:24:33 http: check first byte of the chunk for 0x as well
Ben Kallus 92ea8476 2024-02-18T08:56:46 Forbid 0x/+/-/whitespace prefixes on HTTP chunk sizes (#1542) Currently, libevent's HTTP parser accepts and ignores 0x, +, and whitespace prefixes on chunk sizes. It also ignores - prefixes on chunk sizes of 0. This patch fixes that. There is a potential danger in the current behavior, which is that there exist HTTP implementations that interpret chunk sizes as their longest valid prefix. For those implementations, 0xa (for example) is equivalent to 0, and this may present a request smuggling risk when those implementations are used in conjunction with libevent. However, as far I'm aware, there is no HTTP proxy that both interprets 0xa as 0 and forwards it verbatim, so I think this is a low-risk bug that is acceptable to report in public.
Ben Kallus 665d79f1 2024-01-18T16:42:52 Fix integer overflow in HTTP version (#1541) Currently, when libevent parses requests with version `HTTP/4294967295.255`, you end up with `req->major == req->minor == (char)-1`. (At least on linux-gnu-x86_64, where `char` is signed.) This is sort of weird. This patch changes the version parser to match the grammar in RFCs 7230 and 9112. (i.e. `HTTP/[0-9].[0-9]`) EDIT: Technically, a little stronger than the RFC requires, since this patch continues to block major versions greater than 1, which was already what libevent was doing.
Andy Pan 7658b788 2024-01-06T00:52:43 Implement full support of TCP Keep-Alives across most Unix-like OS's (#1532) Default settings of TCP keep-alive are not always feasible, take Linux for example, the duration a connection needs to be idle before sending out the first keep-alive probe is two hours, which makes detecting dead connections extremely deferred. Thus, enabling TCP keep-alive will be to little avail. This sets TCP_KEEPIDLE, TCP_KEEPINTVL, and TCP_KEEPCNT when enabling TCP keep-alive mechanism to make it practicable.
Sam James 4c38de8c 2023-11-26T20:52:32 Fix -Walloc-size (#1526) Co-authored-by: Azat Khuzhin <azat@libevent.org>
Liao Tonglang 9203d98f 2023-03-27T04:35:00 http: style fix: use space between arguments list (#1435)
Liao Tonglang 6bfa5805 2023-03-05T23:59:21 http: Reduce times of checking if response has body (#1395) Use a variable 'need_body' to store the result of evhttp_response_needs_body(), then use the variable instead of call the function again.
Cœur 3bcc92cf 2023-03-02T13:59:32 Fix the value is never actually read from 'argument' in evhttp_parse_query_impl() Although the value stored to 'argument' is used in the enclosing expression, the value is never actually read from 'argument'
Leon George 3ec3b469 2022-10-23T13:47:23 ws: fix compile error on centos 7 - very old compiler (#1359) * http: fix typo * ws: fix comile error On CentOS: CC ws.lo ws.c: In function 'get_ws_frame': ws.c:244:3: error: 'for' loop initial declarations are only allowed in C99 mode for (int i = 0; i < payload_len; i++) { ^ ws.c:244:3: note: use option -std=c99 or -std=gnu99 to compile your code
Dmitry Ilyin e8313084 2022-09-12T22:16:56 Add minimal WebSocket server implementation for evhttp (#1322) This adds few functions to use evhttp-based webserver to handle incoming WebSockets connections. We've tried to use both libevent and libwebsockets in our application, but found that we need to have different ports at the same time to handle standard HTTP and WebSockets traffic. This change can help to stick only with libevent library. Implementation was inspired by modified Libevent source code in ipush project [1]. [1]: https://github.com/sqfasd/ipush/tree/master/deps/libevent-2.0.21-stable Also, WebSocket-based chat server was added as a sample.
mareksm b19af675 2022-08-28T15:27:04 Fix non-std printf %p arguments (#1327) * Fix non-std printf %p arguments when running with -Werror -pedantic-errors Co-authored-by: Mareks Malnacs <mareks.malnacs>
Leon M. George 1bdc9135 2022-08-01T10:16:18 http: allow setting bevcb per socket Co-authored-by: Azat Khuzhin <azat@libevent.org> v2: remove handling of HTTP_BIND_IPV6
Azat Khuzhin c8501afc 2022-07-09T17:17:38 http: suppress "flags may be used uninitialized in this function" error Some GCC reports [1]: /home/runner/work/libevent/libevent/http.c: In function ‘evhttp_make_header’: /home/runner/work/libevent/libevent/http.c:503:14: error: ‘flags’ may be used uninitialized in this function [-Werror=maybe-uninitialized] ev_uint16_t flags; ^~~~~ /home/runner/work/libevent/libevent/http.c: In function ‘evhttp_get_body’: /home/runner/work/libevent/libevent/http.c:2354:14: error: ‘flags’ may be used uninitialized in this function [-Werror=maybe-uninitialized] ev_uint16_t flags; ^~~~~ [1]: https://github.com/libevent/libevent/runs/7263518338?check_suite_focus=true#logs
Azat Khuzhin 2b92b830 2021-08-12T01:40:27 http: fix building under windows (guard with _WIN32 for unixsocket free) Reported-by: @kaend
Sean Young f446229b 2016-01-31T11:31:00 http: support unix domain sockets There are no standard for encoding a unix socket in an url. nginx uses: http://unix:/path/to/unix/socket:/httppath The second colon is needed to delimit where the unix path ends and where the rest of the url continues. Signed-off-by: Sean Young <sean@mess.org>
Azat Khuzhin 2385638e 2021-03-23T09:02:39 http: fix fd leak on fd reset (by using bufferevent_replacefd()) Fixes: afa66ea4 ("http: eliminate redundant bev fd manipulating and caching [WIP]")
ihsinme d13b7bbf 2021-02-05T18:54:30 http: fix invalid unsigned arithmetic
Azat Khuzhin afa66ea4 2019-09-04T00:56:20 http: eliminate redundant bev fd manipulating and caching [WIP] At the very beginning we reset the bufferevent fd (if bev has it), which is not a good idea, since if user passes bufferevent with existing fd he has some intention. So we need to: - use BEV_OPT_CLOSE_ON_FREE for default bufferevent_socket_new() (to avoid manual shutdown/closee) - drop getsockopt(SOL_SOCKET, SO_ERROR), since bufferevent already has evutil_socket_finished_connecting_() - drop supperior bufferevent_setfd(bev, -1) in evhttp_connection_connect_() Closes: #795 Refs: #875
Azat Khuzhin e91c4363 2020-10-27T01:40:34 http: add EVHTTP_URI_HOST_STRIP_BRACKETS Refs: #1115
Leon M. George a18301a2 2020-09-08T15:38:16 http: const out address param to evcon_get_peer
Azat Khuzhin 4528d8e9 2020-06-25T09:08:31 Check error code of evhttp_add_header_internal() in evhttp_parse_query_impl()
Azat Khuzhin 7426a568 2020-05-25T11:25:18 http: Merge branch 'http-max_connections-pr-592' @jcoffland: "When the max connection limit is enabled and the limit is reached, the server will respond immediately with 503 Service Unavailable. This can be used to prevent servers from running out of file descriptors. This is better than request limiting because clients may make more than one request over a single connection. Blocking a request does not necessarily close the connection and free up a socket." * http-max_connections-pr-592: test: cover evhttp max connections Added evhttp max simultaneous connection limiting
Azat Khuzhin eee26dee 2020-05-19T11:45:43 http: fix EVHTTP_CON_AUTOFREE in case of timeout (and some else) Refs: #182
Azat Khuzhin 083c6d54 2020-05-19T01:02:30 http: fix EVHTTP_CON_AUTOFREE in case of connection error Refs: #182
nntrab 02905413 2016-02-09T18:01:00 Add callback support for error pages The existing error pages are very basic and don't allow for multi-lingual support or for conformity with other pages in a web site. The aim of the callback functionality is to allow custom error pages to be supported for calls to evhttp_send_error() by both calling applications and Libevent itself. A backward-incompatible change has been made to the title of error pages sent by evhttp_send_error(). The original version of the function used the reason argument as part of the title. That might have unforeseen side-effects if it contains HTML tags. Therefore the title has been changed to always use the standard status text. An example of the error callback can be found in this [version](https://github.com/libevent/libevent/files/123607/http-server.zip) of the 'http-server' sample. It will output error pages with very bright backgrounds, the error code using a very large font size and the reason. Closes: #323 (cherr-picked from PR)
Azat Khuzhin 12ad0c8f 2020-01-12T15:29:48 http: do not close connection for CONNECT
Azat Khuzhin 998e6834 2020-01-12T13:43:18 http: do not assume body for CONNECT
yuangongji 0cd536b0 2019-09-18T23:12:59 http: rename bind_socket_ai() to create_bind_socket_nonblock()
yuangongji 1c78451f 2019-09-16T23:24:32 http: make sure the other fields in ext_method are not changed by the callback
Azat Khuzhin 1c573ab3 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
Azat Khuzhin ad51a3c1 2019-05-12T15:19:31 http: avoid use of uninitialized value for AF_UNIX/AF_LOCAL sockaddr unixsock peer does not have sun_path initialized.
Thomas Bernard 8dcb94a4 2016-01-08T13:36:20 Added http method extending User can define his own response method by calling evhttp_set_ext_method_cmp() on the struct http, or evhttp_connection_set_ext_method_cmp() on the connection. We expose a new stucture `evhttp_ext_method` which is passed to the callback if it's set. So any field can be modified, with some exceptions (in evhttp_method_): If the cmp function is set, it has the ability to modify method, and flags. Other fields will be ignored. Flags returned are OR'd with the current flags. Based on changes to the #282 from: Mark Ellzey <socket@gmail.com>
Thomas Bernard 96e56beb 2019-04-02T15:43:35 http: Update allowed_methods field from 16 to 32bits.
Azat Khuzhin 799053db 2019-04-08T22:27:33 http: replace EVHTTP_REQ_UNKNOWN_ with 0 From the server perspective the evhttp_response_phrase_internal() should not be called with 0 before this patch, it will be called with EVHTTP_REQ_UNKNOWN_ hence this patch should not change behavior. Fixes: 68eb526d7b ("http: add WebDAV methods support") Fixes: #789 Fixes: #796 Reported-by: Thomas Bernard <miniupnp@free.fr>
Alexander Drozdov 68eb526d 2019-03-13T10:51:55 http: add WebDAV methods support WebDAV introduced new HTTP methods (RFC4918): PROPFIND, PROPPATCH, MKCOL, LOCK, UNLOCK, COPY, MOVE. Add support of the methods.
Azat Khuzhin bf19462a 2019-03-13T00:20:25 http: suppress -Wwrite-string in evhttp_parse_query_impl()
Azat Khuzhin 5ee507c8 2019-03-04T06:53:42 http: implement separate timeouts for read/write/connect phase This patch allows to change timeout for next events read/write/connect separatelly, using new API: - client: evhttp_connection_set_connect_timeout_tv() -- for connect evhttp_connection_set_read_timeout_tv() -- for read evhttp_connection_set_write_timeout_tv() -- for write - server: evhttp_set_read_timeout_tv() -- for read evhttp_set_write_timeout_tv() -- for write It also changes a logic a little, before there was next fallbacks which does not handled in new API: - HTTP_CONNECT_TIMEOUT - HTTP_WRITE_TIMEOUT - HTTP_READ_TIMEOUT And introduce another internal flag (EVHTTP_CON_TIMEOUT_ADJUSTED) that will be used in evrpc, which adjust evhttp_connection timeout only if it is not default. Fixes: #692 Fixes: #715
Azat Khuzhin 30791ecc 2019-01-29T01:09:44 http: try to read existing data in buffer under EVHTTP_CON_READ_ON_WRITE_ERROR There are two possible ways of getting response from the server: - processing existing bufferevent buffer - reading from the socket (even after write() errored with -1, it is still possible) But we did not tried the first option, only the second one. Fixes: http/read_on_write_error (on freebsd/osx)
Azat Khuzhin d3dcb5ac 2019-01-27T15:16:39 http: do not call deferred readcb if readcb is not set Otherwise evhttp_read_cb can be called with invalid connection state: http/read_on_write_error: [forking] [msg] libevent using: kqueue FAIL ../test/regress_http.c:4079: assert(req) FAIL ../test/regress_http.c:4087: assert(req)[err] evhttp_read_cb: illegal connection state 0
Luke Dashjr 28d7221b 2018-12-28T04:42:20 http: Preserve socket error from listen across closesocket cleanup Closes: #738 (cherry-picked)
Azat Khuzhin f3f7aa5a 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).
Azat Khuzhin b98d32d0 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
Azat Khuzhin 5dc88b38 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
Azat Khuzhin 26ef859a 2018-10-27T17:21:35 Add evhttp_parse_query_str_flags() And a set of flags: - EVHTTP_URI_QUERY_LAST - EVHTTP_URI_QUERY_NONCONFORMANT Fixes: #15
Azat Khuzhin b94d913d 2018-10-22T23:52:46 http: allow non RFC3986 conformant during parsing request-line (http server) Reported-by: lsdyst@163.com
Azat Khuzhin 64ead341 2018-10-22T23:56:50 http: do not try to parse request-line if we do not have enough bytes
Azat Khuzhin 254fbc81 2018-10-22T23:56:19 http: allow trailing spaces (and only them) in request-line (like nginx)
Azat Khuzhin 6cf659b0 2018-10-22T23:25:01 http: cleanup of the request-line parsing
Nathan French 514dc757 2018-07-05T12:46:51 [http] fix C90 warnings
Greg Hazel 367cd9e5 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)
Greg Hazel 939171dc 2018-03-28T19:30:38 remove Proxy-Connection
Azat Khuzhin cd57e38c 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
Joseph Coffland c62f73f5 2018-01-30T15:39:41 Added evhttp max simultaneous connection limiting
Azat Khuzhin 61c21492 2018-01-09T21:44:57 http: fix leaks in evhttp_uriencode() Fixes: #584
John Fremlin 727bcea1 2017-12-01T01:29:32 http: add callback to allow server to decline (and thereby close) incoming connections. This is important, as otherwise clients can easily exhaust the file descriptors available on a libevent HTTP server, which can cause problems in other code which does not handle EMFILE well: for example, see https://github.com/bitcoin/bitcoin/issues/11368 Closes: #578 (patch cherry picked)
Greg Hazel 65eb529a 2017-12-02T12:53:57 CONNECT method only takes an authority
Azat Khuzhin 306747e5 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
Azat Khuzhin db483e3b 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
Andreas Gustafsson 99d0a952 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.
Azat Khuzhin 5ff8eb26 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>
Azat Khuzhin da3f2ba2 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
Greg Hazel b6a3dc5c 2017-05-19T20:11:52 handle errors on incoming requests Signed-off-by: Kirill Rodriguez <theoden8@gmail.com>
Greg Hazel 76df36d5 2017-05-19T00:25:04 don't strip Proxy-Connection
Greg Hazel 9652fe0f 2017-05-15T00:36:47 add const qualifier to evhttp_uri_join declaration Signed-off-by: Kirill Rodriguez <theoden8@gmail.com>
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