fixed bug in web_connection_base when receiving chunked encoding and made sure the unit tests pass

This commit is contained in:
Arvid Norberg 2011-03-24 16:46:26 +00:00
parent 929c31a757
commit 7e07f7469f
7 changed files with 15 additions and 8 deletions

View File

@ -65,7 +65,8 @@ namespace libtorrent
class TORRENT_EXPORT http_parser class TORRENT_EXPORT http_parser
{ {
public: public:
http_parser(); enum flags_t { dont_parse_chunks = 1 };
http_parser(int flags = 0);
std::string const& header(char const* key) const std::string const& header(char const* key) const
{ {
static std::string empty; static std::string empty;
@ -152,6 +153,9 @@ namespace libtorrent
int m_chunk_header_size; int m_chunk_header_size;
int m_partial_chunk_header; int m_partial_chunk_header;
// controls some behaviors of the parser
int m_flags;
}; };
} }

View File

@ -60,7 +60,7 @@ namespace libtorrent
&& http_status < 400; && http_status < 400;
} }
http_parser::http_parser() http_parser::http_parser(int flags)
: m_recv_pos(0) : m_recv_pos(0)
, m_status_code(-1) , m_status_code(-1)
, m_content_length(-1) , m_content_length(-1)
@ -74,6 +74,7 @@ namespace libtorrent
, m_cur_chunk_end(-1) , m_cur_chunk_end(-1)
, m_chunk_header_size(0) , m_chunk_header_size(0)
, m_partial_chunk_header(0) , m_partial_chunk_header(0)
, m_flags(flags)
{} {}
boost::tuple<int, int> http_parser::incoming( boost::tuple<int, int> http_parser::incoming(
@ -245,7 +246,7 @@ restart_response:
{ {
int incoming = recv_buffer.end - pos; int incoming = recv_buffer.end - pos;
if (m_chunked_encoding) if (m_chunked_encoding && (m_flags & dont_parse_chunks) == 0)
{ {
if (m_cur_chunk_end == -1) if (m_cur_chunk_end == -1)
m_cur_chunk_end = m_body_start_pos; m_cur_chunk_end = m_body_start_pos;

View File

@ -376,6 +376,7 @@ namespace libtorrent
#endif #endif
TORRENT_ASSERT(bytes_transferred >= size_t(header_size - m_partial_chunk_header)); TORRENT_ASSERT(bytes_transferred >= size_t(header_size - m_partial_chunk_header));
bytes_transferred -= header_size - m_partial_chunk_header; bytes_transferred -= header_size - m_partial_chunk_header;
m_statistics.received_bytes(0, header_size - m_partial_chunk_header); m_statistics.received_bytes(0, header_size - m_partial_chunk_header);
m_partial_chunk_header = 0; m_partial_chunk_header = 0;
TORRENT_ASSERT(chunk_size != 0 || chunk_start.left() <= header_size || chunk_start.begin[header_size] == 'H'); TORRENT_ASSERT(chunk_size != 0 || chunk_start.left() <= header_size || chunk_start.begin[header_size] == 'H');

View File

@ -2280,7 +2280,7 @@ namespace libtorrent
peer_log("*** The block we just got was not in the request queue ***"); peer_log("*** The block we just got was not in the request queue ***");
#endif #endif
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
TORRENT_ASSERT(m_received_in_piece == p.length); TORRENT_ASSERT_VAL(m_received_in_piece == p.length, m_received_in_piece);
m_received_in_piece = 0; m_received_in_piece = 0;
#endif #endif
t->add_redundant_bytes(p.length); t->add_redundant_bytes(p.length);
@ -2341,7 +2341,7 @@ namespace libtorrent
TORRENT_ASSERT(*b == pending_b); TORRENT_ASSERT(*b == pending_b);
#ifdef TORRENT_DEBUG #ifdef TORRENT_DEBUG
TORRENT_ASSERT(m_received_in_piece == p.length); TORRENT_ASSERT_VAL(m_received_in_piece == p.length, m_received_in_piece);
m_received_in_piece = 0; m_received_in_piece = 0;
#endif #endif
// if the block we got is already finished, then ignore it // if the block we got is already finished, then ignore it

View File

@ -65,6 +65,7 @@ namespace libtorrent
, std::string const& auth , std::string const& auth
, web_seed_entry::headers_t const& extra_headers) , web_seed_entry::headers_t const& extra_headers)
: peer_connection(ses, t, s, remote, peerinfo) : peer_connection(ses, t, s, remote, peerinfo)
, m_parser(http_parser::dont_parse_chunks)
, m_external_auth(auth) , m_external_auth(auth)
, m_extra_headers(extra_headers) , m_extra_headers(extra_headers)
, m_first_request(true) , m_first_request(true)

View File

@ -108,7 +108,7 @@ void test_pex()
torrent_status st1; torrent_status st1;
torrent_status st2; torrent_status st2;
torrent_status st3; torrent_status st3;
for (int i = 0; i < 10; ++i) for (int i = 0; i < 15; ++i)
{ {
print_alerts(ses1, "ses1"); print_alerts(ses1, "ses1");
print_alerts(ses2, "ses2"); print_alerts(ses2, "ses2");

View File

@ -125,11 +125,11 @@ void test_transfer()
if (st2.is_finished) break; if (st2.is_finished) break;
test_sleep(500);
TEST_CHECK(st1.state == torrent_status::seeding TEST_CHECK(st1.state == torrent_status::seeding
|| st1.state == torrent_status::checking_files); || st1.state == torrent_status::checking_files);
TEST_CHECK(st2.state == torrent_status::downloading); TEST_CHECK(st2.state == torrent_status::downloading);
test_sleep(500);
} }
TEST_CHECK(tor1.status().is_finished); TEST_CHECK(tor1.status().is_finished);