Lines Matching refs:parser

8 #include "http-parser.h"
10 #include "http-header-parser.h"
13 #include "http-message-parser.h"
17 void http_message_parser_init(struct http_message_parser *parser,
21 i_zero(parser);
22 parser->input = input;
23 i_stream_ref(parser->input);
25 parser->header_limits = *hdr_limits;
26 parser->max_payload_size = max_payload_size;
27 parser->flags = flags;
30 void http_message_parser_deinit(struct http_message_parser *parser)
32 if (parser->header_parser != NULL)
33 http_header_parser_deinit(&parser->header_parser);
34 pool_unref(&parser->msg.pool);
35 i_stream_unref(&parser->payload);
36 i_stream_unref(&parser->input);
39 void http_message_parser_restart(struct http_message_parser *parser,
42 i_assert(parser->payload == NULL);
44 if (parser->header_parser == NULL) {
47 if ((parser->flags & HTTP_MESSAGE_PARSE_FLAG_STRICT) != 0)
49 parser->header_parser = http_header_parser_init
50 (parser->input, &parser->header_limits, hdr_flags);
52 http_header_parser_reset(parser->header_parser);
55 pool_unref(&parser->msg.pool);
56 i_zero(&parser->msg);
58 parser->msg.pool = pool;
61 parser->msg.date = (time_t)-1;
64 pool_t http_message_parser_get_pool(struct http_message_parser *parser)
66 if (parser->msg.pool == NULL)
67 parser->msg.pool = pool_alloconly_create("http_message", 4096);
68 return parser->msg.pool;
71 int http_message_parse_version(struct http_message_parser *parser)
73 const unsigned char *p = parser->cur;
74 const size_t size = parser->end - parser->cur;
76 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_NONE;
77 parser->error = NULL;
88 parser->error = "Bad HTTP version";
89 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
92 parser->msg.version_major = p[5] - '0';
93 parser->msg.version_minor = p[7] - '0';
94 parser->cur += 8;
98 int http_message_parse_finish_payload(struct http_message_parser *parser)
104 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_NONE;
105 parser->error = NULL;
107 if (parser->payload == NULL)
110 while ((ret = i_stream_read_more(parser->payload, &data, &size)) > 0)
111 i_stream_skip(parser->payload, size);
112 if (ret == 0 || parser->payload->stream_errno != 0) {
114 if (parser->payload->stream_errno == EMSGSIZE) {
115 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_PAYLOAD_TOO_LARGE;
116 parser->error = "Payload is too large";
117 } else if (parser->payload->stream_errno == EIO) {
118 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
119 parser->error = "Invalid payload";
121 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_STREAM;
122 parser->error = t_strdup_printf("Stream error while skipping payload: %s",
123 i_stream_get_error(parser->payload));
129 i_stream_destroy(&parser->payload);
134 http_message_parse_header(struct http_message_parser *parser,
141 pool = http_message_parser_get_pool(parser);
142 if (parser->msg.header == NULL)
143 parser->msg.header = http_header_create(pool, 32);
144 hdr = http_header_field_add(parser->msg.header, name, data, size);
175 parser->msg.connection_close = TRUE;
176 if (!array_is_created(&parser->msg.connection_options))
177 p_array_init(&parser->msg.connection_options, pool, 4);
178 opt_idx = array_append_space(&parser->msg.connection_options);
183 parser->error = "Invalid Connection header";
184 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
192 if (parser->msg.have_content_length) {
195 parser->error = "Duplicate Content-Length header";
196 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
204 if (str_to_uoff(hdr->value, &parser->msg.content_length) < 0) {
205 parser->error= "Invalid Content-Length header";
206 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
209 parser->msg.have_content_length = TRUE;
216 if (parser->msg.date != (time_t)-1) {
217 if ((parser->flags & HTTP_MESSAGE_PARSE_FLAG_STRICT) != 0) {
218 parser->error = "Duplicate Date header";
219 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
229 if (!http_date_parse(data, size, &parser->msg.date) &&
230 (parser->flags & HTTP_MESSAGE_PARSE_FLAG_STRICT) != 0) {
231 parser->error = "Invalid Date header";
232 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
247 /* FIXME: move this to response parser */
248 parser->msg.location = hdr->value;
258 if (!array_is_created(&parser->msg.transfer_encoding))
259 p_array_init(&parser->msg.transfer_encoding, pool, 4);
282 coding = array_append_space(&parser->msg.transfer_encoding);
347 array_count(&parser->msg.transfer_encoding) == 0) {
348 parser->error = "Invalid Transfer-Encoding header";
349 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
361 int http_message_parse_headers(struct http_message_parser *parser)
364 struct http_message *msg = &parser->msg;
369 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_NONE;
370 parser->error = NULL;
373 while ((ret=http_header_parse_next_field(parser->header_parser,
380 pool = http_message_parser_get_pool(parser);
381 if (parser->msg.header == NULL)
382 parser->msg.header = http_header_create(pool, 1);
390 if (array_is_created(&parser->msg.connection_options)) {
402 if (http_message_parse_header(parser,
408 if (parser->input->eof || parser->input->stream_errno != 0) {
409 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_STREAM;
410 parser->error = "Broken stream";
412 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
413 parser->error = t_strdup_printf("Failed to parse header: %s", error);
432 int http_message_parse_body(struct http_message_parser *parser, bool request)
436 i_assert(parser->payload == NULL);
438 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_NONE;
439 parser->error = NULL;
441 if (array_is_created(&parser->msg.transfer_encoding)) {
446 array_foreach(&parser->msg.transfer_encoding, coding) {
450 if ((parser->error_code == HTTP_MESSAGE_PARSE_ERROR_NONE)
456 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BAD_MESSAGE;
457 parser->error = t_strdup_printf(
463 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
464 parser->error = "Chunked Transfer-Encoding must be last";
466 } else if (parser->error_code == HTTP_MESSAGE_PARSE_ERROR_NONE) {
467 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_NOT_IMPLEMENTED;
468 parser->error = t_strdup_printf(
475 parser->payload = http_transfer_chunked_istream_create
476 (parser->input, parser->max_payload_size);
486 parser->payload =
487 i_stream_create_limit(parser->input, (size_t)-1);
497 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_BROKEN_MESSAGE;
498 parser->error = "Final Transfer-Encoding in request is not chunked";
513 if (parser->msg.have_content_length)
514 http_header_field_delete(parser->msg.header, "Content-Length");
516 } else if (parser->msg.content_length > 0) {
517 if (parser->max_payload_size > 0
518 && parser->msg.content_length > parser->max_payload_size) {
519 parser->error_code = HTTP_MESSAGE_PARSE_ERROR_PAYLOAD_TOO_LARGE;
520 parser->error = "Payload is too large";
525 input = i_stream_create_limit(parser->input,
526 parser->msg.content_length);
529 parser->payload = i_stream_create_sized_with_callback(input,
530 parser->msg.content_length,
533 } else if (!parser->msg.have_content_length && !request) {
546 parser->payload =
547 i_stream_create_limit(parser->input, (size_t)-1);
549 if (parser->error_code != HTTP_MESSAGE_PARSE_ERROR_NONE)