]> git.ipfire.org Git - thirdparty/dovecot/core.git/commitdiff
lib-http: Don't silently truncate response payload if server disconnects during it.
authorTimo Sirainen <tss@iki.fi>
Mon, 28 Sep 2015 12:00:04 +0000 (15:00 +0300)
committerTimo Sirainen <tss@iki.fi>
Mon, 28 Sep 2015 12:00:04 +0000 (15:00 +0300)
src/lib-http/http-message-parser.c

index 5a52e295ddc8f9cdbffa5b17bb59b5cebc13a97a..6b92992e68dbd1354c5ed683521b82f862c7151f 100644 (file)
@@ -3,6 +3,8 @@
 #include "lib.h"
 #include "array.h"
 #include "istream.h"
+#include "iostream.h"
+#include "istream-sized.h"
 #include "http-parser.h"
 #include "http-header.h"
 #include "http-header-parser.h"
@@ -383,8 +385,22 @@ int http_message_parse_headers(struct http_message_parser *parser)
        return ret;
 }
 
+static const char *
+http_istream_error_callback(const struct istream_sized_error_data *data,
+                           struct istream *input)
+{
+       i_assert(data->eof);
+       i_assert(data->v_offset + data->new_bytes < data->wanted_size);
+
+       return t_strdup_printf("Disconnected from server at offset %"PRIuUOFF_T
+               " (wanted %"PRIuUOFF_T"): %s", data->v_offset + data->new_bytes,
+               data->wanted_size, io_stream_get_disconnect_reason(input, NULL));
+}
+
 int http_message_parse_body(struct http_message_parser *parser, bool request)
 {
+       struct istream *input;
+
        parser->error_code = HTTP_MESSAGE_PARSE_ERROR_NONE;
        parser->error = NULL;
  
@@ -472,9 +488,14 @@ int http_message_parse_body(struct http_message_parser *parser, bool request)
                }
 
                /* Got explicit message size from Content-Length: header */
-               parser->payload =
-                       i_stream_create_limit(parser->input,
+               input = i_stream_create_limit(parser->input,
                                              parser->msg.content_length);
+               /* Make sure we return failure if HTTP connection closes before
+                  we've finished reading the full input. */
+               parser->payload = i_stream_create_sized_with_callback(input,
+                                       parser->msg.content_length,
+                                       http_istream_error_callback, input);
+               i_stream_unref(&input);
        } else if (!parser->msg.have_content_length && !request) {
                /* RFC 7230, Section 3.3.3: Message Body Length