470 Commits

Author SHA1 Message Date
Leon George
3ec3b469b8
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
2022-10-23 14:47:23 +03:00
Dmitry Ilyin
e8313084f9
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.
2022-09-12 22:16:56 +03:00
mareksm
b19af675c7
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>
2022-08-28 15:27:04 +03:00
Leon M. George
1bdc91350e http: allow setting bevcb per socket
Co-authored-by: Azat Khuzhin <azat@libevent.org>
v2: remove handling of HTTP_BIND_IPV6
2022-08-13 20:12:18 +02:00
Azat Khuzhin
c8501afc0c 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
2022-07-09 17:36:13 +03:00
Azat Khuzhin
2b92b830a7 http: fix building under windows (guard with _WIN32 for unixsocket free)
Reported-by: @kaend
2021-08-12 01:40:46 +03:00
Sean Young
f446229b22 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>
2021-08-10 23:22:10 +03:00
Azat Khuzhin
2385638edf http: fix fd leak on fd reset (by using bufferevent_replacefd())
Fixes: afa66ea4 ("http: eliminate redundant bev fd manipulating and caching [WIP]")
2021-03-23 09:06:58 +03:00
ihsinme
d13b7bbfcf http: fix invalid unsigned arithmetic 2021-02-11 21:14:42 +03:00
Azat Khuzhin
afa66ea420 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
2020-10-31 21:34:02 +03:00
Azat Khuzhin
e91c436388 http: add EVHTTP_URI_HOST_STRIP_BRACKETS
Refs: #1115
2020-10-27 02:13:21 +03:00
Leon M. George
a18301a2bb http: const out address param to evcon_get_peer 2020-09-09 00:37:17 +03:00
Azat Khuzhin
4528d8e987 Check error code of evhttp_add_header_internal() in evhttp_parse_query_impl() 2020-06-25 09:41:54 +03:00
Azat Khuzhin
7426a568d0 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
2020-05-25 11:25:18 +03:00
Azat Khuzhin
eee26deed3 http: fix EVHTTP_CON_AUTOFREE in case of timeout (and some else)
Refs: #182
2020-05-19 11:46:21 +03:00
Azat Khuzhin
083c6d54d5 http: fix EVHTTP_CON_AUTOFREE in case of connection error
Refs: #182
2020-05-19 01:06:12 +03:00
nntrab
02905413fd 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)
2020-01-13 00:50:14 +03:00
Azat Khuzhin
12ad0c8fcd http: do not close connection for CONNECT 2020-01-12 15:34:01 +03:00
Azat Khuzhin
998e68340e http: do not assume body for CONNECT 2020-01-12 15:33:59 +03:00
yuangongji
0cd536b0b3
http: rename bind_socket_ai() to create_bind_socket_nonblock() 2019-09-18 23:13:34 +03:00
yuangongji
1c78451f0d
http: make sure the other fields in ext_method are not changed by the callback 2019-09-18 23:12:56 +03:00
Azat Khuzhin
1c573ab3a9
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
2019-05-25 23:41:38 +03:00
Azat Khuzhin
ad51a3c1ba
http: avoid use of uninitialized value for AF_UNIX/AF_LOCAL sockaddr
unixsock peer does not have sun_path initialized.
2019-05-12 18:21:21 +03:00
Thomas Bernard
8dcb94a4ca
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>
2019-04-11 22:48:01 +03:00
Thomas Bernard
96e56beb94
http: Update allowed_methods field from 16 to 32bits. 2019-04-11 22:47:55 +03:00
Azat Khuzhin
799053db8a
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>
2019-04-10 00:51:27 +03:00
Alexander Drozdov
68eb526d7b http: add WebDAV methods support
WebDAV introduced new HTTP methods (RFC4918):
PROPFIND, PROPPATCH, MKCOL, LOCK, UNLOCK, COPY, MOVE.

Add support of the methods.
2019-03-14 11:12:46 +03:00
Azat Khuzhin
bf19462a55
http: suppress -Wwrite-string in evhttp_parse_query_impl() 2019-03-13 00:21:38 +03:00
Azat Khuzhin
5ee507c889
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
2019-03-05 00:33:46 +03:00
Azat Khuzhin
30791eccce
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)
2019-01-29 01:16:48 +03:00
Azat Khuzhin
d3dcb5aca9
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
2019-01-28 22:20:47 +03:00
Luke Dashjr
28d7221b85
http: Preserve socket error from listen across closesocket cleanup
Closes: #738 (cherry-picked)
2019-01-07 15:22:39 +03:00
Azat Khuzhin
f3f7aa5aff
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).
2018-12-12 21:46:27 +03:00
Azat Khuzhin
b98d32d0c9
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
2018-11-20 06:22:31 +03:00
Azat Khuzhin
5dc88b387f
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
2018-11-13 22:26:12 +03:00
Azat Khuzhin
26ef859aa7
Add evhttp_parse_query_str_flags()
And a set of flags:
- EVHTTP_URI_QUERY_LAST
- EVHTTP_URI_QUERY_NONCONFORMANT

Fixes: #15
2018-10-27 17:59:11 +03:00
Azat Khuzhin
b94d913d90
http: allow non RFC3986 conformant during parsing request-line (http server)
Reported-by: lsdyst@163.com
2018-10-23 00:12:03 +03:00
Azat Khuzhin
64ead341a0
http: do not try to parse request-line if we do not have enough bytes 2018-10-22 23:56:50 +03:00
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