forked from premiere/premiere-libtorrent
http_connection fixes and unit test (not self contained yet, just like test_web_seed)
This commit is contained in:
parent
d34bb2b8ca
commit
a1a841a04d
|
@ -115,6 +115,8 @@ private:
|
|||
, asio::error_code const& e);
|
||||
void on_assign_bandwidth(asio::error_code const& e);
|
||||
|
||||
void callback(asio::error_code const& e, char const* data = 0, int size = 0);
|
||||
|
||||
std::vector<char> m_recvbuffer;
|
||||
tcp::socket m_sock;
|
||||
int m_read_pos;
|
||||
|
|
|
@ -91,6 +91,9 @@ namespace libtorrent
|
|||
int content_length() const { return m_content_length; }
|
||||
|
||||
void reset();
|
||||
|
||||
std::map<std::string, std::string> const& headers() const { return m_header; }
|
||||
|
||||
private:
|
||||
int m_recv_pos;
|
||||
int m_status_code;
|
||||
|
|
|
@ -96,9 +96,7 @@ void http_connection::on_connect_timeout()
|
|||
if (m_connection_ticket > -1) m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(asio::error::timed_out, m_parser, 0, 0);
|
||||
callback(asio::error::timed_out);
|
||||
close();
|
||||
}
|
||||
|
||||
|
@ -112,12 +110,10 @@ void http_connection::on_timeout(boost::weak_ptr<http_connection> p
|
|||
|
||||
if (e == asio::error::operation_aborted) return;
|
||||
|
||||
if (c->m_bottled && c->m_called) return;
|
||||
|
||||
if (c->m_last_receive + c->m_timeout < time_now())
|
||||
{
|
||||
c->m_called = true;
|
||||
c->m_handler(asio::error::timed_out, c->m_parser, 0, 0);
|
||||
c->callback(asio::error::timed_out);
|
||||
c->close();
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -138,9 +134,7 @@ void http_connection::close()
|
|||
if (m_connection_ticket > -1) m_cc.done(m_connection_ticket);
|
||||
m_connection_ticket = -1;
|
||||
|
||||
if (m_called) return;
|
||||
m_called = true;
|
||||
m_handler(asio::error::operation_aborted, m_parser, 0, 0);
|
||||
m_handler.clear();
|
||||
}
|
||||
|
||||
void http_connection::on_resolve(asio::error_code const& e
|
||||
|
@ -148,10 +142,8 @@ void http_connection::on_resolve(asio::error_code const& e
|
|||
{
|
||||
if (e)
|
||||
{
|
||||
callback(e);
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(e, m_parser, 0, 0);
|
||||
return;
|
||||
}
|
||||
TORRENT_ASSERT(i != tcp::resolver::iterator());
|
||||
|
@ -187,10 +179,17 @@ void http_connection::on_connect(asio::error_code const& e
|
|||
}
|
||||
*/ else
|
||||
{
|
||||
callback(e);
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
}
|
||||
}
|
||||
|
||||
void http_connection::callback(asio::error_code const& e, char const* data, int size)
|
||||
{
|
||||
if (!m_bottled || !m_called)
|
||||
{
|
||||
m_called = true;
|
||||
m_handler(e, m_parser, 0, 0);
|
||||
if (m_handler) m_handler(e, m_parser, data, size);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -198,10 +197,8 @@ void http_connection::on_write(asio::error_code const& e)
|
|||
{
|
||||
if (e)
|
||||
{
|
||||
callback(e);
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(e, m_parser, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -236,9 +233,6 @@ void http_connection::on_read(asio::error_code const& e
|
|||
|
||||
if (e == asio::error::eof)
|
||||
{
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
char const* data = 0;
|
||||
std::size_t size = 0;
|
||||
if (m_bottled && m_parser.header_finished())
|
||||
|
@ -246,16 +240,15 @@ void http_connection::on_read(asio::error_code const& e
|
|||
data = m_parser.get_body().begin;
|
||||
size = m_parser.get_body().left();
|
||||
}
|
||||
m_handler(e, m_parser, data, size);
|
||||
callback(e, data, size);
|
||||
close();
|
||||
return;
|
||||
}
|
||||
|
||||
if (e)
|
||||
{
|
||||
callback(e);
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(e, m_parser, 0, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -273,9 +266,7 @@ void http_connection::on_read(asio::error_code const& e
|
|||
if (url.empty())
|
||||
{
|
||||
// missing location header
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(e, m_parser, 0, 0);
|
||||
callback(e);
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -297,7 +288,7 @@ void http_connection::on_read(asio::error_code const& e
|
|||
if (!m_bottled && m_parser.header_finished())
|
||||
{
|
||||
if (m_read_pos > m_parser.body_start())
|
||||
m_handler(e, m_parser, &m_recvbuffer[0] + m_parser.body_start()
|
||||
callback(e, &m_recvbuffer[0] + m_parser.body_start()
|
||||
, m_read_pos - m_parser.body_start());
|
||||
m_read_pos = 0;
|
||||
m_last_receive = time_now();
|
||||
|
@ -305,15 +296,13 @@ void http_connection::on_read(asio::error_code const& e
|
|||
else if (m_bottled && m_parser.finished())
|
||||
{
|
||||
m_timer.cancel();
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(e, m_parser, m_parser.get_body().begin, m_parser.get_body().left());
|
||||
callback(e, m_parser.get_body().begin, m_parser.get_body().left());
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
TORRENT_ASSERT(!m_bottled);
|
||||
m_handler(e, m_parser, &m_recvbuffer[0], m_read_pos);
|
||||
callback(e, &m_recvbuffer[0], m_read_pos);
|
||||
m_read_pos = 0;
|
||||
m_last_receive = time_now();
|
||||
}
|
||||
|
@ -322,10 +311,8 @@ void http_connection::on_read(asio::error_code const& e
|
|||
m_recvbuffer.resize((std::min)(m_read_pos + 2048, int(max_bottled_buffer)));
|
||||
if (m_read_pos == max_bottled_buffer)
|
||||
{
|
||||
callback(asio::error::eof);
|
||||
close();
|
||||
if (m_bottled && m_called) return;
|
||||
m_called = true;
|
||||
m_handler(asio::error::eof, m_parser, 0, 0);
|
||||
return;
|
||||
}
|
||||
int amount_to_read = m_recvbuffer.size() - m_read_pos;
|
||||
|
@ -351,8 +338,7 @@ void http_connection::on_assign_bandwidth(asio::error_code const& e)
|
|||
&& m_limiter_timer_active)
|
||||
|| !m_sock.is_open())
|
||||
{
|
||||
if (!m_bottled || !m_called)
|
||||
m_handler(e, m_parser, 0, 0);
|
||||
callback(asio::error::eof);
|
||||
return;
|
||||
}
|
||||
m_limiter_timer_active = false;
|
||||
|
|
|
@ -23,6 +23,7 @@ project
|
|||
|
||||
|
||||
test-suite libtorrent :
|
||||
[ run test_http_connection.cpp ]
|
||||
[ run test_buffer.cpp ]
|
||||
[ run test_storage.cpp ]
|
||||
[ run test_piece_picker.cpp ]
|
||||
|
|
|
@ -0,0 +1,87 @@
|
|||
#include "test.hpp"
|
||||
#include "libtorrent/socket.hpp"
|
||||
#include "libtorrent/connection_queue.hpp"
|
||||
#include "libtorrent/http_connection.hpp"
|
||||
|
||||
using namespace libtorrent;
|
||||
|
||||
io_service ios;
|
||||
connection_queue cq(ios);
|
||||
|
||||
int connect_handler_called = 0;
|
||||
int handler_called = 0;
|
||||
int data_size = 0;
|
||||
int http_status = 0;
|
||||
asio::error_code error_code;
|
||||
|
||||
void print_http_header(http_parser const& p)
|
||||
{
|
||||
std::cerr << p.status_code() << " " << p.message() << std::endl;
|
||||
|
||||
for (std::map<std::string, std::string>::const_iterator i
|
||||
= p.headers().begin(), end(p.headers().end()); i != end; ++i)
|
||||
{
|
||||
std::cerr << i->first << ": " << i->second << std::endl;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
void http_connect_handler(http_connection& c)
|
||||
{
|
||||
++connect_handler_called;
|
||||
TEST_CHECK(c.socket().is_open());
|
||||
TEST_CHECK(c.socket().remote_endpoint().address() == address::from_string("127.0.0.1"));
|
||||
}
|
||||
|
||||
void http_handler(asio::error_code const& ec, http_parser const& parser, char const* data, int size)
|
||||
{
|
||||
++handler_called;
|
||||
data_size = size;
|
||||
error_code = ec;
|
||||
|
||||
if (parser.header_finished()) http_status = parser.status_code();
|
||||
print_http_header(parser);
|
||||
|
||||
cq.close();
|
||||
}
|
||||
|
||||
void reset_globals()
|
||||
{
|
||||
connect_handler_called = 0;
|
||||
handler_called = 0;
|
||||
data_size = 0;
|
||||
http_status = 0;
|
||||
error_code = asio::error_code();
|
||||
}
|
||||
|
||||
void run_test(char const* url, int size, int status, asio::error_code const& ec)
|
||||
{
|
||||
reset_globals();
|
||||
|
||||
std::cerr << " ===== TESTING: " << url << " =====" << std::endl;
|
||||
|
||||
boost::shared_ptr<http_connection> h(new http_connection(ios, cq
|
||||
, &::http_handler, true, &::http_connect_handler));
|
||||
h->get(url);
|
||||
ios.reset();
|
||||
ios.run();
|
||||
|
||||
std::cerr << "connect_handler_called: " << connect_handler_called << std::endl;
|
||||
std::cerr << "handler_called: " << handler_called << std::endl;
|
||||
std::cerr << "status: " << http_status << std::endl;
|
||||
std::cerr << "size: " << data_size << std::endl;
|
||||
std::cerr << "error_code: " << error_code.message() << std::endl;
|
||||
TEST_CHECK(connect_handler_called == 1);
|
||||
TEST_CHECK(handler_called == 1);
|
||||
TEST_CHECK(data_size == size || size == -1);
|
||||
TEST_CHECK(error_code == ec);
|
||||
TEST_CHECK(http_status == status);
|
||||
}
|
||||
|
||||
int test_main()
|
||||
{
|
||||
run_test("http://127.0.0.1/disk_io.png", 17809, 200, asio::error_code());
|
||||
run_test("http://127.0.0.1/non-existing-file", -1, 404, asio::error::eof);
|
||||
return 0;
|
||||
}
|
||||
|
Loading…
Reference in New Issue