lt sync 1938

This commit is contained in:
Marcos Pinto 2008-01-13 06:24:52 +00:00
parent dc60e26c59
commit 2e0be83732
3 changed files with 41 additions and 38 deletions

View File

@ -78,7 +78,7 @@ struct http_connection : boost::enable_shared_from_this<http_connection>, boost:
, m_download_quota(0) , m_download_quota(0)
, m_limiter_timer_active(false) , m_limiter_timer_active(false)
, m_limiter_timer(ios) , m_limiter_timer(ios)
, m_redirect(true) , m_redirects(5)
, m_connection_ticket(-1) , m_connection_ticket(-1)
, m_cc(cc) , m_cc(cc)
{ {
@ -93,10 +93,10 @@ struct http_connection : boost::enable_shared_from_this<http_connection>, boost:
std::string sendbuffer; std::string sendbuffer;
void get(std::string const& url, time_duration timeout = seconds(30) void get(std::string const& url, time_duration timeout = seconds(30)
, bool handle_redirect = true); , int handle_redirects = 5);
void start(std::string const& hostname, std::string const& port void start(std::string const& hostname, std::string const& port
, time_duration timeout, bool handle_redirect = true); , time_duration timeout, int handle_redirect = 5);
void close(); void close();
tcp::socket const& socket() const { return m_sock; } tcp::socket const& socket() const { return m_sock; }
@ -153,9 +153,8 @@ private:
// as all the quota was used. // as all the quota was used.
deadline_timer m_limiter_timer; deadline_timer m_limiter_timer;
// if set to true, the connection should handle // the number of redirects to follow (in sequence)
// HTTP redirects. int m_redirects;
bool m_redirect;
int m_connection_ticket; int m_connection_ticket;
connection_queue& m_cc; connection_queue& m_cc;

View File

@ -66,7 +66,7 @@ namespace libtorrent
} }
} }
#ifndef NDEBUG #if !defined NDEBUG && !defined TORRENT_DISABLE_INVARIANT_CHECKS
#define INVARIANT_CHECK \ #define INVARIANT_CHECK \
invariant_checker const& _invariant_check = make_invariant_checker(*this); \ invariant_checker const& _invariant_check = make_invariant_checker(*this); \
(void)_invariant_check; \ (void)_invariant_check; \

View File

@ -45,9 +45,8 @@ namespace libtorrent
enum { max_bottled_buffer = 1024 * 1024 }; enum { max_bottled_buffer = 1024 * 1024 };
void http_connection::get(std::string const& url, time_duration timeout void http_connection::get(std::string const& url, time_duration timeout
, bool handle_redirect) , int handle_redirects)
{ {
m_redirect = handle_redirect;
std::string protocol; std::string protocol;
std::string auth; std::string auth;
std::string hostname; std::string hostname;
@ -62,21 +61,23 @@ void http_connection::get(std::string const& url, time_duration timeout
headers << "Authorization: Basic " << base64encode(auth) << "\r\n"; headers << "Authorization: Basic " << base64encode(auth) << "\r\n";
headers << "\r\n"; headers << "\r\n";
sendbuffer = headers.str(); sendbuffer = headers.str();
start(hostname, boost::lexical_cast<std::string>(port), timeout); start(hostname, boost::lexical_cast<std::string>(port), timeout, handle_redirects);
} }
void http_connection::start(std::string const& hostname, std::string const& port void http_connection::start(std::string const& hostname, std::string const& port
, time_duration timeout, bool handle_redirect) , time_duration timeout, int handle_redirects)
{ {
m_redirect = handle_redirect; m_redirects = handle_redirects;
m_timeout = timeout; m_timeout = timeout;
m_timer.expires_from_now(m_timeout); m_timer.expires_from_now(m_timeout);
m_timer.async_wait(bind(&http_connection::on_timeout m_timer.async_wait(bind(&http_connection::on_timeout
, boost::weak_ptr<http_connection>(shared_from_this()), _1)); , boost::weak_ptr<http_connection>(shared_from_this()), _1));
m_called = false; m_called = false;
m_parser.reset();
m_recvbuffer.clear();
m_read_pos = 0;
if (m_sock.is_open() && m_hostname == hostname && m_port == port) if (m_sock.is_open() && m_hostname == hostname && m_port == port)
{ {
m_parser.reset();
asio::async_write(m_sock, asio::buffer(sendbuffer) asio::async_write(m_sock, asio::buffer(sendbuffer)
, bind(&http_connection::on_write, shared_from_this(), _1)); , bind(&http_connection::on_write, shared_from_this(), _1));
} }
@ -233,6 +234,7 @@ void http_connection::on_read(asio::error_code const& e
if (e == asio::error::eof) if (e == asio::error::eof)
{ {
TORRENT_ASSERT(bytes_transferred == 0);
char const* data = 0; char const* data = 0;
std::size_t size = 0; std::size_t size = 0;
if (m_bottled && m_parser.header_finished()) if (m_bottled && m_parser.header_finished())
@ -247,6 +249,7 @@ void http_connection::on_read(asio::error_code const& e
if (e) if (e)
{ {
TORRENT_ASSERT(bytes_transferred == 0);
callback(e); callback(e);
close(); close();
return; return;
@ -255,31 +258,6 @@ void http_connection::on_read(asio::error_code const& e
m_read_pos += bytes_transferred; m_read_pos += bytes_transferred;
TORRENT_ASSERT(m_read_pos <= int(m_recvbuffer.size())); TORRENT_ASSERT(m_read_pos <= int(m_recvbuffer.size()));
// having a nonempty path means we should handle redirects
if (m_redirect && m_parser.header_finished())
{
int code = m_parser.status_code();
if (code >= 300 && code < 400)
{
// attempt a redirect
std::string const& url = m_parser.header("location");
if (url.empty())
{
// missing location header
callback(e);
return;
}
m_limiter_timer_active = false;
close();
get(url, m_timeout);
return;
}
m_redirect = false;
}
if (m_bottled || !m_parser.header_finished()) if (m_bottled || !m_parser.header_finished())
{ {
libtorrent::buffer::const_interval rcv_buf(&m_recvbuffer[0] libtorrent::buffer::const_interval rcv_buf(&m_recvbuffer[0]
@ -295,6 +273,32 @@ void http_connection::on_read(asio::error_code const& e
m_handler.clear(); m_handler.clear();
return; return;
} }
// having a nonempty path means we should handle redirects
if (m_redirects && m_parser.header_finished())
{
int code = m_parser.status_code();
if (code >= 300 && code < 400)
{
// attempt a redirect
std::string const& url = m_parser.header("location");
if (url.empty())
{
// missing location header
callback(e);
return;
}
asio::error_code ec;
m_sock.close(ec);
get(url, m_timeout, m_redirects - 1);
return;
}
m_redirects = 0;
}
if (!m_bottled && m_parser.header_finished()) if (!m_bottled && m_parser.header_finished())
{ {
if (m_read_pos > m_parser.body_start()) if (m_read_pos > m_parser.body_start())