b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#ifndef HTTP_MESSAGE_PARSER_H
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#define HTTP_MESSAGE_PARSER_H
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#include "http-response.h"
9e7bf91667639a2390207ab4d90bf88e2afcec2aStephan Bosch#include "http-transfer.h"
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch#include "http-header.h"
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Boschenum http_message_parse_error {
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch HTTP_MESSAGE_PARSE_ERROR_NONE = 0, /* no error */
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch HTTP_MESSAGE_PARSE_ERROR_BROKEN_STREAM, /* stream error */
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE, /* unrecoverable generic error */
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch HTTP_MESSAGE_PARSE_ERROR_BAD_MESSAGE, /* recoverable generic error */
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch HTTP_MESSAGE_PARSE_ERROR_NOT_IMPLEMENTED, /* used unimplemented feature
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch (recoverable) */
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch HTTP_MESSAGE_PARSE_ERROR_PAYLOAD_TOO_LARGE /* message payload is too large
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch (fatal) */
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Bosch};
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Bosch
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Boschenum http_message_parse_flags {
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch /* Strictly adhere to the HTTP protocol specification */
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch HTTP_MESSAGE_PARSE_FLAG_STRICT = BIT(0)
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch};
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstruct http_message {
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Bosch pool_t pool;
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen unsigned int version_major;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen unsigned int version_minor;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch struct http_header *header;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
e8f1e510df3ab051a816715c2056f0d10aee929eStephan Bosch time_t date;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen uoff_t content_length;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen const char *location;
9e7bf91667639a2390207ab4d90bf88e2afcec2aStephan Bosch ARRAY_TYPE(http_transfer_coding) transfer_encoding;
9e7bf91667639a2390207ab4d90bf88e2afcec2aStephan Bosch ARRAY_TYPE(const_string) connection_options;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool connection_close:1;
0dffa25d211be541ee3c953b23566a1a990789dfTimo Sirainen bool have_content_length:1;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen};
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenstruct http_message_parser {
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct istream *input;
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch
feba5e502b2131c9a1c766b7ef9ff041dbf71d1dStephan Bosch struct http_header_limits header_limits;
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch uoff_t max_payload_size;
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch enum http_message_parse_flags flags;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
8f985b8241246b321db52b9f63d2e6a4a83d4707Stephan Bosch const unsigned char *begin, *cur, *end;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Bosch const char *error;
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Bosch enum http_message_parse_error error_code;
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Bosch
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct http_header_parser *header_parser;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct istream *payload;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen pool_t msg_pool;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen struct http_message msg;
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen};
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenvoid http_message_parser_init(struct http_message_parser *parser,
1175415b88ff168e367c77df23901eada13225b9Stephan Bosch struct istream *input, const struct http_header_limits *hdr_limits,
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch uoff_t max_payload_size, enum http_message_parse_flags flags)
7ebcb054e0d3cc4be54038cbf763ec4189d9725bStephan Bosch ATTR_NULL(3);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenvoid http_message_parser_deinit(struct http_message_parser *parser);
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Boschvoid http_message_parser_restart(struct http_message_parser *parser,
6dad0888fcec8372f230941c70d8940b8c203b32Stephan Bosch pool_t pool);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
1ec26e0b70ac7f8a4e3dfbc59aa77f572651d5aeStephan Boschpool_t http_message_parser_get_pool(struct http_message_parser *parser);
1ec26e0b70ac7f8a4e3dfbc59aa77f572651d5aeStephan Bosch
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Boschint http_message_parse_finish_payload(struct http_message_parser *parser);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainenint http_message_parse_version(struct http_message_parser *parser);
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Boschint http_message_parse_headers(struct http_message_parser *parser);
208dcaf62332b80b220c8c66e776f7cc0c39253bStephan Boschint http_message_parse_body(struct http_message_parser *parser, bool request);
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen
b72c3363092b73cab1da2de4a9d75592e7d8fd6bTimo Sirainen#endif