This commit addresses a minor inconsistency identified in the
documentation of multiple `evhttp` callback functions within
the `event2/http.h` header file. It was observed that the word
"additional" was presumably missing in the description of the
`arg` parameter for several functions. This oversight led to
an incorrect phrasing: "an context argument for the callback."
The documentation for the following functions has been updated
to rectify this issue:
- `evhttp_set_gencb`
- `evhttp_set_bevcb`
- `evhttp_set_newreqcb`
- `evhttp_set_errorcb`
This commit solely improves the readability of the function
descriptions without altering any functional aspects of the
code.
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>
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
@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
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)
- Documentation for `bufferevent_compat.h` and `rpc.h` is not generated
since the `@file` command is missing. It can be fixed by adding
`@file` in file comment block.
- The briefs of buffer.h,bufferevent.h and some other files are missing.
Adding `@brief` command can fix it.
- The parameters in the function declaration are different from the
parameters following the `@param` command.We should change them to the
same.
- Documentation of `watch.h` is not generated since `watch.h` has not
been added to the Doxyfile `INPUT` tag.
- Add link to the watch.h in event.h
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>
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: #692Fixes: #715
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/11368Closes: #578 (patch cherry picked)
Replaces reference in the http.h include header file to evhttp_get_decoded_uri
with evhttp_uridecode. There is no function called evhttp_get_decoded_uri.
Like in `sockaddr_in` structure in /usr/include/netinet/in.h
@azat: convert all other users (bench, compat, ..) and tweak message
Fixes: #178Fixes: #196
Refs: 6bf1ca78
Link: https://codereview.appspot.com/156040043/#msg4
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
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
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
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.
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.
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.
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
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)
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)
Previously we used include-guards with names like _EVENT2_EVENT_H_.
But C reserves macros beginning with an underscore for use by the
system. This patch converts all include guards for files like
include/event2/<fname.h> to be of form EVENT2_<FNAME_H>_INCLUDED_,
and all Libevent 1.x headers in include/<fname.h> to be of the form
EVENT1_<FNAME_H>_INCLUDED_, and all internal libevent headers with
names like <fname.h> to the form <FNAME_H>_INCLUDED_.
FNAME_H is here derived from fname.h by replacing every
non-macro-usable character in fname.h with an underscore, and
putting every remaining character in uppercase.
This is an automatic conversion. The script that produced was made by
running the following script over all header files:
=====
#!/usr/bin/perl -w
# Run this on every .h file except config.h, sys/queue.h, WIN32/event2/event-config.h
use strict;
my %macros = ();
my %skipped = ();
FILE: for my $fn (@ARGV) {
my $f = $fn;
if ($fn !~ /^\.\//) {
$f = "./$fn";
}
if ($f eq './config.h' or
$f =~ m#/tree.h$# or
$f =~ m#/queue.h# or
$f =~ m#/event-config.h# or
$f =~ m#/evconfig-private.h#) {
$skipped{$fn} = 1;
next FILE;
}
$skipped{$fn} = 0;
open(F, $fn);
while (<F>) {
if (/^#ifndef ([A-Za-z0-9_]+)/) {
$macros{$fn} = $1;
next FILE;
}
}
}
print "#!/usr/bin/perl -w -i -p\n\n";
for my $fn (@ARGV) {
if (! exists $macros{$fn}) {
print "# No macro known for $fn!\n" if (!$skipped{$fn});
} else {
if ($macros{$fn} !~ /_H_?$/) {
print "# Weird macro for $fn...\n";
}
my $goodmacro = uc $fn;
$goodmacro =~ s#^\./##;
$goodmacro =~ s#INCLUDE/EVENT2#EVENT2#;
$goodmacro =~ s#INCLUDE/#EVENT1_#;
$goodmacro =~ s#TEST/##;
$goodmacro =~ s#[\/\-\.]#_#g;
print "s/(?<![A-Za-z0-9_])$macros{$fn}(?![A-Za-z0-9_])/${goodmacro}_INCLUDED_/g;\n"
}
}
=== And then running the script below that it generated over all
=== the .h files again
#!/usr/bin/perl -w -i -p
s/(?<![A-Za-z0-9_])_BUFFEREVENT_INTERNAL_H_(?![A-Za-z0-9_])/BUFFEREVENT_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_CHANGELIST_H_(?![A-Za-z0-9_])/CHANGELIST_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_DEFER_INTERNAL_H_(?![A-Za-z0-9_])/DEFER_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVBUFFER_INTERNAL_H_(?![A-Za-z0-9_])/EVBUFFER_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_INTERNAL_H_(?![A-Za-z0-9_])/EVENT_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVMAP_H_(?![A-Za-z0-9_])/EVMAP_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVRPC_INTERNAL_H_(?![A-Za-z0-9_])/EVRPC_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVSIGNAL_H_(?![A-Za-z0-9_])/EVSIGNAL_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVTHREAD_INTERNAL_H_(?![A-Za-z0-9_])/EVTHREAD_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_HT_H(?![A-Za-z0-9_])/HT_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_HTTP_INTERNAL_H_(?![A-Za-z0-9_])/HTTP_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVDNS_H_(?![A-Za-z0-9_])/EVENT1_EVDNS_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_H_(?![A-Za-z0-9_])/EVENT1_EVENT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_BUFFER_H_(?![A-Za-z0-9_])/EVENT2_BUFFER_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_BUFFER_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_BUFFER_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_BUFFEREVENT_H_(?![A-Za-z0-9_])/EVENT2_BUFFEREVENT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_BUFFEREVENT_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_BUFFEREVENT_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_BUFFEREVENT_SSL_H_(?![A-Za-z0-9_])/EVENT2_BUFFEREVENT_SSL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_BUFFEREVENT_STRUCT_H_(?![A-Za-z0-9_])/EVENT2_BUFFEREVENT_STRUCT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_DNS_H_(?![A-Za-z0-9_])/EVENT2_DNS_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_DNS_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_DNS_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_DNS_STRUCT_H_(?![A-Za-z0-9_])/EVENT2_DNS_STRUCT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_EVENT_H_(?![A-Za-z0-9_])/EVENT2_EVENT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_EVENT_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_EVENT_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_EVENT_STRUCT_H_(?![A-Za-z0-9_])/EVENT2_EVENT_STRUCT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_HTTP_H_(?![A-Za-z0-9_])/EVENT2_HTTP_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_HTTP_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_HTTP_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_HTTP_STRUCT_H_(?![A-Za-z0-9_])/EVENT2_HTTP_STRUCT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_EVENT_KEYVALQ_STRUCT_H_(?![A-Za-z0-9_])/EVENT2_KEYVALQ_STRUCT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_LISTENER_H_(?![A-Za-z0-9_])/EVENT2_LISTENER_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_RPC_H_(?![A-Za-z0-9_])/EVENT2_RPC_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_RPC_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_RPC_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_RPC_STRUCT_H_(?![A-Za-z0-9_])/EVENT2_RPC_STRUCT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_TAG_H_(?![A-Za-z0-9_])/EVENT2_TAG_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_TAG_COMPAT_H_(?![A-Za-z0-9_])/EVENT2_TAG_COMPAT_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_THREAD_H_(?![A-Za-z0-9_])/EVENT2_THREAD_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT2_UTIL_H_(?![A-Za-z0-9_])/EVENT2_UTIL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVHTTP_H_(?![A-Za-z0-9_])/EVENT1_EVHTTP_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVRPC_H_(?![A-Za-z0-9_])/EVENT1_EVRPC_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVUTIL_H_(?![A-Za-z0-9_])/EVENT1_EVUTIL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_IOCP_INTERNAL_H(?![A-Za-z0-9_])/IOCP_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_IPV6_INTERNAL_H(?![A-Za-z0-9_])/IPV6_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_LOG_H_(?![A-Za-z0-9_])/LOG_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_MIN_HEAP_H_(?![A-Za-z0-9_])/MINHEAP_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_MM_INTERNAL_H(?![A-Za-z0-9_])/MM_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_RATELIM_INTERNAL_H_(?![A-Za-z0-9_])/RATELIM_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_STRLCPY_INTERNAL_H_(?![A-Za-z0-9_])/STRLCPY_INTERNAL_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_REGRESS_H_(?![A-Za-z0-9_])/REGRESS_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_TESTUTILS_H(?![A-Za-z0-9_])/REGRESS_TESTUTILS_H_INCLUDED_/g;
# Weird macro for test/tinytest.h...
s/(?<![A-Za-z0-9_])TINYTEST_H_INCLUDED_(?![A-Za-z0-9_])/TINYTEST_H_INCLUDED_/g;
# No macro known for test/tinytest_local.h!
# Weird macro for test/tinytest_macros.h...
s/(?<![A-Za-z0-9_])TINYTEST_MACROS_H_INCLUDED_(?![A-Za-z0-9_])/TINYTEST_MACROS_H_INCLUDED_/g;
s/(?<![A-Za-z0-9_])_EVENT_UTIL_INTERNAL_H(?![A-Za-z0-9_])/UTIL_INTERNAL_H_INCLUDED_/g;
Applies the function specified in the first argument to all
evhttp_bound_sockets associated with a struct evhttp. The user
must not attempt to free or remove any connections, sockets or
listeners in the callback function.