diff options
| author | Dan Winship <danw@gnome.org> | 2010-07-31 10:32:51 +0200 |
|---|---|---|
| committer | Dan Winship <danw@gnome.org> | 2010-07-31 15:30:04 +0200 |
| commit | 74e253068cfa2a9d13c8d06f96ea42ad0069a657 (patch) | |
| tree | 5d7f46cefc0b41209af8a58db2f22f6bd1bb0342 /libsoup/soup-message-io.c | |
| parent | dff6d6d79d6aa2c53ab1d2f9bc1fc7a38c0df3bf (diff) | |
| download | libsoup-74e253068cfa2a9d13c8d06f96ea42ad0069a657.tar.gz | |
soup-message-io: fix wrong-Content-Length logic
Previously we just ignored Content-Length if the server specified
"Connection: close", which does the right thing if the specified
Content-Length is too large, but fails if the Content-Length is
correct but the server "forgets" to close the connection. Fix this so
that we always stop reading once we get to the expected
Content-Length, but we also cope with the connection closing before
that point.
https://bugzilla.gnome.org/show_bug.cgi?id=611481
Diffstat (limited to 'libsoup/soup-message-io.c')
| -rw-r--r-- | libsoup/soup-message-io.c | 21 |
1 files changed, 18 insertions, 3 deletions
diff --git a/libsoup/soup-message-io.c b/libsoup/soup-message-io.c index ff1fec26..f4f4c965 100644 --- a/libsoup/soup-message-io.c +++ b/libsoup/soup-message-io.c @@ -54,6 +54,7 @@ typedef struct { GByteArray *read_meta_buf; SoupMessageBody *read_body; goffset read_length; + gboolean read_eof_ok; gboolean need_content_sniffed, need_got_chunk; SoupMessageBody *sniff_data; @@ -212,8 +213,7 @@ io_disconnected (SoupSocket *sock, SoupMessage *msg) SoupMessageIOData *io = priv->io_data; /* Closing the connection to signify EOF is sometimes ok */ - if (io->read_state == SOUP_MESSAGE_IO_STATE_BODY && - io->read_encoding == SOUP_ENCODING_EOF) { + if (io->read_state == SOUP_MESSAGE_IO_STATE_BODY && io->read_eof_ok) { io->read_state = SOUP_MESSAGE_IO_STATE_FINISHING; io_read (sock, msg); return; @@ -462,8 +462,10 @@ read_body_chunk (SoupMessage *msg) break; case SOUP_SOCKET_EOF: - if (read_to_eof) + if (io->read_eof_ok) { + io->read_length = 0; return TRUE; + } /* else fall through */ case SOUP_SOCKET_ERROR: @@ -842,11 +844,24 @@ io_read (SoupSocket *sock, SoupMessage *msg) break; } + if (io->read_encoding == SOUP_ENCODING_EOF) + io->read_eof_ok = TRUE; + if (io->read_encoding == SOUP_ENCODING_CONTENT_LENGTH) { SoupMessageHeaders *hdrs = (io->mode == SOUP_MESSAGE_IO_CLIENT) ? msg->response_headers : msg->request_headers; io->read_length = soup_message_headers_get_content_length (hdrs); + + if (io->mode == SOUP_MESSAGE_IO_CLIENT && + !soup_message_is_keepalive (msg)) { + /* Some servers suck and send + * incorrect Content-Length values, so + * allow EOF termination in this case + * (iff the message is too short) too. + */ + io->read_eof_ok = TRUE; + } } if (io->mode == SOUP_MESSAGE_IO_CLIENT && |
