forked from premiere/premiere-libtorrent
added support for http redirection
This commit is contained in:
parent
bd296f3657
commit
7f21b35a33
|
@ -66,7 +66,8 @@ namespace libtorrent
|
|||
public:
|
||||
|
||||
http_tracker_connection(
|
||||
tracker_request const& req
|
||||
tracker_manager& man
|
||||
, tracker_request const& req
|
||||
, std::string const& hostname
|
||||
, unsigned short port
|
||||
, std::string const& request
|
||||
|
@ -79,13 +80,19 @@ namespace libtorrent
|
|||
|
||||
private:
|
||||
|
||||
void init_send_buffer(
|
||||
std::string const& hostname
|
||||
, std::string const& request);
|
||||
|
||||
void parse(const entry& e);
|
||||
peer_entry extract_peer_info(const entry& e);
|
||||
|
||||
tracker_manager& m_man;
|
||||
enum { read_status, read_header, read_body } m_state;
|
||||
|
||||
enum { plain, gzip } m_content_encoding;
|
||||
int m_content_length;
|
||||
std::string m_location;
|
||||
|
||||
boost::shared_ptr<socket> m_socket;
|
||||
int m_recv_pos;
|
||||
|
@ -99,6 +106,9 @@ namespace libtorrent
|
|||
std::string m_server_protocol;
|
||||
|
||||
const http_settings& m_settings;
|
||||
tracker_request m_req;
|
||||
std::string m_password;
|
||||
int m_code;
|
||||
};
|
||||
|
||||
}
|
||||
|
|
|
@ -151,7 +151,9 @@ namespace libtorrent
|
|||
|
||||
private:
|
||||
|
||||
std::vector<boost::shared_ptr<tracker_connection> > m_connections;
|
||||
typedef std::list<boost::shared_ptr<tracker_connection> >
|
||||
tracker_connections_t;
|
||||
tracker_connections_t m_connections;
|
||||
const http_settings& m_settings;
|
||||
};
|
||||
|
||||
|
|
|
@ -95,7 +95,9 @@ namespace libtorrent
|
|||
assert(len >= 0);
|
||||
// http://www.ietf.org/rfc/rfc2396.txt
|
||||
// section 2.3
|
||||
static const char unreserved_chars[] = "-_.!~*'()";
|
||||
// some trackers seems to require that ' is escaped
|
||||
// static const char unreserved_chars[] = "-_.!~*'()";
|
||||
static const char unreserved_chars[] = "-_.!~*()";
|
||||
|
||||
std::stringstream ret;
|
||||
ret << std::hex << std::setfill('0');
|
||||
|
@ -109,6 +111,10 @@ namespace libtorrent
|
|||
{
|
||||
ret << *str;
|
||||
}
|
||||
else if (*str == ' ')
|
||||
{
|
||||
ret << '+';
|
||||
}
|
||||
else
|
||||
{
|
||||
ret << '%'
|
||||
|
|
|
@ -75,9 +75,9 @@ namespace
|
|||
namespace libtorrent
|
||||
{
|
||||
|
||||
|
||||
http_tracker_connection::http_tracker_connection(
|
||||
tracker_request const& req
|
||||
tracker_manager& man
|
||||
, tracker_request const& req
|
||||
, std::string const& hostname
|
||||
, unsigned short port
|
||||
, std::string const& request
|
||||
|
@ -85,12 +85,16 @@ namespace libtorrent
|
|||
, const http_settings& stn
|
||||
, std::string const& password)
|
||||
: tracker_connection(c)
|
||||
, m_man(man)
|
||||
, m_state(read_status)
|
||||
, m_content_encoding(plain)
|
||||
, m_content_length(0)
|
||||
, m_recv_pos(0)
|
||||
, m_request_time(boost::posix_time::second_clock::local_time())
|
||||
, m_settings(stn)
|
||||
, m_req(req)
|
||||
, m_password(password)
|
||||
, m_code(0)
|
||||
{
|
||||
const std::string* connect_to_host;
|
||||
bool using_proxy = false;
|
||||
|
@ -320,15 +324,19 @@ namespace libtorrent
|
|||
if (requester()) requester()->tracker_request_error(-1, error_msg.c_str());
|
||||
return true;
|
||||
}
|
||||
int code;
|
||||
line >> code;
|
||||
line >> m_code;
|
||||
std::getline(line, m_server_message);
|
||||
m_state = read_header;
|
||||
|
||||
if (code != 200)
|
||||
if (m_code != 200
|
||||
&& m_code != 301
|
||||
&& m_code != 302
|
||||
&& m_code != 303
|
||||
&& m_code != 307)
|
||||
{
|
||||
std::string error_msg = boost::lexical_cast<std::string>(code) + " " + m_server_message;
|
||||
if (requester()) requester()->tracker_request_error(code, error_msg.c_str());
|
||||
std::string error_msg = boost::lexical_cast<std::string>(m_code)
|
||||
+ " " + m_server_message;
|
||||
if (requester()) requester()->tracker_request_error(m_code, error_msg.c_str());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
@ -381,7 +389,7 @@ namespace libtorrent
|
|||
return true;
|
||||
}
|
||||
|
||||
if (m_content_length < minimum_tracker_response_length)
|
||||
if (m_content_length < minimum_tracker_response_length && m_code == 200)
|
||||
{
|
||||
if (requester())
|
||||
{
|
||||
|
@ -404,18 +412,44 @@ namespace libtorrent
|
|||
error_str += line.substr(18, line.length() - 18 - 2);
|
||||
error_str += "\"";
|
||||
if (requester())
|
||||
{
|
||||
requester()->tracker_request_error(-1, error_str.c_str());
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
else if (line.substr(0, 10) == "Location: ")
|
||||
{
|
||||
m_location.assign(line.begin() + 10, line.end());
|
||||
}
|
||||
else if (line.size() < 3)
|
||||
{
|
||||
m_state = read_body;
|
||||
#ifndef NDEBUG
|
||||
if (requester()) requester()->debug_log("end of http header");
|
||||
#endif
|
||||
if (m_code >= 300 && m_code < 400)
|
||||
{
|
||||
if (m_location.empty())
|
||||
{
|
||||
std::string error_str = "got redirection response (";
|
||||
error_str += boost::lexical_cast<std::string>(m_code);
|
||||
error_str += ") without 'Location' header";
|
||||
if (requester())
|
||||
requester()->tracker_request_error(m_code, error_str.c_str());
|
||||
return true;
|
||||
}
|
||||
|
||||
#ifndef NDEBUG
|
||||
if (requester()) requester()->debug_log("Redirecting to \"" + m_location + "\"");
|
||||
#endif
|
||||
std::string::size_type i = m_location.find('?');
|
||||
if (i == std::string::npos)
|
||||
m_req.url = m_location;
|
||||
else
|
||||
m_req.url.assign(m_location.begin(), m_location.begin() + i);
|
||||
|
||||
m_man.queue_request(m_req, requester(), m_password);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
++newline;
|
||||
|
|
|
@ -283,7 +283,7 @@ namespace libtorrent
|
|||
|
||||
void tracker_manager::tick()
|
||||
{
|
||||
std::vector<boost::shared_ptr<tracker_connection> >::iterator i;
|
||||
tracker_connections_t::iterator i;
|
||||
for (i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||
{
|
||||
boost::shared_ptr<tracker_connection>& c = *i;
|
||||
|
@ -297,8 +297,7 @@ namespace libtorrent
|
|||
c->requester()->tracker_request_error(-1, e.what());
|
||||
}
|
||||
if (c->requester()) c->requester()->m_manager = 0;
|
||||
m_connections.erase(i);
|
||||
--i; // compensate for the remove
|
||||
i = m_connections.erase(i);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -347,7 +346,7 @@ namespace libtorrent
|
|||
}
|
||||
catch(boost::bad_lexical_cast&)
|
||||
{
|
||||
throw std::runtime_error("invalid url");
|
||||
throw std::runtime_error("invalid url: \"" + req.url + "\"");
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -363,7 +362,8 @@ namespace libtorrent
|
|||
if (protocol == "http")
|
||||
{
|
||||
con.reset(new http_tracker_connection(
|
||||
req
|
||||
*this
|
||||
, req
|
||||
, hostname
|
||||
, port
|
||||
, request_string
|
||||
|
@ -398,7 +398,7 @@ namespace libtorrent
|
|||
void tracker_manager::abort_request(request_callback* c)
|
||||
{
|
||||
assert(c != 0);
|
||||
std::vector<boost::shared_ptr<tracker_connection> >::iterator i;
|
||||
tracker_connections_t::iterator i;
|
||||
for (i = m_connections.begin(); i != m_connections.end(); ++i)
|
||||
{
|
||||
if ((*i)->requester() == c)
|
||||
|
@ -415,9 +415,9 @@ namespace libtorrent
|
|||
// except those with a requester == 0 (since those are
|
||||
// 'event=stopped'-requests)
|
||||
|
||||
std::vector<boost::shared_ptr<tracker_connection> > keep_connections;
|
||||
tracker_connections_t keep_connections;
|
||||
|
||||
for (std::vector<boost::shared_ptr<tracker_connection> >::const_iterator i =
|
||||
for (tracker_connections_t::const_iterator i =
|
||||
m_connections.begin();
|
||||
i != m_connections.end();
|
||||
++i)
|
||||
|
@ -430,10 +430,8 @@ namespace libtorrent
|
|||
|
||||
bool tracker_manager::send_finished() const
|
||||
{
|
||||
for (std::vector<boost::shared_ptr<tracker_connection> >::const_iterator i =
|
||||
m_connections.begin();
|
||||
i != m_connections.end();
|
||||
++i)
|
||||
for (tracker_connections_t::const_iterator i =
|
||||
m_connections.begin(); i != m_connections.end(); ++i)
|
||||
{
|
||||
if (!(*i)->send_finished()) return false;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue