/* Потоковый 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 #include #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