Branch
Hash :
a8cd11f9
Author :
Date :
2024-10-29T11:18:48
remove proxy-connection from http-connect
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130
#include "event2/event-config.h"
#include <event2/event.h>
#include <event2/http.h>
#include <event2/http_struct.h>
#include <event2/buffer.h>
#include <stdlib.h>
#include <stdio.h>
#include <limits.h>
#define VERIFY(cond) do { \
if (!(cond)) { \
fprintf(stderr, "[error] %s\n", #cond); \
exit(EXIT_FAILURE); \
} \
} while (0); \
#define URL_MAX 4096
struct connect_base
{
struct evhttp_connection *evcon;
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;
VERIFY(req);
evbuf = evhttp_request_get_input_buffer(req);
len = evbuffer_get_length(evbuf);
fwrite(evbuffer_pullup(evbuf, len), len, 1, stdout);
evbuffer_drain(evbuf, len);
}
static void connect_cb(struct evhttp_request *proxy_req, void *arg)
{
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);
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 hostport[URL_MAX];
struct evhttp_uri *location;
struct evhttp_uri *proxy;
struct event_base *base;
struct evhttp_connection *evcon;
struct evhttp_request *req;
struct connect_base connect_base;
if (argc != 3) {
printf("Usage: %s proxy url\n", argv[0]);
return 1;
}
proxy = uri_parse(argv[1]);
location = uri_parse(argv[2]);
VERIFY(base = event_base_new());
VERIFY(evcon = evhttp_connection_base_new(base, NULL,
evhttp_uri_get_host(proxy), evhttp_uri_get_port(proxy)));
connect_base.evcon = evcon;
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, "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(location);
return 0;
}