Draft of HTTP_Proxy and HTTP_ProxyEngine
This commit is contained in:
@@ -0,0 +1,18 @@
|
||||
#include <stdio.h>
|
||||
#include "../tinyhttp.h"
|
||||
|
||||
int main(void)
|
||||
{
|
||||
HTTP_Proxy proxy;
|
||||
int ret = http_proxy_init(&proxy, "127.0.0.1", 8080);
|
||||
if (ret < 0) {
|
||||
printf("http_proxy_init failed\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
for (;;)
|
||||
http_proxy_wait(&proxy, -1);
|
||||
|
||||
http_proxy_free(&proxy);
|
||||
return 0;
|
||||
}
|
||||
+371
-9
@@ -1000,18 +1000,26 @@ static int parse_response(Scanner *s, HTTP_Response *res)
|
||||
return num_headers;
|
||||
res->num_headers = num_headers;
|
||||
|
||||
int content_length_index = find_header(res->headers, res->num_headers, HTTP_STR("Content-Length"));
|
||||
int content_length_index = find_header(
|
||||
res->headers, res->num_headers,
|
||||
HTTP_STR("Content-Length"));
|
||||
if (content_length_index == -1) {
|
||||
res->body.ptr = NULL;
|
||||
res->body.len = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASSERT(0);
|
||||
return -1;
|
||||
/*
|
||||
// TODO: transfer-encoding
|
||||
|
||||
HTTP_String content_length_str = res->headers[content_length_index].value;
|
||||
|
||||
unsigned long long content_length;
|
||||
if (parse_content_length(content_length_str.ptr, content_length_str.len, &content_length) < 0) {
|
||||
ASSERT(0); // TODO
|
||||
}
|
||||
|
||||
if (content_length > 1<<20) {
|
||||
// TODO
|
||||
ASSERT(0); // TODO
|
||||
}
|
||||
|
||||
if (content_length > (unsigned long long) (s->len - s->cur))
|
||||
@@ -1019,11 +1027,7 @@ static int parse_response(Scanner *s, HTTP_Response *res)
|
||||
|
||||
res->body.ptr = s->src + s->cur;
|
||||
res->body.len = content_length;
|
||||
|
||||
}
|
||||
|
||||
return 1;
|
||||
*/
|
||||
}
|
||||
|
||||
int http_parse_ipv4(char *src, int len, HTTP_IPv4 *ipv4)
|
||||
@@ -2056,6 +2060,138 @@ void http_engine_undo(HTTP_Engine *eng)
|
||||
|
||||
#endif // HTTP_ENGINE
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP PROXY ENGINE
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_PROXY_ENGINE
|
||||
|
||||
#if !HTTP_ENGINE
|
||||
#error "HTTP_PROXY_ENGINE depends on HTTP_ENGINE"
|
||||
#endif
|
||||
|
||||
void http_proxyengine_init(HTTP_ProxyEngine *eng, HTTP_MemoryFunc memfunc, void *memfuncdata)
|
||||
{
|
||||
http_engine_init(&eng->in, 0, memfunc, memfuncdata);
|
||||
http_engine_init(&eng->out, 1, memfunc, memfuncdata);
|
||||
|
||||
ASSERT(http_engine_state(&eng->in) == HTTP_ENGINE_STATE_SERVER_RECV_BUF);
|
||||
ASSERT(http_engine_state(&eng->out) == HTTP_ENGINE_STATE_CLIENT_PREP_URL);
|
||||
}
|
||||
|
||||
void http_proxyengine_free(HTTP_ProxyEngine *eng)
|
||||
{
|
||||
http_engine_free(&eng->in);
|
||||
http_engine_free(&eng->out);
|
||||
}
|
||||
|
||||
HTTP_ProxyEngineState http_proxyengine_state(HTTP_ProxyEngine *eng)
|
||||
{
|
||||
HTTP_EngineState istate = http_engine_state(&eng->in);
|
||||
HTTP_EngineState ostate = http_engine_state(&eng->out);
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_RECV_BUF && ostate == HTTP_ENGINE_STATE_CLIENT_PREP_URL) return HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_BUF;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_RECV_ACK && ostate == HTTP_ENGINE_STATE_CLIENT_PREP_URL) return HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_ACK;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_PREP_STATUS && ostate == HTTP_ENGINE_STATE_CLIENT_SEND_BUF) return HTTP_PROXY_ENGINE_STATE_SERVER_SEND_BUF;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_PREP_STATUS && ostate == HTTP_ENGINE_STATE_CLIENT_SEND_ACK) return HTTP_PROXY_ENGINE_STATE_SERVER_SEND_ACK;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_PREP_STATUS && ostate == HTTP_ENGINE_STATE_CLIENT_RECV_BUF) return HTTP_PROXY_ENGINE_STATE_SERVER_RECV_BUF;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_PREP_STATUS && ostate == HTTP_ENGINE_STATE_CLIENT_RECV_ACK) return HTTP_PROXY_ENGINE_STATE_SERVER_RECV_ACK;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_SEND_BUF && ostate == HTTP_ENGINE_STATE_CLIENT_PREP_URL) return HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_BUF;
|
||||
if (istate == HTTP_ENGINE_STATE_SERVER_SEND_ACK && ostate == HTTP_ENGINE_STATE_CLIENT_PREP_URL) return HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_ACK;
|
||||
ASSERT(istate == HTTP_ENGINE_STATE_SERVER_CLOSED || ostate == HTTP_ENGINE_STATE_CLIENT_CLOSED);
|
||||
return HTTP_PROXY_ENGINE_STATE_CLOSED;
|
||||
}
|
||||
|
||||
void http_proxyengine_close(HTTP_ProxyEngine *eng)
|
||||
{
|
||||
http_engine_close(&eng->in);
|
||||
http_engine_close(&eng->out);
|
||||
}
|
||||
|
||||
char *http_proxyengine_serverrecvbuf(HTTP_ProxyEngine *eng, int *cap)
|
||||
{
|
||||
return http_engine_recvbuf(&eng->in, cap);
|
||||
}
|
||||
|
||||
static void forward_request(HTTP_ProxyEngine *eng)
|
||||
{
|
||||
if (http_engine_state(&eng->in) == HTTP_ENGINE_STATE_SERVER_PREP_STATUS &&
|
||||
http_engine_state(&eng->out) == HTTP_ENGINE_STATE_CLIENT_PREP_URL) {
|
||||
|
||||
HTTP_Request *req = http_engine_getreq(&eng->in);
|
||||
|
||||
char url[] = "???";
|
||||
http_engine_url(&eng->out, req->method, url, 1);
|
||||
|
||||
for (int i = 0; i < req->num_headers; i++)
|
||||
http_engine_header_fmt(&eng->out, "%.*s: %.*s",
|
||||
req->headers[i].name.len, req->headers[i].name.ptr,
|
||||
req->headers[i].value.len, req->headers[i].value.ptr
|
||||
);
|
||||
|
||||
http_engine_body(&eng->out, req->body.ptr, req->body.len);
|
||||
http_engine_done(&eng->out);
|
||||
}
|
||||
}
|
||||
|
||||
static void forward_response(HTTP_ProxyEngine *eng)
|
||||
{
|
||||
if (http_engine_state(&eng->in) == HTTP_ENGINE_STATE_SERVER_PREP_STATUS &&
|
||||
http_engine_state(&eng->out) == HTTP_ENGINE_STATE_CLIENT_PREP_URL) {
|
||||
|
||||
HTTP_Response *res = http_engine_getres(&eng->out);
|
||||
|
||||
http_engine_status(&eng->in, res->status);
|
||||
|
||||
for (int i = 0; i < res->num_headers; i++)
|
||||
http_engine_header_fmt(&eng->in, "%.*s: %.*s",
|
||||
res->headers[i].name.len, res->headers[i].name.ptr,
|
||||
res->headers[i].value.len, res->headers[i].value.ptr
|
||||
);
|
||||
|
||||
http_engine_body(&eng->in, res->body.ptr, res->body.len);
|
||||
http_engine_done(&eng->in);
|
||||
}
|
||||
}
|
||||
|
||||
void http_proxyengine_serverrecvack(HTTP_ProxyEngine *eng, int num)
|
||||
{
|
||||
http_engine_recvack(&eng->in, num);
|
||||
forward_request(eng);
|
||||
}
|
||||
|
||||
char *http_proxyengine_serversendbuf(HTTP_ProxyEngine *eng, int *len)
|
||||
{
|
||||
return http_engine_sendbuf(&eng->in, len);
|
||||
}
|
||||
|
||||
void http_proxyengine_serversendack(HTTP_ProxyEngine *eng, int num)
|
||||
{
|
||||
http_engine_sendack(&eng->in, num);
|
||||
forward_request(eng);
|
||||
}
|
||||
|
||||
char *http_proxyengine_clientrecvbuf(HTTP_ProxyEngine *eng, int *cap)
|
||||
{
|
||||
return http_engine_recvbuf(&eng->out, cap);
|
||||
}
|
||||
|
||||
void http_proxyengine_clientrecvack(HTTP_ProxyEngine *eng, int num)
|
||||
{
|
||||
http_engine_recvack(&eng->out, num);
|
||||
forward_response(eng);
|
||||
}
|
||||
|
||||
char *http_proxyengine_clientsendbuf(HTTP_ProxyEngine *eng, int *len)
|
||||
{
|
||||
return http_engine_sendbuf(&eng->out, len);
|
||||
}
|
||||
|
||||
void http_proxyengine_clientsendack(HTTP_ProxyEngine *eng, int num)
|
||||
{
|
||||
http_engine_sendack(&eng->out, num);
|
||||
forward_response(eng);
|
||||
}
|
||||
|
||||
#endif // HTTP_PROXY_ENGINE
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP CLIENT AND SERVER
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_CLIENT || HTTP_SERVER
|
||||
@@ -3202,6 +3338,232 @@ void http_response_done(HTTP_ResponseHandle res)
|
||||
|
||||
#endif // HTTP_SERVER
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP PROXY
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_PROXY
|
||||
|
||||
#if !HTTP_PROXY_ENGINE
|
||||
#error "HTTP_PROXY depends on HTTP_PROXY_ENGINE"
|
||||
#endif
|
||||
|
||||
int http_proxy_init(HTTP_Proxy *proxy, const char *addr, int port)
|
||||
{
|
||||
struct sockaddr_in buf;
|
||||
buf.sin_family = AF_INET;
|
||||
buf.sin_port = htons(port);
|
||||
memset(&buf.sin_zero, 0, sizeof(buf.sin_zero));
|
||||
if (inet_pton(AF_INET, addr, &buf.sin_addr) != 1)
|
||||
return -1;
|
||||
|
||||
SOCKET listen_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
|
||||
#ifdef _WIN32
|
||||
if (listen_sock == INVALID_SOCKET && WSAGetLastError() == WSANOTINITIALISED) {
|
||||
WSADATA wd;
|
||||
if (WSAStartup(MAKEWORD(2, 2), &wd))
|
||||
return -1;
|
||||
listen_sock = socket(AF_INET, SOCK_STREAM, 0);
|
||||
}
|
||||
#endif
|
||||
|
||||
if (listen_sock == INVALID_SOCKET)
|
||||
return -1;
|
||||
|
||||
if (set_socket_blocking(listen_sock, 0) < 0) {
|
||||
CLOSE_SOCKET(listen_sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (bind(listen_sock, (struct sockaddr*) &buf, sizeof(buf)) < 0) {
|
||||
CLOSE_SOCKET(listen_sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (listen(listen_sock, 32) < 0) {
|
||||
CLOSE_SOCKET(listen_sock);
|
||||
return -1;
|
||||
}
|
||||
|
||||
proxy->num_conns = 0;
|
||||
proxy->listen_sock = listen_sock;
|
||||
for (int i = 0; i < HTTP_MAX_CONNS_PER_PROXY; i++) {
|
||||
proxy->conns[i].client_sock = INVALID_SOCKET;
|
||||
proxy->conns[i].server_sock = INVALID_SOCKET;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
void http_proxy_free(HTTP_Proxy *proxy)
|
||||
{
|
||||
for (int i = 0, j = 0; j < proxy->num_conns; i++) {
|
||||
|
||||
if (proxy->conns[i].client_sock == INVALID_SOCKET)
|
||||
continue;
|
||||
j++;
|
||||
|
||||
CLOSE_SOCKET(proxy->conns[i].client_sock);
|
||||
CLOSE_SOCKET(proxy->conns[i].server_sock);
|
||||
http_proxyengine_free(&proxy->conns[i].eng);
|
||||
}
|
||||
|
||||
CLOSE_SOCKET(proxy->listen_sock);
|
||||
}
|
||||
|
||||
int http_proxy_wait(HTTP_Proxy *proxy, int timeout)
|
||||
{
|
||||
for (;;) {
|
||||
|
||||
int poll_indices[HTTP_MAX_CONNS_PER_PROXY+1];
|
||||
struct pollfd poll_array[HTTP_MAX_CONNS_PER_PROXY+1];
|
||||
int poll_count = 0;
|
||||
|
||||
if (proxy->num_conns < HTTP_MAX_CONNS_PER_PROXY) {
|
||||
poll_indices[poll_count] = -1;
|
||||
poll_array[poll_count].fd = proxy->listen_sock;
|
||||
poll_array[poll_count].events = POLLIN;
|
||||
poll_array[poll_count].revents = 0;
|
||||
poll_count++;
|
||||
}
|
||||
|
||||
for (int i=0, j=0; j<proxy->num_conns; i++) {
|
||||
|
||||
if (proxy->conns[i].client_sock == INVALID_SOCKET)
|
||||
continue;
|
||||
j++;
|
||||
|
||||
SOCKET fd;
|
||||
int events = 0;
|
||||
switch (http_proxyengine_state(&proxy->conns[i].eng)) {
|
||||
case HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_BUF: fd = proxy->conns[i].client_sock; events = POLLIN; break;
|
||||
case HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_BUF: fd = proxy->conns[i].client_sock; events = POLLOUT; break;
|
||||
case HTTP_PROXY_ENGINE_STATE_SERVER_RECV_BUF: fd = proxy->conns[i].server_sock; events = POLLIN; break;
|
||||
case HTTP_PROXY_ENGINE_STATE_SERVER_SEND_BUF: fd = proxy->conns[i].server_sock; events = POLLOUT; break;
|
||||
}
|
||||
ASSERT(events);
|
||||
|
||||
poll_indices[poll_count] = i;
|
||||
poll_array[poll_count].fd = proxy->conns[i].client_sock;
|
||||
poll_array[poll_count].events = events;
|
||||
poll_array[poll_count].revents = 0;
|
||||
poll_count++;
|
||||
}
|
||||
|
||||
int num = POLL(poll_array, poll_count, timeout);
|
||||
|
||||
for (int i = 0; i < poll_count; i++) {
|
||||
|
||||
if (!poll_array[i].revents)
|
||||
continue;
|
||||
|
||||
int j = poll_indices[i];
|
||||
if (j == -1) {
|
||||
|
||||
SOCKET accepted_sock = accept(proxy->listen_sock, NULL, NULL);
|
||||
if (accepted_sock == INVALID_SOCKET) {
|
||||
ASSERT(0); // TODO
|
||||
}
|
||||
|
||||
int i = 0;
|
||||
while (proxy->conns[i].client_sock != INVALID_SOCKET)
|
||||
i++;
|
||||
|
||||
HTTP_ProxyConnection *conn = &proxy->conns[i];
|
||||
conn->client_sock = accepted_sock;
|
||||
conn->server_sock = xxx;
|
||||
http_proxyengine_init(&conn->eng, memfunc, NULL);
|
||||
continue;
|
||||
}
|
||||
|
||||
HTTP_ProxyConnection *conn = &proxy->conns[j];
|
||||
HTTP_ProxyEngine *eng = &conn->eng;
|
||||
|
||||
switch (http_proxyengine_state(eng)) {
|
||||
|
||||
case HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_BUF:
|
||||
{
|
||||
int cap;
|
||||
char *dst = http_proxyengine_clientrecvbuf(eng, &cap);
|
||||
if (dst) {
|
||||
int ret = recv(conn->client_sock, dst, cap, 0);
|
||||
if (ret == 0)
|
||||
http_proxyengine_close(eng);
|
||||
else if (ret < 0) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
http_proxyengine_close(eng);
|
||||
ret = 0;
|
||||
}
|
||||
http_proxyengine_clientrecvack(eng, ret);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_BUF:
|
||||
{
|
||||
int len;
|
||||
char *src = http_proxyengine_clientsendbuf(eng, &len);
|
||||
if (src) {
|
||||
int ret = send(conn->client_sock, src, len, 0);
|
||||
if (ret < 0) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
http_proxyengine_close(eng);
|
||||
ret = 0;
|
||||
}
|
||||
http_proxyengine_clientsendack(eng, ret);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HTTP_PROXY_ENGINE_STATE_SERVER_RECV_BUF:
|
||||
{
|
||||
int cap;
|
||||
char *dst = http_proxyengine_serverrecvbuf(eng, &cap);
|
||||
if (dst) {
|
||||
int ret = recv(conn->server_sock, dst, cap, 0);
|
||||
if (ret == 0)
|
||||
http_proxyengine_close(eng);
|
||||
else if (ret < 0) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
http_proxyengine_close(eng);
|
||||
ret = 0;
|
||||
}
|
||||
http_proxyengine_serverrecvack(eng, ret);
|
||||
}
|
||||
}
|
||||
break;
|
||||
|
||||
case HTTP_PROXY_ENGINE_STATE_SERVER_SEND_BUF:
|
||||
{
|
||||
int len;
|
||||
char *src = http_proxyengine_serversendbuf(eng, &len);
|
||||
if (src) {
|
||||
int ret = send(conn->server_sock, src, len, 0);
|
||||
if (ret < 0) {
|
||||
if (errno != EAGAIN && errno != EWOULDBLOCK && errno != EINTR)
|
||||
http_proxyengine_close(eng);
|
||||
ret = 0;
|
||||
}
|
||||
http_proxyengine_serversendack(eng, ret);
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if (http_proxyengine_state(eng) == HTTP_PROXY_ENGINE_STATE_CLOSED) {
|
||||
http_proxyengine_free(eng);
|
||||
CLOSE_SOCKET(conn->client_sock);
|
||||
CLOSE_SOCKET(conn->server_sock);
|
||||
conn->client_sock = INVALID_SOCKET;
|
||||
conn->server_sock = INVALID_SOCKET;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif // HTTP_PROXY
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP ROUTER
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_ROUTER
|
||||
|
||||
+70
-1
@@ -9,6 +9,10 @@
|
||||
#define HTTP_ENGINE 1
|
||||
#endif
|
||||
|
||||
#ifndef HTTP_PROXY_ENGINE
|
||||
#define HTTP_PROXY_ENGINE 1
|
||||
#endif
|
||||
|
||||
#ifndef HTTP_CLIENT
|
||||
#define HTTP_CLIENT 1
|
||||
#endif
|
||||
@@ -17,6 +21,10 @@
|
||||
#define HTTP_SERVER 1
|
||||
#endif
|
||||
|
||||
#ifndef HTTP_PROXY
|
||||
#define HTTP_PROXY 1
|
||||
#endif
|
||||
|
||||
#ifndef HTTP_ROUTER
|
||||
#define HTTP_ROUTER 1
|
||||
#endif
|
||||
@@ -254,9 +262,46 @@ void http_engine_undo (HTTP_Engine *eng);
|
||||
|
||||
#endif // HTTP_ENGINE
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP PROXY ENGINE
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_PROXY_ENGINE
|
||||
|
||||
typedef struct {
|
||||
HTTP_Engine in;
|
||||
HTTP_Engine out;
|
||||
} HTTP_ProxyEngine;
|
||||
|
||||
typedef enum {
|
||||
HTTP_PROXY_ENGINE_STATE_NONE,
|
||||
HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_BUF,
|
||||
HTTP_PROXY_ENGINE_STATE_CLIENT_RECV_ACK,
|
||||
HTTP_PROXY_ENGINE_STATE_SERVER_SEND_BUF,
|
||||
HTTP_PROXY_ENGINE_STATE_SERVER_SEND_ACK,
|
||||
HTTP_PROXY_ENGINE_STATE_SERVER_RECV_BUF,
|
||||
HTTP_PROXY_ENGINE_STATE_SERVER_RECV_ACK,
|
||||
HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_BUF,
|
||||
HTTP_PROXY_ENGINE_STATE_CLIENT_SEND_ACK,
|
||||
HTTP_PROXY_ENGINE_STATE_CLOSED,
|
||||
} HTTP_ProxyEngineState;
|
||||
|
||||
void http_proxyengine_init(HTTP_ProxyEngine *eng, HTTP_MemoryFunc memfunc, void *memfuncdata);
|
||||
void http_proxyengine_free(HTTP_ProxyEngine *eng);
|
||||
HTTP_ProxyEngineState http_proxyengine_state(HTTP_ProxyEngine *eng);
|
||||
void http_proxyengine_close(HTTP_ProxyEngine *eng);
|
||||
char* http_proxyengine_serverrecvbuf(HTTP_ProxyEngine *eng, int *cap);
|
||||
void http_proxyengine_serverrecvack(HTTP_ProxyEngine *eng, int num);
|
||||
char* http_proxyengine_serversendbuf(HTTP_ProxyEngine *eng, int *len);
|
||||
void http_proxyengine_serversendack(HTTP_ProxyEngine *eng, int num);
|
||||
char* http_proxyengine_clientrecvbuf(HTTP_ProxyEngine *eng, int *cap);
|
||||
void http_proxyengine_clientrecvack(HTTP_ProxyEngine *eng, int num);
|
||||
char* http_proxyengine_clientsendbuf(HTTP_ProxyEngine *eng, int *len);
|
||||
void http_proxyengine_clientsendack(HTTP_ProxyEngine *eng, int num);
|
||||
|
||||
#endif // HTTP_PROXY_ENGINE
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP CLIENT AND SERVER
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_CLIENT || HTTP_SERVER
|
||||
#if HTTP_CLIENT || HTTP_SERVER || HTTP_PROXY
|
||||
|
||||
typedef unsigned long long HTTP_Socket;
|
||||
|
||||
@@ -387,6 +432,30 @@ void http_response_undo(HTTP_ResponseHandle res);
|
||||
|
||||
#endif // HTTP_SERVER
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP PROXY
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_PROXY
|
||||
|
||||
#define HTTP_MAX_CONNS_PER_PROXY (1<<10)
|
||||
|
||||
typedef struct {
|
||||
HTTP_Socket client_sock;
|
||||
HTTP_Socket server_sock;
|
||||
HTTP_ProxyEngine eng;
|
||||
} HTTP_ProxyConnection;
|
||||
|
||||
typedef struct {
|
||||
HTTP_Socket listen_sock;
|
||||
int num_conns;
|
||||
HTTP_ProxyConnection conns[HTTP_MAX_CONNS_PER_PROXY];
|
||||
} HTTP_Proxy;
|
||||
|
||||
int http_proxy_init(HTTP_Proxy *proxy, const char *addr, int port);
|
||||
void http_proxy_free(HTTP_Proxy *proxy);
|
||||
int http_proxy_wait(HTTP_Proxy *proxy, int timeout);
|
||||
|
||||
#endif // HTTP_PROXY
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
// HTTP ROUTER
|
||||
/////////////////////////////////////////////////////////////////////
|
||||
#if HTTP_ROUTER
|
||||
|
||||
Reference in New Issue
Block a user