Files
utun2/src/proxy/http_proxy.h
T

67 lines
3.0 KiB
C

/* Потоковый HTTP/1.x codec локального proxy. Не владеет сокетами/DNS/ETCP.
* Заголовки проверяются целиком до пересылки; тело передаётся ограниченными порциями.
* emit получает исходное число байт для возврата ETCP credit после доставки результата.
* Возврат feed: 0=нужно продолжение, 1=сообщение завершено, <0=HTTP error status. */
#ifndef HTTP_PROXY_H
#define HTTP_PROXY_H
#include <stddef.h>
#include <stdint.h>
#define HTTP_PROXY_LINE_LIMIT 8192
#define HTTP_PROXY_HEADER_LIMIT 32768
#define HTTP_PROXY_FIELDS_LIMIT 512
typedef int (*http_proxy_emit)(void* arg, const uint8_t* data, size_t len, size_t source_len);
struct http_proxy_field { char* name; char* value; };
enum http_proxy_body_state { HTTP_BODY_NONE, HTTP_BODY_LENGTH, HTTP_BODY_EOF, HTTP_BODY_CHUNK_SIZE,
HTTP_BODY_CHUNK_DATA, HTTP_BODY_CHUNK_CRLF, HTTP_BODY_TRAILERS, HTTP_BODY_DONE };
struct http_proxy_message {
char headers[HTTP_PROXY_HEADER_LIMIT + 1];
size_t header_len;
size_t first_line_len;
struct http_proxy_field fields[HTTP_PROXY_FIELDS_LIMIT];
unsigned field_count;
uint8_t headers_done;
uint8_t minor;
uint8_t close;
uint8_t chunked;
uint8_t has_length;
uint8_t upgrade;
uint8_t decode_chunks;
unsigned status;
uint64_t length;
enum http_proxy_body_state body;
uint64_t remaining;
char line[HTTP_PROXY_LINE_LIMIT + 1];
size_t line_len;
size_t trailer_len;
unsigned crlf_pos;
};
struct http_proxy_request {
char host[256];
char authority[264];
char upgrade[HTTP_PROXY_LINE_LIMIT + 1];
uint16_t port;
uint8_t connect;
uint8_t head;
uint8_t close;
uint8_t minor;
};
// Накапливает только заголовки; хвост входа остаётся у вызывающей стороны.
int http_proxy_headers_feed(struct http_proxy_message* m, const uint8_t* data, size_t len, size_t* used);
// Проверяет запрос и отправляет реконструированные заголовки через emit (кроме CONNECT).
int http_proxy_request_parse(struct http_proxy_message* m, struct http_proxy_request* r, http_proxy_emit emit, void* arg);
// Проверяет ответ, учитывает HEAD/Upgrade и формирует собственные connection headers.
int http_proxy_response_parse(struct http_proxy_message* m, const struct http_proxy_request* r,
int close_client, http_proxy_emit emit, void* arg);
// Определяет точную границу тела, фильтрует trailers; поддерживает произвольные TCP-разбиения.
int http_proxy_body_feed(struct http_proxy_message* m, const uint8_t* data, size_t len, size_t* used,
http_proxy_emit emit, void* arg);
#endif