preliminary http proxy support for web seeds, bumped version number
This commit is contained in:
parent
00df2b5bc3
commit
eef4ffa18c
|
@ -1,6 +1,11 @@
|
||||||
|
|
||||||
* Added more clients to the identifiable list
|
* session::listen_on() won't reopen the socket in case the port and
|
||||||
* Fixed fingerprint parser to cope with latest Mainline versions
|
interface is the same as is already open.
|
||||||
|
* Added http proxy support for web seeds.
|
||||||
|
* Fixed problem where upload and download stats could become incorrect
|
||||||
|
in case of high cpu load.
|
||||||
|
* Added more clients to the identifiable list.
|
||||||
|
* Fixed fingerprint parser to cope with latest Mainline versions.
|
||||||
|
|
||||||
release 0.10
|
release 0.10
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,15 @@ SUBDIRS = include @ZLIBDIR@ src examples test
|
||||||
EXTRA_DIST = docs/manual.html docs/manual.rst docs/extension_protocol.rst \
|
EXTRA_DIST = docs/manual.html docs/manual.rst docs/extension_protocol.rst \
|
||||||
docs/extension_protocol.html docs/udp_tracker_protocol.rst \
|
docs/extension_protocol.html docs/udp_tracker_protocol.rst \
|
||||||
docs/projects.rst docs/projects.html \
|
docs/projects.rst docs/projects.html \
|
||||||
|
docs/arctic_thumb.png \
|
||||||
|
docs/bitbuddy_thumb.jpg \
|
||||||
|
docs/bitslug_thumb.png \
|
||||||
|
docs/btg_thumb.jpg \
|
||||||
|
docs/moopolice_thumb.gif \
|
||||||
|
docs/qbittorrent_thumb.jpg \
|
||||||
|
docs/ziptorrent_thumb.gif \
|
||||||
|
docs/vs2005_build_notes.html \
|
||||||
|
docs/vs2005_build_notes.rst \
|
||||||
docs/udp_tracker_protocol.html docs/client_test.rst docs/client_test.html \
|
docs/udp_tracker_protocol.html docs/client_test.rst docs/client_test.html \
|
||||||
docs/unicode_support.png docs/client_test.png docs/style.css Jamfile project-root.jam \
|
docs/unicode_support.png docs/client_test.png docs/style.css Jamfile project-root.jam \
|
||||||
m4/ac_cxx_namespaces.m4 m4/acx_pthread.m4 m4/ax_boost_date-time.m4 \
|
m4/ac_cxx_namespaces.m4 m4/acx_pthread.m4 m4/ax_boost_date-time.m4 \
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
AC_PREREQ(2.59)
|
AC_PREREQ(2.59)
|
||||||
|
|
||||||
AC_INIT(src/torrent.cpp)
|
AC_INIT(src/torrent.cpp)
|
||||||
AM_INIT_AUTOMAKE(libtorrent, 0.10)
|
AM_INIT_AUTOMAKE(libtorrent, 0.11)
|
||||||
|
|
||||||
AM_CONFIG_HEADER(config.h)
|
AM_CONFIG_HEADER(config.h)
|
||||||
|
|
||||||
|
|
|
@ -18,7 +18,7 @@
|
||||||
<tr><th class="docinfo-name">Author:</th>
|
<tr><th class="docinfo-name">Author:</th>
|
||||||
<td>Arvid Norberg, <a class="last reference" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
<td>Arvid Norberg, <a class="last reference" href="mailto:arvid@rasterbar.com">arvid@rasterbar.com</a></td></tr>
|
||||||
<tr><th class="docinfo-name">Version:</th>
|
<tr><th class="docinfo-name">Version:</th>
|
||||||
<td>0.10</td></tr>
|
<td>0.11</td></tr>
|
||||||
</tbody>
|
</tbody>
|
||||||
</table>
|
</table>
|
||||||
<div class="contents topic" id="table-of-contents">
|
<div class="contents topic" id="table-of-contents">
|
||||||
|
@ -189,7 +189,7 @@ following features:</p>
|
||||||
<li>serves multiple torrents on a single port and in a single thread</li>
|
<li>serves multiple torrents on a single port and in a single thread</li>
|
||||||
<li>gzipped tracker-responses</li>
|
<li>gzipped tracker-responses</li>
|
||||||
<li><a class="reference" href="#http-seeding">HTTP seeding</a>, as <a class="reference" href="http://www.getright.com/seedtorrent.html">specified by Michael Burford of GetRight</a>.</li>
|
<li><a class="reference" href="#http-seeding">HTTP seeding</a>, as <a class="reference" href="http://www.getright.com/seedtorrent.html">specified by Michael Burford of GetRight</a>.</li>
|
||||||
<li>piece picking on block-level like in <a class="reference" href="http://azureus.sourceforge.net">Azureus</a> (as opposed to piece-level).
|
<li>piece picking on block-level (as opposed to piece-level).
|
||||||
This means it can download parts of the same piece from different peers.
|
This means it can download parts of the same piece from different peers.
|
||||||
It will also prefer to download whole pieces from single peers if the
|
It will also prefer to download whole pieces from single peers if the
|
||||||
download speed is high enough from that particular peer.</li>
|
download speed is high enough from that particular peer.</li>
|
||||||
|
|
|
@ -3,7 +3,7 @@ libtorrent manual
|
||||||
=================
|
=================
|
||||||
|
|
||||||
:Author: Arvid Norberg, arvid@rasterbar.com
|
:Author: Arvid Norberg, arvid@rasterbar.com
|
||||||
:Version: 0.10
|
:Version: 0.11
|
||||||
|
|
||||||
.. contents:: Table of contents
|
.. contents:: Table of contents
|
||||||
:depth: 2
|
:depth: 2
|
||||||
|
@ -31,7 +31,7 @@ following features:
|
||||||
* serves multiple torrents on a single port and in a single thread
|
* serves multiple torrents on a single port and in a single thread
|
||||||
* gzipped tracker-responses
|
* gzipped tracker-responses
|
||||||
* `HTTP seeding`_, as `specified by Michael Burford of GetRight`__.
|
* `HTTP seeding`_, as `specified by Michael Burford of GetRight`__.
|
||||||
* piece picking on block-level like in Azureus_ (as opposed to piece-level).
|
* piece picking on block-level (as opposed to piece-level).
|
||||||
This means it can download parts of the same piece from different peers.
|
This means it can download parts of the same piece from different peers.
|
||||||
It will also prefer to download whole pieces from single peers if the
|
It will also prefer to download whole pieces from single peers if the
|
||||||
download speed is high enough from that particular peer.
|
download speed is high enough from that particular peer.
|
||||||
|
@ -67,7 +67,6 @@ following features:
|
||||||
|
|
||||||
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
__ http://home.elp.rr.com/tur/multitracker-spec.txt
|
||||||
__ http://www.getright.com/seedtorrent.html
|
__ http://www.getright.com/seedtorrent.html
|
||||||
.. _Azureus: http://azureus.sourceforge.net
|
|
||||||
__ extension_protocol.html
|
__ extension_protocol.html
|
||||||
__ udp_tracker_protocol.html
|
__ udp_tracker_protocol.html
|
||||||
|
|
||||||
|
|
|
@ -425,6 +425,8 @@ int main(int ac, char* av[])
|
||||||
std::string allocation_mode;
|
std::string allocation_mode;
|
||||||
std::string in_monitor_dir;
|
std::string in_monitor_dir;
|
||||||
std::string bind_to_interface;
|
std::string bind_to_interface;
|
||||||
|
std::string proxy;
|
||||||
|
std::string proxy_login;
|
||||||
int poll_interval;
|
int poll_interval;
|
||||||
|
|
||||||
namespace po = boost::program_options;
|
namespace po = boost::program_options;
|
||||||
|
@ -469,6 +471,13 @@ int main(int ac, char* av[])
|
||||||
("bind,b", po::value<std::string>(&bind_to_interface)->default_value("")
|
("bind,b", po::value<std::string>(&bind_to_interface)->default_value("")
|
||||||
, "Sets the local interface to bind outbound and the listen "
|
, "Sets the local interface to bind outbound and the listen "
|
||||||
"socket to")
|
"socket to")
|
||||||
|
("proxy-server,x", po::value<std::string>(&proxy)->default_value("")
|
||||||
|
, "Sets the http proxy to be used for tracker and web seeds "
|
||||||
|
"connections. The string is expected to be on the form: "
|
||||||
|
"<hostname>:<port>. If no port is specified, 8080 is assumed")
|
||||||
|
("proxy-login,o", po::value<std::string>(&proxy_login)->default_value("")
|
||||||
|
, "Sets the username and password used to authenticate with the http "
|
||||||
|
"proxy. The string should be given in the form: <username>:<password>")
|
||||||
;
|
;
|
||||||
|
|
||||||
po::positional_options_description p;
|
po::positional_options_description p;
|
||||||
|
@ -511,6 +520,38 @@ int main(int ac, char* av[])
|
||||||
input = vm["input-file"].as< std::vector<std::string> >();
|
input = vm["input-file"].as< std::vector<std::string> >();
|
||||||
|
|
||||||
session_settings settings;
|
session_settings settings;
|
||||||
|
|
||||||
|
if (!proxy.empty())
|
||||||
|
{
|
||||||
|
try
|
||||||
|
{
|
||||||
|
std::size_t i = proxy.find(':');
|
||||||
|
settings.proxy_ip = proxy.substr(0, i);
|
||||||
|
if (i == std::string::npos) settings.proxy_port = 8080;
|
||||||
|
else settings.proxy_port = boost::lexical_cast<int>(
|
||||||
|
proxy.substr(i + 1));
|
||||||
|
}
|
||||||
|
catch (std::exception&)
|
||||||
|
{
|
||||||
|
std::cerr << "Proxy hostname did not match the required format: "
|
||||||
|
<< proxy << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!proxy_login.empty())
|
||||||
|
{
|
||||||
|
std::size_t i = proxy_login.find(':');
|
||||||
|
if (i == std::string::npos)
|
||||||
|
{
|
||||||
|
std::cerr << "Proxy login did not match the required format: "
|
||||||
|
<< proxy_login << std::endl;
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
settings.proxy_login = proxy_login.substr(0, i);
|
||||||
|
settings.proxy_password = proxy_login.substr(i + 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
settings.user_agent = "client_test " LIBTORRENT_VERSION;
|
settings.user_agent = "client_test " LIBTORRENT_VERSION;
|
||||||
settings.sequenced_download_threshold = 15;
|
settings.sequenced_download_threshold = 15;
|
||||||
|
|
||||||
|
|
|
@ -34,8 +34,8 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#define TORRENT_VERSION_HPP_INCLUDED
|
#define TORRENT_VERSION_HPP_INCLUDED
|
||||||
|
|
||||||
#define LIBTORRENT_VERSION_MAJOR 0
|
#define LIBTORRENT_VERSION_MAJOR 0
|
||||||
#define LIBTORRENT_VERSION_MINOR 10
|
#define LIBTORRENT_VERSION_MINOR 11
|
||||||
|
|
||||||
#define LIBTORRENT_VERSION "0.10.0.0"
|
#define LIBTORRENT_VERSION "0.11.0.0"
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -128,7 +128,6 @@ namespace libtorrent
|
||||||
|
|
||||||
#ifndef NDEBUG
|
#ifndef NDEBUG
|
||||||
void check_invariant() const;
|
void check_invariant() const;
|
||||||
boost::posix_time::ptime m_last_choke;
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
|
@ -1054,7 +1054,6 @@ namespace libtorrent { namespace detail
|
||||||
i != m_half_open.end(); ++i)
|
i != m_half_open.end(); ++i)
|
||||||
{
|
{
|
||||||
assert(i->second->is_connecting());
|
assert(i->second->is_connecting());
|
||||||
// assert(m_selector.is_writability_monitored(i->second->get_socket()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (connection_map::iterator i = m_connections.begin();
|
for (connection_map::iterator i = m_connections.begin();
|
||||||
|
@ -1062,14 +1061,10 @@ namespace libtorrent { namespace detail
|
||||||
{
|
{
|
||||||
assert(i->second);
|
assert(i->second);
|
||||||
assert(!i->second->is_connecting());
|
assert(!i->second->is_connecting());
|
||||||
if (i->second->is_connecting()
|
if (i->second->is_connecting())
|
||||||
/* || i->second->can_write() != m_selector.is_writability_monitored(i->first)
|
|
||||||
|| i->second->can_read() != m_selector.is_readability_monitored(i->first)*/)
|
|
||||||
{
|
{
|
||||||
std::ofstream error_log("error.log", std::ios_base::app);
|
std::ofstream error_log("error.log", std::ios_base::app);
|
||||||
boost::intrusive_ptr<peer_connection> p = i->second;
|
boost::intrusive_ptr<peer_connection> p = i->second;
|
||||||
// error_log << "selector::is_writability_monitored() " << m_selector.is_writability_monitored(i->first) << "\n";
|
|
||||||
// error_log << "selector::is_readability_monitored() " << m_selector.is_readability_monitored(i->first) << "\n";
|
|
||||||
error_log << "peer_connection::is_connecting() " << p->is_connecting() << "\n";
|
error_log << "peer_connection::is_connecting() " << p->is_connecting() << "\n";
|
||||||
error_log << "peer_connection::can_write() " << p->can_write() << "\n";
|
error_log << "peer_connection::can_write() " << p->can_write() << "\n";
|
||||||
error_log << "peer_connection::can_read() " << p->can_read() << "\n";
|
error_log << "peer_connection::can_read() " << p->can_read() << "\n";
|
||||||
|
@ -1396,16 +1391,24 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
session_impl::mutex_t::scoped_lock l(m_impl.m_mutex);
|
session_impl::mutex_t::scoped_lock l(m_impl.m_mutex);
|
||||||
|
|
||||||
|
tcp::endpoint new_interface;
|
||||||
|
if (net_interface && std::strlen(net_interface) > 0)
|
||||||
|
new_interface = tcp::endpoint(address::from_string(net_interface), port_range.first);
|
||||||
|
else
|
||||||
|
new_interface = tcp::endpoint(address(), port_range.first);
|
||||||
|
|
||||||
|
m_impl.m_listen_port_range = port_range;
|
||||||
|
|
||||||
|
// if the interface is the same and the socket is open
|
||||||
|
// don't do anything
|
||||||
|
if (new_interface == m_impl.m_listen_interface
|
||||||
|
&& m_impl.m_listen_socket) return true;
|
||||||
|
|
||||||
if (m_impl.m_listen_socket)
|
if (m_impl.m_listen_socket)
|
||||||
m_impl.m_listen_socket.reset();
|
m_impl.m_listen_socket.reset();
|
||||||
|
|
||||||
m_impl.m_incoming_connection = false;
|
m_impl.m_incoming_connection = false;
|
||||||
|
m_impl.m_listen_interface = new_interface;
|
||||||
m_impl.m_listen_port_range = port_range;
|
|
||||||
if (net_interface && std::strlen(net_interface) > 0)
|
|
||||||
m_impl.m_listen_interface = tcp::endpoint(address::from_string(net_interface), port_range.first);
|
|
||||||
else
|
|
||||||
m_impl.m_listen_interface = tcp::endpoint(address(), port_range.first);
|
|
||||||
|
|
||||||
m_impl.open_listen_port();
|
m_impl.open_listen_port();
|
||||||
return m_impl.m_listen_socket;
|
return m_impl.m_listen_socket;
|
||||||
|
|
|
@ -960,11 +960,21 @@ namespace libtorrent
|
||||||
= parse_url_components(url);
|
= parse_url_components(url);
|
||||||
|
|
||||||
m_resolving_web_seeds.insert(url);
|
m_resolving_web_seeds.insert(url);
|
||||||
|
if (m_ses.m_settings.proxy_ip.empty())
|
||||||
|
{
|
||||||
tcp::resolver::query q(hostname, "0");
|
tcp::resolver::query q(hostname, "0");
|
||||||
|
|
||||||
m_host_resolver.async_resolve(q, bind(&torrent::on_name_lookup
|
m_host_resolver.async_resolve(q, bind(&torrent::on_name_lookup
|
||||||
, shared_from_this(), _1, _2, port, url));
|
, shared_from_this(), _1, _2, port, url));
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// use proxy
|
||||||
|
tcp::resolver::query q(m_ses.m_settings.proxy_ip, "0");
|
||||||
|
m_host_resolver.async_resolve(q, bind(&torrent::on_name_lookup
|
||||||
|
, shared_from_this(), _1, _2, m_ses.m_settings.proxy_port, url));
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void torrent::on_name_lookup(asio::error const& e, tcp::resolver::iterator host
|
void torrent::on_name_lookup(asio::error const& e, tcp::resolver::iterator host
|
||||||
, int port, std::string url) try
|
, int port, std::string url) try
|
||||||
|
|
|
@ -138,10 +138,15 @@ namespace libtorrent
|
||||||
|
|
||||||
m_requests.push_back(r);
|
m_requests.push_back(r);
|
||||||
|
|
||||||
|
bool using_proxy = false;
|
||||||
|
if (!m_ses.m_settings.proxy_ip.empty())
|
||||||
|
using_proxy = true;
|
||||||
|
|
||||||
if (single_file_request)
|
if (single_file_request)
|
||||||
{
|
{
|
||||||
request += "GET ";
|
request += "GET ";
|
||||||
request += escape_path(m_path.c_str(), m_path.length());
|
if (using_proxy) request += m_url;
|
||||||
|
else request += escape_path(m_path.c_str(), m_path.length());
|
||||||
request += " HTTP/1.1\r\n";
|
request += " HTTP/1.1\r\n";
|
||||||
request += "Host: ";
|
request += "Host: ";
|
||||||
request += m_host;
|
request += m_host;
|
||||||
|
@ -151,13 +156,23 @@ namespace libtorrent
|
||||||
request += escape_string(m_ses.m_settings.user_agent.c_str()
|
request += escape_string(m_ses.m_settings.user_agent.c_str()
|
||||||
, m_ses.m_settings.user_agent.size());
|
, m_ses.m_settings.user_agent.size());
|
||||||
}
|
}
|
||||||
|
if (using_proxy && !m_ses.m_settings.proxy_login.empty())
|
||||||
|
{
|
||||||
|
request += "\r\nProxy-Authorization: Basic ";
|
||||||
|
request += base64encode(m_ses.m_settings.proxy_login + ":"
|
||||||
|
+ m_ses.m_settings.proxy_password);
|
||||||
|
}
|
||||||
|
if (using_proxy)
|
||||||
|
{
|
||||||
|
request += "\r\nProxy-Connection: keep-alive";
|
||||||
|
}
|
||||||
request += "\r\nRange: bytes=";
|
request += "\r\nRange: bytes=";
|
||||||
request += boost::lexical_cast<std::string>(r.piece
|
request += boost::lexical_cast<std::string>(r.piece
|
||||||
* info.piece_length() + r.start);
|
* info.piece_length() + r.start);
|
||||||
request += "-";
|
request += "-";
|
||||||
request += boost::lexical_cast<std::string>(r.piece
|
request += boost::lexical_cast<std::string>(r.piece
|
||||||
* info.piece_length() + r.start + r.length - 1);
|
* info.piece_length() + r.start + r.length - 1);
|
||||||
if (m_first_request)
|
if (m_first_request || using_proxy)
|
||||||
request += "\r\nConnection: keep-alive";
|
request += "\r\nConnection: keep-alive";
|
||||||
request += "\r\n\r\n";
|
request += "\r\n\r\n";
|
||||||
m_first_request = false;
|
m_first_request = false;
|
||||||
|
@ -173,10 +188,19 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
file_slice const& f = *i;
|
file_slice const& f = *i;
|
||||||
|
|
||||||
|
request += "GET ";
|
||||||
|
if (using_proxy)
|
||||||
|
{
|
||||||
|
request += m_url;
|
||||||
|
std::string path = info.file_at(f.file_index).path.string();
|
||||||
|
request += escape_path(path.c_str(), path.length());
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
std::string path = m_path;
|
std::string path = m_path;
|
||||||
path += info.file_at(f.file_index).path.string();
|
path += info.file_at(f.file_index).path.string();
|
||||||
request += "GET ";
|
|
||||||
request += escape_path(path.c_str(), path.length());
|
request += escape_path(path.c_str(), path.length());
|
||||||
|
}
|
||||||
request += " HTTP/1.1\r\n";
|
request += " HTTP/1.1\r\n";
|
||||||
request += "Host: ";
|
request += "Host: ";
|
||||||
request += m_host;
|
request += m_host;
|
||||||
|
@ -186,11 +210,21 @@ namespace libtorrent
|
||||||
request += escape_string(m_ses.m_settings.user_agent.c_str()
|
request += escape_string(m_ses.m_settings.user_agent.c_str()
|
||||||
, m_ses.m_settings.user_agent.size());
|
, m_ses.m_settings.user_agent.size());
|
||||||
}
|
}
|
||||||
|
if (using_proxy && !m_ses.m_settings.proxy_login.empty())
|
||||||
|
{
|
||||||
|
request += "\r\nProxy-Authorization: Basic ";
|
||||||
|
request += base64encode(m_ses.m_settings.proxy_login + ":"
|
||||||
|
+ m_ses.m_settings.proxy_password);
|
||||||
|
}
|
||||||
|
if (using_proxy)
|
||||||
|
{
|
||||||
|
request += "\r\nProxy-Connection: keep-alive";
|
||||||
|
}
|
||||||
request += "\r\nRange: bytes=";
|
request += "\r\nRange: bytes=";
|
||||||
request += boost::lexical_cast<std::string>(f.offset);
|
request += boost::lexical_cast<std::string>(f.offset);
|
||||||
request += "-";
|
request += "-";
|
||||||
request += boost::lexical_cast<std::string>(f.offset + f.size - 1);
|
request += boost::lexical_cast<std::string>(f.offset + f.size - 1);
|
||||||
if (m_first_request)
|
if (m_first_request || using_proxy)
|
||||||
request += "\r\nConnection: keep-alive";
|
request += "\r\nConnection: keep-alive";
|
||||||
request += "\r\n\r\n";
|
request += "\r\n\r\n";
|
||||||
m_first_request = false;
|
m_first_request = false;
|
||||||
|
|
Loading…
Reference in New Issue