482 Commits

Author SHA1 Message Date
Azat Khuzhin
254fbc81b4
http: allow trailing spaces (and only them) in request-line (like nginx) 2018-10-22 23:56:31 +03:00
Azat Khuzhin
6cf659b0bd
http: cleanup of the request-line parsing 2018-10-22 23:55:35 +03:00
Nathan French
514dc7579c
[http] fix C90 warnings 2018-07-05 12:46:51 -04:00
Greg Hazel
367cd9e5c2 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)
2018-04-24 02:29:17 +03:00
Azat Khuzhin
cd57e38c3f 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
2018-02-20 12:12:19 +03:00
Joseph Coffland
c62f73f5b5 Added evhttp max simultaneous connection limiting 2018-01-30 15:39:41 -08:00
Azat Khuzhin
61c2149268 http: fix leaks in evhttp_uriencode()
Fixes: #584
2018-01-09 21:47:57 +03:00
John Fremlin
727bcea130 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)
2017-12-18 03:00:04 +03:00
Greg Hazel
65eb529a9f CONNECT method only takes an authority 2017-12-11 01:03:29 +03:00
Azat Khuzhin
306747e51c 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
2017-11-04 19:15:32 +03:00
Azat Khuzhin
db483e3b00 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
2017-10-30 11:32:13 +03:00
Andreas Gustafsson
99d0a952da 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.
2017-10-30 11:32:13 +03:00
Azat Khuzhin
5ff8eb2637 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>
2017-10-29 20:30:42 +03:00
Azat Khuzhin
da3f2ba22a 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
2017-10-22 02:01:09 +03:00
Vis Virial
db60ade81d http: do not use local settings for Date header 2016-12-19 00:55:50 +03:00
Azat Khuzhin
1cbf26f67a http: fix formatter for pritnf for req->ntoread (osx) 2016-12-06 11:51:40 +03:00
Thomas Bernard
e983712456 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
2016-10-26 01:41:13 +03:00
Zonr Chang
c6b1ec1220 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
2016-08-27 01:24:11 +03:00
Mark Ellzey
e94250c8e3
removed unused vars 2016-08-14 14:03:56 -07:00
Mark Ellzey
72afe4c93b
pointer overflow checks for evhttp_uriencode
Check to make sure pointer math is all OK.
2016-08-14 14:02:37 -07:00
Mark Ellzey
17cc636223
[Issue #313] set method to ASCII "NULL" if evhttp_method() returns NULL 2016-06-24 18:07:39 -07:00
Azat Khuzhin
24b521499a 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))
                        ^          ~~
2016-03-25 10:21:48 +03:00
Azat Khuzhin
7a4b472925 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
2016-03-24 14:01:31 +03:00
Azat Khuzhin
f0e1341179 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.
2016-03-23 12:53:51 +03:00
Azat Khuzhin
4a53c54bf7 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.
2016-03-23 12:53:03 +03:00
Azat Khuzhin
d4054928c7 http: make fallback for EVHTTP_CON_READ_ON_WRITE_ERROR more cleaner 2016-03-11 20:59:58 +03:00
Azat Khuzhin
2ff164abac 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
2016-03-11 20:59:58 +03:00
Azat Khuzhin
7c8999956f 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
2016-03-11 20:59:58 +03:00
Azat Khuzhin
8f18a626e6 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")
2016-03-11 20:59:12 +03:00
Azat Khuzhin
0b46b39e95 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
2016-03-11 20:58:46 +03:00
Azat Khuzhin
2185e63921 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
2016-03-11 18:53:10 +03:00
Azat Khuzhin
ac448a74d0 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
2016-03-09 18:52:52 +03:00
Azat Khuzhin
9fde5189df 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
2016-03-09 18:52:07 +03:00
Azat Khuzhin
680742e166 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
2016-03-09 01:12:50 +03:00
Azat Khuzhin
4dc09795c0 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
2016-02-24 14:22:31 +03:00
Azat Khuzhin
365f181aa3 http: coding style issue 2016-02-24 14:22:27 +03:00
Azat Khuzhin
ab3bc69f47 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]
 ...
2015-11-20 01:51:39 +03:00
Azat Khuzhin
040000d7a7 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
2015-11-18 15:42:22 +03:00
Ed Schouten
c1404b5651 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.
2015-09-10 12:14:27 +03:00
Azat Khuzhin
b0d3964ff5 http: fix evhttp_request_own() by checking EVHTTP_USER_OWNED in more cases
Suggested-by: @ellzey
Fixes: http/request_own
Fixes: #68
2015-09-09 19:31:12 +03:00
Azat Khuzhin
7ed02ac129 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
2015-09-09 18:06:42 +03:00
Azat Khuzhin
dfad1a460a http: eliminate warning about "socklen" in evhttp_connection_connect_() 2015-08-19 23:00:49 +03:00
Azat Khuzhin
a50f5f0ac0 http: reuse connected address only with EVHTTP_CON_REUSE_CONNECTED_ADDR 2015-08-18 20:06:53 +03:00
Azat Khuzhin
54c887d823 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.
2015-08-18 20:06:52 +03:00
Azat Khuzhin
8bb3842552 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.
2015-08-18 20:06:52 +03:00
Azat Khuzhin
22061ac1e9 http: introduce evhttp_request_free_() helper 2015-08-18 11:58:13 +03:00
Azat Khuzhin
6540da3893 http: introduce evhttp_is_request_connection_close() helper 2015-08-18 11:57:54 +03:00
Mark Ellzey
bdeec440f1 Merge pull request #190 from JohnOhl/evhttp-post-fix
evhttp: Fix failure to send all output data for POST/PUT requests
2015-06-17 08:24:52 -07:00
Nick Mathewson
7fd4941465 Merge remote-tracking branch 'origin/pr/182' 2014-11-30 19:26:20 -05:00
John Ohl
24eea0da97 evhttp: Fix failure to send all output data for POST/PUT requests 2014-11-24 02:32:23 -05:00