added redirection support to http_connection

This commit is contained in:
Arvid Norberg 2007-04-19 20:52:29 +00:00
parent 05714ab5aa
commit 8ef7819a95
2 changed files with 44 additions and 4 deletions

View File

@ -70,6 +70,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)
{ {
assert(!m_handler.empty()); assert(!m_handler.empty());
} }
@ -81,10 +82,11 @@ 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);
void start(std::string const& hostname, std::string const& port void start(std::string const& hostname, std::string const& port
, time_duration timeout); , time_duration timeout, bool handle_redirect = true);
void close(); void close();
private: private:
@ -133,6 +135,10 @@ private:
// the timer fires every 250 millisecond as long // the timer fires every 250 millisecond as long
// 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
// HTTP redirects.
bool m_redirect;
}; };
} }

View File

@ -42,8 +42,10 @@ using boost::bind;
namespace libtorrent namespace libtorrent
{ {
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)
{ {
m_redirect = handle_redirect;
std::string protocol; std::string protocol;
std::string hostname; std::string hostname;
std::string path; std::string path;
@ -54,13 +56,15 @@ void http_connection::get(std::string const& url, time_duration timeout)
"Host:" << hostname << "Host:" << hostname <<
"Connection: close\r\n" "Connection: close\r\n"
"\r\n\r\n"; "\r\n\r\n";
m_path = path;
sendbuffer = headers.str(); sendbuffer = headers.str();
start(hostname, boost::lexical_cast<std::string>(port), timeout); start(hostname, boost::lexical_cast<std::string>(port), timeout);
} }
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) , time_duration timeout, bool handle_redirect = true)
{ {
m_redirect = handle_redirect;
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
@ -213,6 +217,36 @@ void http_connection::on_read(asio::error_code const& e
m_read_pos += bytes_transferred; m_read_pos += bytes_transferred;
assert(m_read_pos <= int(m_recvbuffer.size())); 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 url = m_parser.header<std::string>("location");
if (url.empty())
{
// missing location header
if (m_bottled && m_called) return;
m_called = true;
m_handler(e, m_parser, 0, 0);
return;
}
m_limiter_timer_active = false;
m_timer.cancel();
m_limiter_timer.cancel();
m_sock.close();
m_hostname.clear();
m_port.clear();
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]