mirror of
https://github.com/cuberite/libevent.git
synced 2025-09-08 03:44:22 -04:00
fix a bug where it was not possible to bind multiple sockets to the same http
server; test that binding multiple sockets works. svn:r769
This commit is contained in:
parent
5786d5255a
commit
f940eb4b8d
3
evhttp.h
3
evhttp.h
@ -97,6 +97,9 @@ int evhttp_bind_socket(struct evhttp *http, const char *address, u_short port);
|
||||
* descriptor passing in situations where an http servers does not have
|
||||
* permissions to bind to a low-numbered port.
|
||||
*
|
||||
* Can be called multiple times to have the http server listen to
|
||||
* multiple different sockets.
|
||||
*
|
||||
* @param http a pointer to an evhttp object
|
||||
* @param fd a socket fd that is ready for accepting connections
|
||||
* @return 0 on success, -1 on failure.
|
||||
|
@ -91,8 +91,15 @@ struct evhttp_cb {
|
||||
/* both the http server as well as the rpc system need to queue connections */
|
||||
TAILQ_HEAD(evconq, evhttp_connection);
|
||||
|
||||
/* each bound socket is stored in one of these */
|
||||
struct evhttp_bound_socket {
|
||||
TAILQ_ENTRY(evhttp_bound_socket) (next);
|
||||
|
||||
struct event bind_ev;
|
||||
};
|
||||
|
||||
struct evhttp {
|
||||
struct event bind_ev;
|
||||
TAILQ_HEAD(boundq, evhttp_bound_socket) sockets;
|
||||
|
||||
TAILQ_HEAD(httpcbq, evhttp_cb) callbacks;
|
||||
struct evconq connections;
|
||||
|
39
http.c
39
http.c
@ -1976,12 +1976,30 @@ evhttp_bind_socket(struct evhttp *http, const char *address, u_short port)
|
||||
int
|
||||
evhttp_accept_socket(struct evhttp *http, evutil_socket_t fd)
|
||||
{
|
||||
struct event *ev = &http->bind_ev;
|
||||
struct evhttp_bound_socket *bound;
|
||||
struct event *ev;
|
||||
int res;
|
||||
|
||||
bound = mm_malloc(sizeof(struct evhttp_bound_socket));
|
||||
if (bound == NULL)
|
||||
return (-1);
|
||||
|
||||
ev = &bound->bind_ev;
|
||||
|
||||
/* Schedule the socket for accepting */
|
||||
event_assign(ev, http->base, fd, EV_READ | EV_PERSIST, accept_socket, http);
|
||||
event_assign(ev, http->base,
|
||||
fd, EV_READ | EV_PERSIST, accept_socket, http);
|
||||
|
||||
return (event_add(ev, NULL));
|
||||
res = event_add(ev, NULL);
|
||||
|
||||
if (res == -1) {
|
||||
mm_free(bound);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
TAILQ_INSERT_TAIL(&http->sockets, bound, next);
|
||||
|
||||
return (0);
|
||||
}
|
||||
|
||||
static struct evhttp*
|
||||
@ -1996,6 +2014,7 @@ evhttp_new_object(void)
|
||||
|
||||
http->timeout = -1;
|
||||
|
||||
TAILQ_INIT(&http->sockets);
|
||||
TAILQ_INIT(&http->callbacks);
|
||||
TAILQ_INIT(&http->connections);
|
||||
|
||||
@ -2034,11 +2053,19 @@ evhttp_free(struct evhttp* http)
|
||||
{
|
||||
struct evhttp_cb *http_cb;
|
||||
struct evhttp_connection *evcon;
|
||||
evutil_socket_t fd = http->bind_ev.ev_fd;
|
||||
struct evhttp_bound_socket *bound;
|
||||
evutil_socket_t fd;
|
||||
|
||||
/* Remove the accepting part */
|
||||
event_del(&http->bind_ev);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
while ((bound = TAILQ_FIRST(&http->sockets)) != NULL) {
|
||||
TAILQ_REMOVE(&http->sockets, bound, next);
|
||||
|
||||
fd = bound->bind_ev.ev_fd;
|
||||
event_del(&bound->bind_ev);
|
||||
EVUTIL_CLOSESOCKET(fd);
|
||||
|
||||
mm_free(bound);
|
||||
}
|
||||
|
||||
while ((evcon = TAILQ_FIRST(&http->connections)) != NULL) {
|
||||
/* evhttp_connection_free removes the connection */
|
||||
|
@ -261,6 +261,12 @@ http_basic_test(void)
|
||||
fprintf(stdout, "Testing Basic HTTP Server: ");
|
||||
|
||||
http = http_setup(&port, NULL);
|
||||
|
||||
/* bind to a second socket */
|
||||
if (evhttp_bind_socket(http, "127.0.0.1", port + 1) == -1) {
|
||||
fprintf(stdout, "FAILED (bind)\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
fd = http_connect("127.0.0.1", port);
|
||||
|
||||
@ -278,16 +284,41 @@ http_basic_test(void)
|
||||
|
||||
event_dispatch();
|
||||
|
||||
if (test_ok != 2) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* connect to the second port */
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
|
||||
fd = http_connect("127.0.0.1", port + 1);
|
||||
|
||||
/* Stupid thing to send a request */
|
||||
bev = bufferevent_new(fd, http_readcb, http_writecb,
|
||||
http_errorcb, NULL);
|
||||
|
||||
http_request =
|
||||
"GET /test HTTP/1.1\r\n"
|
||||
"Host: somehost\r\n"
|
||||
"Connection: close\r\n"
|
||||
"\r\n";
|
||||
|
||||
bufferevent_write(bev, http_request, strlen(http_request));
|
||||
|
||||
event_dispatch();
|
||||
|
||||
bufferevent_free(bev);
|
||||
close(fd);
|
||||
|
||||
evhttp_free(http);
|
||||
|
||||
if (test_ok != 2) {
|
||||
if (test_ok != 4) {
|
||||
fprintf(stdout, "FAILED\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
|
||||
fprintf(stdout, "OK\n");
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user