mirror of
https://github.com/libevent/libevent.git
synced 2025-01-09 00:56:20 +08:00
Merge branch 'http-connect'
After this patchset http-connect works with pproxy [1]: $ pproxy -l http://:8000/ -vvv & $ http-connect //127.1:8000 http://kernel.org:80/ [1]: https://pypi.org/project/pproxy/ * http-connect: http-connect: do not check connection on GET cb http-connect: set Host header (for CONNECT and GET) (like curl) http-connect: cleanup and helpers http: do not close connection for CONNECT http: do not assume body for CONNECT Fixes: #946
This commit is contained in:
commit
462f2e9766
4
http.c
4
http.c
@ -417,6 +417,7 @@ evhttp_response_needs_body(struct evhttp_request *req)
|
||||
return (req->response_code != HTTP_NOCONTENT &&
|
||||
req->response_code != HTTP_NOTMODIFIED &&
|
||||
(req->response_code < 100 || req->response_code >= 200) &&
|
||||
req->type != EVHTTP_REQ_CONNECT &&
|
||||
req->type != EVHTTP_REQ_HEAD);
|
||||
}
|
||||
|
||||
@ -541,6 +542,9 @@ evhttp_is_connection_close(int flags, struct evkeyvalq* headers)
|
||||
static int
|
||||
evhttp_is_request_connection_close(struct evhttp_request *req)
|
||||
{
|
||||
if (req->type == EVHTTP_REQ_CONNECT)
|
||||
return 0;
|
||||
|
||||
return
|
||||
evhttp_is_connection_close(req->flags, req->input_headers) ||
|
||||
evhttp_is_connection_close(req->flags, req->output_headers);
|
||||
|
@ -23,15 +23,44 @@ struct connect_base
|
||||
struct evhttp_uri *location;
|
||||
};
|
||||
|
||||
static struct evhttp_uri* uri_parse(const char *str)
|
||||
{
|
||||
struct evhttp_uri *uri;
|
||||
VERIFY(uri = evhttp_uri_parse(str));
|
||||
VERIFY(evhttp_uri_get_host(uri));
|
||||
VERIFY(evhttp_uri_get_port(uri) > 0);
|
||||
return uri;
|
||||
}
|
||||
static char* uri_path(struct evhttp_uri *uri, char buffer[URL_MAX])
|
||||
{
|
||||
struct evhttp_uri *path;
|
||||
|
||||
VERIFY(evhttp_uri_join(uri, buffer, URL_MAX));
|
||||
|
||||
path = evhttp_uri_parse(buffer);
|
||||
evhttp_uri_set_scheme(path, NULL);
|
||||
evhttp_uri_set_userinfo(path, 0);
|
||||
evhttp_uri_set_host(path, NULL);
|
||||
evhttp_uri_set_port(path, -1);
|
||||
VERIFY(evhttp_uri_join(path, buffer, URL_MAX));
|
||||
return buffer;
|
||||
}
|
||||
static char* uri_hostport(struct evhttp_uri *uri, char buffer[URL_MAX])
|
||||
{
|
||||
VERIFY(evhttp_uri_join(uri, buffer, URL_MAX));
|
||||
VERIFY(evhttp_uri_get_host(uri));
|
||||
VERIFY(evhttp_uri_get_port(uri) > 0);
|
||||
evutil_snprintf(buffer, URL_MAX, "%s:%d",
|
||||
evhttp_uri_get_host(uri), evhttp_uri_get_port(uri));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
static void get_cb(struct evhttp_request *req, void *arg)
|
||||
{
|
||||
ev_ssize_t len;
|
||||
struct evbuffer *evbuf;
|
||||
struct evhttp_connection *evcon;
|
||||
|
||||
VERIFY(req);
|
||||
evcon = evhttp_request_get_connection(req);
|
||||
VERIFY(evcon);
|
||||
|
||||
evbuf = evhttp_request_get_input_buffer(req);
|
||||
len = evbuffer_get_length(evbuf);
|
||||
@ -41,26 +70,26 @@ static void get_cb(struct evhttp_request *req, void *arg)
|
||||
|
||||
static void connect_cb(struct evhttp_request *proxy_req, void *arg)
|
||||
{
|
||||
char buffer[URL_MAX];
|
||||
|
||||
struct connect_base *base = arg;
|
||||
struct evhttp_connection *evcon = base->evcon;
|
||||
struct evhttp_uri *location = base->location;
|
||||
struct evhttp_request *req;
|
||||
char buffer[URL_MAX];
|
||||
|
||||
VERIFY(proxy_req);
|
||||
if (evcon) {
|
||||
struct evhttp_request *req = evhttp_request_new(get_cb, NULL);
|
||||
evhttp_add_header(req->output_headers, "Connection", "close");
|
||||
VERIFY(!evhttp_make_request(evcon, req, EVHTTP_REQ_GET,
|
||||
evhttp_uri_join(location, buffer, URL_MAX)));
|
||||
}
|
||||
VERIFY(evcon);
|
||||
|
||||
req = evhttp_request_new(get_cb, NULL);
|
||||
evhttp_add_header(req->output_headers, "Connection", "close");
|
||||
evhttp_add_header(req->output_headers, "Host", evhttp_uri_get_host(location));
|
||||
VERIFY(!evhttp_make_request(evcon, req, EVHTTP_REQ_GET,
|
||||
uri_path(location, buffer)));
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv)
|
||||
{
|
||||
char buffer[URL_MAX];
|
||||
char hostport[URL_MAX];
|
||||
|
||||
struct evhttp_uri *host_port;
|
||||
struct evhttp_uri *location;
|
||||
struct evhttp_uri *proxy;
|
||||
|
||||
@ -75,28 +104,8 @@ int main(int argc, const char **argv)
|
||||
return 1;
|
||||
}
|
||||
|
||||
{
|
||||
VERIFY(proxy = evhttp_uri_parse(argv[1]));
|
||||
VERIFY(evhttp_uri_get_host(proxy));
|
||||
VERIFY(evhttp_uri_get_port(proxy) > 0);
|
||||
}
|
||||
{
|
||||
host_port = evhttp_uri_parse(argv[2]);
|
||||
evhttp_uri_set_scheme(host_port, NULL);
|
||||
evhttp_uri_set_userinfo(host_port, NULL);
|
||||
evhttp_uri_set_path(host_port, NULL);
|
||||
evhttp_uri_set_query(host_port, NULL);
|
||||
evhttp_uri_set_fragment(host_port, NULL);
|
||||
VERIFY(evhttp_uri_get_host(host_port));
|
||||
VERIFY(evhttp_uri_get_port(host_port) > 0);
|
||||
}
|
||||
{
|
||||
location = evhttp_uri_parse(argv[2]);
|
||||
evhttp_uri_set_scheme(location, NULL);
|
||||
evhttp_uri_set_userinfo(location, 0);
|
||||
evhttp_uri_set_host(location, NULL);
|
||||
evhttp_uri_set_port(location, -1);
|
||||
}
|
||||
proxy = uri_parse(argv[1]);
|
||||
location = uri_parse(argv[2]);
|
||||
|
||||
VERIFY(base = event_base_new());
|
||||
VERIFY(evcon = evhttp_connection_base_new(base, NULL,
|
||||
@ -105,17 +114,18 @@ int main(int argc, const char **argv)
|
||||
connect_base.location = location;
|
||||
VERIFY(req = evhttp_request_new(connect_cb, &connect_base));
|
||||
|
||||
uri_hostport(location, hostport);
|
||||
evhttp_add_header(req->output_headers, "Connection", "keep-alive");
|
||||
evhttp_add_header(req->output_headers, "Proxy-Connection", "keep-alive");
|
||||
evutil_snprintf(buffer, URL_MAX, "%s:%d",
|
||||
evhttp_uri_get_host(host_port), evhttp_uri_get_port(host_port));
|
||||
evhttp_make_request(evcon, req, EVHTTP_REQ_CONNECT, buffer);
|
||||
evhttp_add_header(req->output_headers, "Host", hostport);
|
||||
evhttp_make_request(evcon, req, EVHTTP_REQ_CONNECT, hostport);
|
||||
|
||||
event_base_dispatch(base);
|
||||
|
||||
evhttp_connection_free(evcon);
|
||||
event_base_free(base);
|
||||
evhttp_uri_free(proxy);
|
||||
evhttp_uri_free(host_port);
|
||||
evhttp_uri_free(location);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user