diff --git a/ChangeLog b/ChangeLog index 876fbf3e6..0a7181a63 100644 --- a/ChangeLog +++ b/ChangeLog @@ -54,6 +54,7 @@ * added more detailed instrumentation of the disk I/O thread + * support 100 Continue HTTP responses * changed default choker behavior to use 8 unchoke slots (instead of being rate based) * fixed error reporting issue in disk I/O thread * fixed file allocation issues on linux diff --git a/src/http_parser.cpp b/src/http_parser.cpp index 46e2214a0..87f441635 100644 --- a/src/http_parser.cpp +++ b/src/http_parser.cpp @@ -91,6 +91,9 @@ namespace libtorrent } char const* pos = recv_buffer.begin + m_recv_pos; + +restart_response: + if (m_state == read_status) { TORRENT_ASSERT(!m_finished); @@ -160,6 +163,13 @@ namespace libtorrent std::string::size_type separator = line.find(':'); if (separator == std::string::npos) { + if (m_status_code == 100) + { + // for 100 Continue, we need to read another response header + // before reading the body + m_state = read_status; + goto restart_response; + } // this means we got a blank line, // the header is finished and the body // starts. diff --git a/test/test_primitives.cpp b/test/test_primitives.cpp index d689af304..0dd271b18 100644 --- a/test/test_primitives.cpp +++ b/test/test_primitives.cpp @@ -939,6 +939,24 @@ int test_main() TEST_CHECK(parser.content_range() == (std::pair(0, 4))); TEST_CHECK(parser.content_length() == 5); + parser.reset(); + + // make sure we support content-range responses + // and that we're case insensitive + char const* one_hundred_response = + "HTTP/1.1 100 Continue\n" + "\r\n" + "HTTP/1.1 200 OK\n" + "Content-Length: 4\r\n" + "Content-Type: test/plain\r\n" + "\r\n" + "test"; + + received = feed_bytes(parser, one_hundred_response); + + TEST_CHECK(received == make_tuple(4, int(strlen(one_hundred_response) - 4), false)); + TEST_EQUAL(parser.content_length(), 4); + { // test chunked encoding parser char const chunk_header1[] = "f;this is a comment\r\n";