--- /dev/null
+diff --git a/src/protocol/http/http.c b/src/protocol/http/http.c
+index 1264f6f..6de3078 100644
+--- a/src/protocol/http/http.c
++++ b/src/protocol/http/http.c
+@@ -983,29 +983,23 @@ decompress_data(struct connection *conn,
+ int *new_len)
+ {
+ struct http_connection_info *http = conn->info;
+- /* to_read is number of bytes to be read from the decoder. It is 65536
+- * (then we are just emptying the decoder buffer as we finished the walk
+- * through the incoming stream already) or PIPE_BUF / 2 (when we are
+- * still walking through the stream - then we write PIPE_BUF / 2 to the
+- * pipe and read it back to the decoder ASAP; the point is that we can't
+- * write more than PIPE_BUF to the pipe at once, but we also have to
+- * never let read_encoded() (gzread(), in fact) to empty the pipe - that
+- * causes further malfunction of zlib :[ ... so we will make sure that
+- * we will always have at least PIPE_BUF / 2 + 1 in the pipe (returning
+- * early otherwise)). */
+- int to_read = PIPE_BUF / 2, did_read = 0;
++ enum { NORMAL, FINISHING } state = NORMAL;
++ int did_read = 0;
+ int *length_of_block;
+ unsigned char *output = NULL;
+
+- length_of_block = (http->length == LEN_CHUNKED ? &http->chunk_remaining
+- : &http->length);
+-
+ #define BIG_READ 65536
+- if (!*length_of_block) {
+- /* Going to finish this decoding bussiness. */
+- /* Some nicely big value - empty encoded output queue by reading
+- * big chunks from it. */
+- to_read = BIG_READ;
++
++ if (http->length == LEN_CHUNKED) {
++ if (http->chunk_remaining == CHUNK_ZERO_SIZE)
++ state = FINISHING;
++ length_of_block = &http->chunk_remaining;
++ } else {
++ length_of_block = &http->length;
++ if (!*length_of_block) {
++ /* Going to finish this decoding bussiness. */
++ state = FINISHING;
++ }
+ }
+
+ if (conn->content_encoding == ENCODING_NONE) {
+@@ -1024,14 +1018,13 @@ #define BIG_READ 65536
+ }
+
+ do {
+- int init = 0;
++ unsigned char *tmp;
+
+- if (to_read == PIPE_BUF / 2) {
++ if (state == NORMAL) {
+ /* ... we aren't finishing yet. */
+- int written = safe_write(conn->stream_pipes[1], data,
+- len > to_read ? to_read : len);
++ int written = safe_write(conn->stream_pipes[1], data, len);
+
+- if (written > 0) {
++ if (written >= 0) {
+ data += written;
+ len -= written;
+
+@@ -1042,7 +1035,7 @@ #define BIG_READ 65536
+ * non-keep-alive and chunked */
+ if (!http->length) {
+ /* That's all, folks - let's finish this. */
+- to_read = BIG_READ;
++ state = FINISHING;
+ } else if (!len) {
+ /* We've done for this round (but not done
+ * completely). Thus we will get out with
+@@ -1061,28 +1054,26 @@ #define BIG_READ 65536
+ conn->stream = open_encoded(conn->stream_pipes[0],
+ conn->content_encoding);
+ if (!conn->stream) return NULL;
+- /* On "startup" pipe is treated with care, but if everything
+- * was already written to the pipe, caution isn't necessary */
+- else if (to_read != BIG_READ) init = 1;
+- } else init = 0;
++ }
+
+- output = (unsigned char *) mem_realloc(output, *new_len + to_read);
+- if (!output) break;
++ tmp = mem_realloc(output, *new_len + BIG_READ);
++ if (!tmp) break;
++ output = tmp;
++
++ did_read = read_encoded(conn->stream, output + *new_len, BIG_READ);
+
+- did_read = read_encoded(conn->stream, output + *new_len,
+- init ? PIPE_BUF / 32 : to_read); /* on init don't read too much */
+ if (did_read > 0) *new_len += did_read;
+- else if (did_read == -1) {
+- mem_free_set(&output, NULL);
+- *new_len = 0;
+- break; /* Loop prevention (bug 517), is this correct ? --Zas */
++ else {
++ if (did_read < 0) state = FINISHING;
++ break;
+ }
+- } while (len || did_read == BIG_READ);
++ } while (len || (did_read == BIG_READ));
+
+- shutdown_connection_stream(conn);
++ if (state == FINISHING) shutdown_connection_stream(conn);
+ return output;
+ }
+
++
+ static int
+ is_line_in_buffer(struct read_buffer *rb)
+ {
+@@ -1206,11 +1197,8 @@ read_chunked_http_data(struct connection
+ } else {
+ unsigned char *data;
+ int data_len;
+- int len;
+ int zero = (http->chunk_remaining == CHUNK_ZERO_SIZE);
+-
+- if (zero) http->chunk_remaining = 0;
+- len = http->chunk_remaining;
++ int len = zero ? 0 : http->chunk_remaining;
+
+ /* Maybe everything necessary didn't come yet.. */
+ int_upper_bound(&len, rb->length);
+@@ -1850,8 +1838,7 @@ #endif
+ conn->cached->encoding_info = stracpy(get_encoding_name(conn->content_encoding));
+ }
+
+- if (http->length == -1
+- || (PRE_HTTP_1_1(http->recv_version) && http->close))
++ if (http->length == -1 || http->close)
+ socket->state = SOCKET_END_ONCLOSE;
+
+ read_http_data(socket, rb);