allow extending web seeds with extra headers and custom authorization schemese
This commit is contained in:
parent
3b550ece98
commit
72322dbc10
|
@ -2,6 +2,7 @@ cmake_minimum_required(VERSION 2.6)
|
||||||
project(libtorrent)
|
project(libtorrent)
|
||||||
|
|
||||||
set(sources
|
set(sources
|
||||||
|
web_connection_base
|
||||||
alert
|
alert
|
||||||
allocator
|
allocator
|
||||||
assert
|
assert
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
|
* support extending web seeds with custom authorization and extra headers
|
||||||
* settings that are not changed from the default values are not saved
|
* settings that are not changed from the default values are not saved
|
||||||
in the session state
|
in the session state
|
||||||
* made seeding choking algorithm configurable
|
* made seeding choking algorithm configurable
|
||||||
|
|
1
Jamfile
1
Jamfile
|
@ -375,6 +375,7 @@ SOURCES =
|
||||||
ip_filter
|
ip_filter
|
||||||
peer_connection
|
peer_connection
|
||||||
bt_peer_connection
|
bt_peer_connection
|
||||||
|
web_connection_base
|
||||||
web_peer_connection
|
web_peer_connection
|
||||||
http_seed_connection
|
http_seed_connection
|
||||||
i2p_stream
|
i2p_stream
|
||||||
|
|
|
@ -1385,10 +1385,9 @@ The ``torrent_info`` has the following synopsis::
|
||||||
|
|
||||||
bool priv() const;
|
bool priv() const;
|
||||||
|
|
||||||
std::vector<std::string> const& url_seeds() const;
|
|
||||||
void add_url_seed(std::string const& url);
|
void add_url_seed(std::string const& url);
|
||||||
std::vector<std::string> const& http_seeds() const;
|
|
||||||
void add_http_seed(std::string const& url);
|
void add_http_seed(std::string const& url);
|
||||||
|
std::vector<web_seed_entry> const& web_seeds() const;
|
||||||
|
|
||||||
size_type total_size() const;
|
size_type total_size() const;
|
||||||
int piece_length() const;
|
int piece_length() const;
|
||||||
|
@ -1646,24 +1645,59 @@ The input range is assumed to be valid within the torrent. ``file_offset``
|
||||||
must refer to a valid file, i.e. it cannot be >= ``num_files()``.
|
must refer to a valid file, i.e. it cannot be >= ``num_files()``.
|
||||||
|
|
||||||
|
|
||||||
url_seeds() add_url_seed() http_seeds() add_http_seed()
|
add_url_seed() add_http_seed()
|
||||||
-------------------------------------------------------
|
------------------------------
|
||||||
|
|
||||||
::
|
::
|
||||||
|
|
||||||
std::vector<std::string> const& url_seeds() const;
|
void add_url_seed(std::string const& url
|
||||||
void add_url_seed(std::string const& url);
|
, std::string const& extern_auth = std::string()
|
||||||
std::vector<std::string> const& http_seeds() const;
|
, web_seed_entry::headers_t const& extra_headers = web_seed_entry::headers_t());
|
||||||
void add_http_seed(std::string const& url);
|
void add_http_seed(std::string const& url
|
||||||
|
, std::string const& extern_auth = std::string()
|
||||||
|
, web_seed_entry::headers_t const& extra_headers = web_seed_entry::headers_t());
|
||||||
|
std::vector<web_seed_entry> const& web_seeds() const;
|
||||||
|
|
||||||
|
``web_seeds()`` returns all url seeds and http seeds in the torrent. Each entry
|
||||||
|
is a ``web_seed_entry`` and may refer to either a url seed or http seed.
|
||||||
|
|
||||||
If there are any url-seeds or http seeds in this torrent, ``url_seeds()``
|
|
||||||
and ``http_seeds()`` will return a vector of those urls.
|
|
||||||
``add_url_seed()`` and ``add_http_seed()`` adds one url to the list of
|
``add_url_seed()`` and ``add_http_seed()`` adds one url to the list of
|
||||||
url/http seeds. Currently, the only transport protocol
|
url/http seeds. Currently, the only transport protocol supported for the url
|
||||||
supported for the url is http.
|
is http.
|
||||||
|
|
||||||
|
The ``extern_auth`` argument can be used for other athorization schemese than
|
||||||
|
basic HTTP authorization. If set, it will override any username and password
|
||||||
|
found in the URL itself. The string will be sent as the HTTP authorization header's
|
||||||
|
value (without specifying "Basic").
|
||||||
|
|
||||||
|
The ``extra_headers`` argument defaults to an empty list, but can be used to
|
||||||
|
insert custom HTTP headers in the requests to a specific web seed.
|
||||||
|
|
||||||
See `HTTP seeding`_ for more information.
|
See `HTTP seeding`_ for more information.
|
||||||
|
|
||||||
|
The ``web_seed_entry`` has the following members::
|
||||||
|
|
||||||
|
struct web_seed_entry
|
||||||
|
{
|
||||||
|
enum type_t { url_seed, http_seed };
|
||||||
|
|
||||||
|
typedef std::vector<std::pair<std::string, std::string> > headers_t;
|
||||||
|
|
||||||
|
web_seed_entry(std::string const& url_, type_t type_
|
||||||
|
, std::string const& auth_ = std::string()
|
||||||
|
, headers_t const& extra_headers_ = headers_t());
|
||||||
|
|
||||||
|
bool operator==(web_seed_entry const& e) const;
|
||||||
|
bool operator<(web_seed_entry const& e) const;
|
||||||
|
|
||||||
|
std::string url;
|
||||||
|
type_t type;
|
||||||
|
std::string auth;
|
||||||
|
headers_t extra_headers;
|
||||||
|
|
||||||
|
// ...
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
trackers()
|
trackers()
|
||||||
----------
|
----------
|
||||||
|
|
|
@ -168,6 +168,21 @@ support, you need to patch parts of boost.
|
||||||
|
|
||||||
Also make sure to optimize for size when compiling.
|
Also make sure to optimize for size when compiling.
|
||||||
|
|
||||||
|
Another way of reducing the executable size is to disable code that isn't used.
|
||||||
|
There are a number of ``TORRENT_*`` macros that control which features are included
|
||||||
|
in libtorrent. If these macros are used to strip down libtorrent, make sure the same
|
||||||
|
macros are defined when building libtorrent as when linking against it. If these
|
||||||
|
are different the structures will look different from the libtorrent side and from
|
||||||
|
the client side and memory corruption will follow.
|
||||||
|
|
||||||
|
One, probably, safe macro to define is ``TORRENT_NO_DEPRECATE`` which removes all
|
||||||
|
deprecated functions and struct members. As long as no deprecated functions are
|
||||||
|
relied upon, this should be a simple way to eliminate a little bit of code.
|
||||||
|
|
||||||
|
For all available options, see the `building libtorrent`_ secion.
|
||||||
|
|
||||||
|
.. _`building libtorrent`: building.html
|
||||||
|
|
||||||
reduce statistics
|
reduce statistics
|
||||||
-----------------
|
-----------------
|
||||||
|
|
||||||
|
|
|
@ -56,7 +56,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/peer_connection.hpp"
|
#include "libtorrent/web_connection_base.hpp"
|
||||||
#include "libtorrent/disk_buffer_holder.hpp"
|
#include "libtorrent/disk_buffer_holder.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/piece_block_progress.hpp"
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
|
@ -73,7 +73,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
class TORRENT_EXPORT http_seed_connection
|
class TORRENT_EXPORT http_seed_connection
|
||||||
: public peer_connection
|
: public web_connection_base
|
||||||
{
|
{
|
||||||
friend class invariant_access;
|
friend class invariant_access;
|
||||||
public:
|
public:
|
||||||
|
@ -87,43 +87,23 @@ namespace libtorrent
|
||||||
, boost::shared_ptr<socket_type> s
|
, boost::shared_ptr<socket_type> s
|
||||||
, tcp::endpoint const& remote
|
, tcp::endpoint const& remote
|
||||||
, std::string const& url
|
, std::string const& url
|
||||||
, policy::peer* peerinfo);
|
, policy::peer* peerinfo
|
||||||
void start();
|
, std::string const& ext_auth
|
||||||
|
, web_seed_entry::headers_t const& ext_headers);
|
||||||
|
|
||||||
virtual int type() const { return peer_connection::http_seed_connection; }
|
virtual int type() const { return peer_connection::http_seed_connection; }
|
||||||
|
|
||||||
// called from the main loop when this connection has any
|
// called from the main loop when this connection has any
|
||||||
// work to do.
|
// work to do.
|
||||||
void on_sent(error_code const& error
|
|
||||||
, std::size_t bytes_transferred);
|
|
||||||
void on_receive(error_code const& error
|
void on_receive(error_code const& error
|
||||||
, std::size_t bytes_transferred);
|
, std::size_t bytes_transferred);
|
||||||
|
|
||||||
std::string const& url() const { return m_url; }
|
std::string const& url() const { return m_url; }
|
||||||
|
|
||||||
virtual void get_specific_peer_info(peer_info& p) const;
|
virtual void get_specific_peer_info(peer_info& p) const;
|
||||||
virtual bool in_handshake() const;
|
|
||||||
virtual void disconnect(error_code const& ec, int error = 0);
|
virtual void disconnect(error_code const& ec, int error = 0);
|
||||||
|
|
||||||
// the following functions appends messages
|
|
||||||
// to the send buffer
|
|
||||||
void write_choke() {}
|
|
||||||
void write_unchoke() {}
|
|
||||||
void write_interested() {}
|
|
||||||
void write_not_interested() {}
|
|
||||||
void write_request(peer_request const& r);
|
void write_request(peer_request const& r);
|
||||||
void write_cancel(peer_request const& r) {}
|
|
||||||
void write_have(int index) {}
|
|
||||||
void write_piece(peer_request const& r, disk_buffer_holder& buffer) { TORRENT_ASSERT(false); }
|
|
||||||
void write_keepalive() {}
|
|
||||||
void on_connected();
|
|
||||||
void write_reject_request(peer_request const&) {}
|
|
||||||
void write_allow_fast(int) {}
|
|
||||||
void write_suggest(int piece) {}
|
|
||||||
|
|
||||||
#ifdef TORRENT_DEBUG
|
|
||||||
void check_invariant() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -134,32 +114,13 @@ namespace libtorrent
|
||||||
// will be invalid.
|
// will be invalid.
|
||||||
boost::optional<piece_block_progress> downloading_piece_progress() const;
|
boost::optional<piece_block_progress> downloading_piece_progress() const;
|
||||||
|
|
||||||
// this has one entry per bittorrent request
|
|
||||||
std::deque<peer_request> m_requests;
|
|
||||||
|
|
||||||
std::string m_server_string;
|
|
||||||
http_parser m_parser;
|
|
||||||
std::string m_auth;
|
|
||||||
std::string m_host;
|
|
||||||
int m_port;
|
|
||||||
std::string m_path;
|
|
||||||
|
|
||||||
// this is const since it's used as a key in the web seed list in the torrent
|
// this is const since it's used as a key in the web seed list in the torrent
|
||||||
// if it's changed referencing back into that list will fail
|
// if it's changed referencing back into that list will fail
|
||||||
const std::string m_url;
|
const std::string m_url;
|
||||||
|
|
||||||
// the first request will contain a little bit more data
|
|
||||||
// than subsequent ones, things that aren't critical are left
|
|
||||||
// out to save bandwidth.
|
|
||||||
bool m_first_request;
|
|
||||||
|
|
||||||
// the number of bytes left to receive of the response we're
|
// the number of bytes left to receive of the response we're
|
||||||
// currently parsing
|
// currently parsing
|
||||||
int m_response_left;
|
int m_response_left;
|
||||||
|
|
||||||
// the number of bytes in the start of the receive buffer
|
|
||||||
// that's http header
|
|
||||||
int m_body_start;
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -98,39 +98,6 @@ namespace libtorrent
|
||||||
struct piece_checker_data;
|
struct piece_checker_data;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct web_seed_entry
|
|
||||||
{
|
|
||||||
std::string url;
|
|
||||||
// http seeds are different from url seeds in the
|
|
||||||
// protocol they use. http seeds follows the original
|
|
||||||
// http seed spec. by John Hoffman
|
|
||||||
enum type_t { url_seed, http_seed } type;
|
|
||||||
|
|
||||||
// if this is > now, we can't reconnect yet
|
|
||||||
ptime retry;
|
|
||||||
|
|
||||||
// this indicates whether or not we're resolving the
|
|
||||||
// hostname of this URL
|
|
||||||
bool resolving;
|
|
||||||
|
|
||||||
tcp::endpoint endpoint;
|
|
||||||
|
|
||||||
peer_connection* connection;
|
|
||||||
|
|
||||||
web_seed_entry(std::string const& url_, type_t type_)
|
|
||||||
: url(url_), type(type_), retry(time_now()), resolving(false), connection(0) {}
|
|
||||||
|
|
||||||
bool operator==(web_seed_entry const& e) const
|
|
||||||
{ return url == e.url && type == e.type; }
|
|
||||||
|
|
||||||
bool operator<(web_seed_entry const& e) const
|
|
||||||
{
|
|
||||||
if (url < e.url) return true;
|
|
||||||
if (url > e.url) return false;
|
|
||||||
return type < e.type;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
// a torrent is a class that holds information
|
// a torrent is a class that holds information
|
||||||
// for a specific download. It updates itself against
|
// for a specific download. It updates itself against
|
||||||
// the tracker
|
// the tracker
|
||||||
|
@ -365,7 +332,23 @@ namespace libtorrent
|
||||||
// add or remove a url that will be attempted for
|
// add or remove a url that will be attempted for
|
||||||
// finding the file(s) in this torrent.
|
// finding the file(s) in this torrent.
|
||||||
void add_web_seed(std::string const& url, web_seed_entry::type_t type)
|
void add_web_seed(std::string const& url, web_seed_entry::type_t type)
|
||||||
{ m_web_seeds.push_back(web_seed_entry(url, type)); }
|
{
|
||||||
|
m_web_seeds.push_back(web_seed_entry(url, type));
|
||||||
|
}
|
||||||
|
|
||||||
|
void add_web_seed(std::string const& url, web_seed_entry::type_t type
|
||||||
|
, std::string const& auth, web_seed_entry::headers_t const& extra_headers)
|
||||||
|
{
|
||||||
|
m_web_seeds.push_back(web_seed_entry(url, type, auth, extra_headers));
|
||||||
|
}
|
||||||
|
|
||||||
|
void remove_web_seed(std::string const& url, web_seed_entry::type_t type)
|
||||||
|
{
|
||||||
|
std::list<web_seed_entry>::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end()
|
||||||
|
, (boost::bind(&web_seed_entry::url, _1)
|
||||||
|
== url && boost::bind(&web_seed_entry::type, _1) == type));
|
||||||
|
if (i != m_web_seeds.end()) m_web_seeds.erase(i);
|
||||||
|
}
|
||||||
|
|
||||||
void disconnect_web_seed(peer_connection* p)
|
void disconnect_web_seed(peer_connection* p)
|
||||||
{
|
{
|
||||||
|
@ -379,14 +362,6 @@ namespace libtorrent
|
||||||
i->connection = 0;
|
i->connection = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void remove_web_seed(std::string const& url, web_seed_entry::type_t type)
|
|
||||||
{
|
|
||||||
std::list<web_seed_entry>::iterator i = std::find_if(m_web_seeds.begin(), m_web_seeds.end()
|
|
||||||
, (boost::bind(&web_seed_entry::url, _1)
|
|
||||||
== url && boost::bind(&web_seed_entry::type, _1) == type));
|
|
||||||
if (i != m_web_seeds.end()) m_web_seeds.erase(i);
|
|
||||||
}
|
|
||||||
|
|
||||||
void retry_web_seed(peer_connection* p, int retry = 0);
|
void retry_web_seed(peer_connection* p, int retry = 0);
|
||||||
|
|
||||||
void remove_web_seed(peer_connection* p)
|
void remove_web_seed(peer_connection* p)
|
||||||
|
|
|
@ -57,9 +57,12 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
#include "libtorrent/file_storage.hpp"
|
#include "libtorrent/file_storage.hpp"
|
||||||
#include "libtorrent/copy_ptr.hpp"
|
#include "libtorrent/copy_ptr.hpp"
|
||||||
|
#include "libtorrent/socket.hpp"
|
||||||
|
|
||||||
namespace libtorrent
|
namespace libtorrent
|
||||||
{
|
{
|
||||||
|
struct peer_connection;
|
||||||
|
|
||||||
enum
|
enum
|
||||||
{
|
{
|
||||||
// wait 60 seconds before retrying a failed tracker
|
// wait 60 seconds before retrying a failed tracker
|
||||||
|
@ -168,6 +171,50 @@ namespace libtorrent
|
||||||
void trim();
|
void trim();
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct web_seed_entry
|
||||||
|
{
|
||||||
|
// http seeds are different from url seeds in the
|
||||||
|
// protocol they use. http seeds follows the original
|
||||||
|
// http seed spec. by John Hoffman
|
||||||
|
enum type_t { url_seed, http_seed };
|
||||||
|
|
||||||
|
typedef std::vector<std::pair<std::string, std::string> > headers_t;
|
||||||
|
|
||||||
|
web_seed_entry(std::string const& url_, type_t type_
|
||||||
|
, std::string const& auth_ = std::string()
|
||||||
|
, headers_t const& extra_headers_ = headers_t())
|
||||||
|
: url(url_), type(type_)
|
||||||
|
, auth(auth_), extra_headers(extra_headers_)
|
||||||
|
, retry(time_now()), resolving(false), connection(0)
|
||||||
|
{}
|
||||||
|
|
||||||
|
bool operator==(web_seed_entry const& e) const
|
||||||
|
{ return url == e.url && type == e.type; }
|
||||||
|
|
||||||
|
bool operator<(web_seed_entry const& e) const
|
||||||
|
{
|
||||||
|
if (url < e.url) return true;
|
||||||
|
if (url > e.url) return false;
|
||||||
|
return type < e.type;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::string url;
|
||||||
|
type_t type;
|
||||||
|
std::string auth;
|
||||||
|
headers_t extra_headers;
|
||||||
|
|
||||||
|
// if this is > now, we can't reconnect yet
|
||||||
|
ptime retry;
|
||||||
|
|
||||||
|
// this indicates whether or not we're resolving the
|
||||||
|
// hostname of this URL
|
||||||
|
bool resolving;
|
||||||
|
|
||||||
|
tcp::endpoint endpoint;
|
||||||
|
|
||||||
|
peer_connection* connection;
|
||||||
|
};
|
||||||
|
|
||||||
#ifndef BOOST_NO_EXCEPTIONS
|
#ifndef BOOST_NO_EXCEPTIONS
|
||||||
// for backwards compatibility with 0.14
|
// for backwards compatibility with 0.14
|
||||||
typedef libtorrent_exception invalid_torrent_file;
|
typedef libtorrent_exception invalid_torrent_file;
|
||||||
|
@ -220,15 +267,24 @@ namespace libtorrent
|
||||||
void add_tracker(std::string const& url, int tier = 0);
|
void add_tracker(std::string const& url, int tier = 0);
|
||||||
std::vector<announce_entry> const& trackers() const { return m_urls; }
|
std::vector<announce_entry> const& trackers() const { return m_urls; }
|
||||||
|
|
||||||
std::vector<std::string> const& url_seeds() const
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
{ return m_url_seeds; }
|
// deprecated in 0.16. Use web_seeds() instead
|
||||||
void add_url_seed(std::string const& url)
|
TORRENT_DEPRECATED_PREFIX
|
||||||
{ m_url_seeds.push_back(url); }
|
std::vector<std::string> url_seeds() const TORRENT_DEPRECATED;
|
||||||
|
TORRENT_DEPRECATED_PREFIX
|
||||||
|
std::vector<std::string> http_seeds() const TORRENT_DEPRECATED;
|
||||||
|
#endif // TORRENT_NO_DEPRECATE
|
||||||
|
|
||||||
std::vector<std::string> const& http_seeds() const
|
void add_url_seed(std::string const& url
|
||||||
{ return m_http_seeds; }
|
, std::string const& extern_auth = std::string()
|
||||||
void add_http_seed(std::string const& url)
|
, web_seed_entry::headers_t const& extra_headers = web_seed_entry::headers_t());
|
||||||
{ m_http_seeds.push_back(url); }
|
|
||||||
|
void add_http_seed(std::string const& url
|
||||||
|
, std::string const& extern_auth = std::string()
|
||||||
|
, web_seed_entry::headers_t const& extra_headers = web_seed_entry::headers_t());
|
||||||
|
|
||||||
|
std::vector<web_seed_entry> const& web_seeds() const
|
||||||
|
{ return m_web_seeds; }
|
||||||
|
|
||||||
size_type total_size() const { return m_files.total_size(); }
|
size_type total_size() const { return m_files.total_size(); }
|
||||||
int piece_length() const { return m_files.piece_length(); }
|
int piece_length() const { return m_files.piece_length(); }
|
||||||
|
@ -358,8 +414,7 @@ namespace libtorrent
|
||||||
|
|
||||||
// the urls to the trackers
|
// the urls to the trackers
|
||||||
std::vector<announce_entry> m_urls;
|
std::vector<announce_entry> m_urls;
|
||||||
std::vector<std::string> m_url_seeds;
|
std::vector<web_seed_entry> m_web_seeds;
|
||||||
std::vector<std::string> m_http_seeds;
|
|
||||||
nodes_t m_nodes;
|
nodes_t m_nodes;
|
||||||
|
|
||||||
// if this is a merkle torrent, this is the merkle
|
// if this is a merkle torrent, this is the merkle
|
||||||
|
|
|
@ -0,0 +1,168 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2003, Arvid Norberg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the author nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef WEB_CONNECTION_BASE_HPP_INCLUDED
|
||||||
|
#define WEB_CONNECTION_BASE_HPP_INCLUDED
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
#include <algorithm>
|
||||||
|
#include <vector>
|
||||||
|
#include <deque>
|
||||||
|
#include <string>
|
||||||
|
|
||||||
|
#include "libtorrent/debug.hpp"
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(push, 1)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <boost/smart_ptr.hpp>
|
||||||
|
#include <boost/weak_ptr.hpp>
|
||||||
|
#include <boost/noncopyable.hpp>
|
||||||
|
#include <boost/array.hpp>
|
||||||
|
#include <boost/optional.hpp>
|
||||||
|
#include <boost/cstdint.hpp>
|
||||||
|
|
||||||
|
#ifdef _MSC_VER
|
||||||
|
#pragma warning(pop)
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include "libtorrent/buffer.hpp"
|
||||||
|
#include "libtorrent/peer_connection.hpp"
|
||||||
|
#include "libtorrent/socket.hpp"
|
||||||
|
#include "libtorrent/peer_id.hpp"
|
||||||
|
#include "libtorrent/storage.hpp"
|
||||||
|
#include "libtorrent/stat.hpp"
|
||||||
|
#include "libtorrent/alert.hpp"
|
||||||
|
#include "libtorrent/torrent_handle.hpp"
|
||||||
|
#include "libtorrent/torrent.hpp"
|
||||||
|
#include "libtorrent/peer_request.hpp"
|
||||||
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
|
#include "libtorrent/config.hpp"
|
||||||
|
// parse_url
|
||||||
|
#include "libtorrent/tracker_manager.hpp"
|
||||||
|
#include "libtorrent/http_parser.hpp"
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
class torrent;
|
||||||
|
|
||||||
|
namespace detail
|
||||||
|
{
|
||||||
|
struct session_impl;
|
||||||
|
}
|
||||||
|
|
||||||
|
class TORRENT_EXPORT web_connection_base
|
||||||
|
: public peer_connection
|
||||||
|
{
|
||||||
|
friend class invariant_access;
|
||||||
|
public:
|
||||||
|
|
||||||
|
// this is the constructor where the we are the active part.
|
||||||
|
// The peer_conenction should handshake and verify that the
|
||||||
|
// other end has the correct id
|
||||||
|
web_connection_base(
|
||||||
|
aux::session_impl& ses
|
||||||
|
, boost::weak_ptr<torrent> t
|
||||||
|
, boost::shared_ptr<socket_type> s
|
||||||
|
, tcp::endpoint const& remote
|
||||||
|
, std::string const& url
|
||||||
|
, policy::peer* peerinfo
|
||||||
|
, std::string const& ext_auth
|
||||||
|
, web_seed_entry::headers_t const& ext_headers);
|
||||||
|
void start();
|
||||||
|
|
||||||
|
~web_connection_base();
|
||||||
|
|
||||||
|
// called from the main loop when this connection has any
|
||||||
|
// work to do.
|
||||||
|
void on_sent(error_code const& error
|
||||||
|
, std::size_t bytes_transferred);
|
||||||
|
|
||||||
|
virtual std::string const& url() const = 0;
|
||||||
|
|
||||||
|
bool in_handshake() const;
|
||||||
|
|
||||||
|
// the following functions appends messages
|
||||||
|
// to the send buffer
|
||||||
|
void write_choke() {}
|
||||||
|
void write_unchoke() {}
|
||||||
|
void write_interested() {}
|
||||||
|
void write_not_interested() {}
|
||||||
|
virtual void write_request(peer_request const& r) = 0;
|
||||||
|
void write_cancel(peer_request const& r)
|
||||||
|
{ incoming_reject_request(r); }
|
||||||
|
void write_have(int index) {}
|
||||||
|
void write_piece(peer_request const& r, disk_buffer_holder& buffer) { TORRENT_ASSERT(false); }
|
||||||
|
void write_keepalive() {}
|
||||||
|
void on_connected();
|
||||||
|
void write_reject_request(peer_request const&) {}
|
||||||
|
void write_allow_fast(int) {}
|
||||||
|
void write_suggest(int piece) {}
|
||||||
|
|
||||||
|
#ifdef TORRENT_DEBUG
|
||||||
|
void check_invariant() const;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
virtual void get_specific_peer_info(peer_info& p) const;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
|
||||||
|
virtual void add_headers(std::string& request
|
||||||
|
, proxy_settings const& ps, bool using_proxy) const;
|
||||||
|
|
||||||
|
// this has one entry per bittorrent request
|
||||||
|
std::deque<peer_request> m_requests;
|
||||||
|
|
||||||
|
std::string m_server_string;
|
||||||
|
http_parser m_parser;
|
||||||
|
std::string m_basic_auth;
|
||||||
|
std::string m_host;
|
||||||
|
int m_port;
|
||||||
|
std::string m_path;
|
||||||
|
|
||||||
|
std::string m_external_auth;
|
||||||
|
web_seed_entry::headers_t m_extra_headers;
|
||||||
|
|
||||||
|
// the first request will contain a little bit more data
|
||||||
|
// than subsequent ones, things that aren't critical are left
|
||||||
|
// out to save bandwidth.
|
||||||
|
bool m_first_request;
|
||||||
|
|
||||||
|
// the number of bytes into the receive buffer where
|
||||||
|
// current read cursor is.
|
||||||
|
int m_body_start;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TORRENT_WEB_CONNECTION_BASE_HPP_INCLUDED
|
||||||
|
|
|
@ -55,7 +55,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#include "libtorrent/config.hpp"
|
#include "libtorrent/config.hpp"
|
||||||
#include "libtorrent/peer_connection.hpp"
|
#include "libtorrent/web_connection_base.hpp"
|
||||||
#include "libtorrent/disk_buffer_holder.hpp"
|
#include "libtorrent/disk_buffer_holder.hpp"
|
||||||
#include "libtorrent/torrent.hpp"
|
#include "libtorrent/torrent.hpp"
|
||||||
#include "libtorrent/piece_block_progress.hpp"
|
#include "libtorrent/piece_block_progress.hpp"
|
||||||
|
@ -71,7 +71,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
class TORRENT_EXPORT web_peer_connection
|
class TORRENT_EXPORT web_peer_connection
|
||||||
: public peer_connection
|
: public web_connection_base
|
||||||
{
|
{
|
||||||
friend class invariant_access;
|
friend class invariant_access;
|
||||||
public:
|
public:
|
||||||
|
@ -85,43 +85,23 @@ namespace libtorrent
|
||||||
, boost::shared_ptr<socket_type> s
|
, boost::shared_ptr<socket_type> s
|
||||||
, tcp::endpoint const& remote
|
, tcp::endpoint const& remote
|
||||||
, std::string const& url
|
, std::string const& url
|
||||||
, policy::peer* peerinfo);
|
, policy::peer* peerinfo
|
||||||
void start();
|
, std::string const& ext_auth
|
||||||
|
, web_seed_entry::headers_t const& ext_headers);
|
||||||
|
|
||||||
virtual int type() const { return peer_connection::url_seed_connection; }
|
virtual int type() const { return peer_connection::url_seed_connection; }
|
||||||
|
|
||||||
// called from the main loop when this connection has any
|
// called from the main loop when this connection has any
|
||||||
// work to do.
|
// work to do.
|
||||||
void on_sent(error_code const& error
|
|
||||||
, std::size_t bytes_transferred);
|
|
||||||
void on_receive(error_code const& error
|
void on_receive(error_code const& error
|
||||||
, std::size_t bytes_transferred);
|
, std::size_t bytes_transferred);
|
||||||
|
|
||||||
std::string const& url() const { return m_original_url; }
|
std::string const& url() const { return m_original_url; }
|
||||||
|
|
||||||
virtual void get_specific_peer_info(peer_info& p) const;
|
virtual void get_specific_peer_info(peer_info& p) const;
|
||||||
virtual bool in_handshake() const;
|
|
||||||
virtual void disconnect(error_code const& ec, int error = 0);
|
virtual void disconnect(error_code const& ec, int error = 0);
|
||||||
|
|
||||||
// the following functions appends messages
|
|
||||||
// to the send buffer
|
|
||||||
void write_choke() {}
|
|
||||||
void write_unchoke() {}
|
|
||||||
void write_interested() {}
|
|
||||||
void write_not_interested() {}
|
|
||||||
void write_request(peer_request const& r);
|
void write_request(peer_request const& r);
|
||||||
void write_cancel(peer_request const& r) {}
|
|
||||||
void write_have(int index) {}
|
|
||||||
void write_piece(peer_request const& r, disk_buffer_holder& buffer) { TORRENT_ASSERT(false); }
|
|
||||||
void write_keepalive() {}
|
|
||||||
void on_connected();
|
|
||||||
void write_reject_request(peer_request const&) {}
|
|
||||||
void write_allow_fast(int) {}
|
|
||||||
void write_suggest(int piece) {}
|
|
||||||
|
|
||||||
#ifdef TORRENT_DEBUG
|
|
||||||
void check_invariant() const;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
||||||
|
@ -132,33 +112,17 @@ namespace libtorrent
|
||||||
// will be invalid.
|
// will be invalid.
|
||||||
boost::optional<piece_block_progress> downloading_piece_progress() const;
|
boost::optional<piece_block_progress> downloading_piece_progress() const;
|
||||||
|
|
||||||
// this has one entry per bittorrent request
|
|
||||||
std::deque<peer_request> m_requests;
|
|
||||||
// this has one entry per http-request
|
// this has one entry per http-request
|
||||||
// (might be more than the bt requests)
|
// (might be more than the bt requests)
|
||||||
std::deque<int> m_file_requests;
|
std::deque<int> m_file_requests;
|
||||||
|
|
||||||
std::string m_server_string;
|
|
||||||
http_parser m_parser;
|
|
||||||
std::string m_auth;
|
|
||||||
std::string m_host;
|
|
||||||
int m_port;
|
|
||||||
std::string m_path;
|
|
||||||
std::string m_url;
|
std::string m_url;
|
||||||
std::string m_original_url;
|
std::string m_original_url;
|
||||||
|
|
||||||
// the first request will contain a little bit more data
|
|
||||||
// than subsequent ones, things that aren't critical are left
|
|
||||||
// out to save bandwidth.
|
|
||||||
bool m_first_request;
|
|
||||||
|
|
||||||
// this is used for intermediate storage of pieces
|
// this is used for intermediate storage of pieces
|
||||||
// that are received in more than one HTTP response
|
// that are received in more than one HTTP response
|
||||||
std::vector<char> m_piece;
|
std::vector<char> m_piece;
|
||||||
|
|
||||||
// the number of bytes into the receive buffer where
|
|
||||||
// current read cursor is.
|
|
||||||
int m_body_start;
|
|
||||||
// the number of bytes received in the current HTTP
|
// the number of bytes received in the current HTTP
|
||||||
// response. used to know where in the buffer the
|
// response. used to know where in the buffer the
|
||||||
// next response starts
|
// next response starts
|
||||||
|
|
|
@ -17,6 +17,7 @@ GEOIP_SOURCES = GeoIP.c
|
||||||
endif
|
endif
|
||||||
|
|
||||||
libtorrent_rasterbar_la_SOURCES = \
|
libtorrent_rasterbar_la_SOURCES = \
|
||||||
|
web_connection_base.cpp \
|
||||||
alert.cpp \
|
alert.cpp \
|
||||||
allocator.cpp \
|
allocator.cpp \
|
||||||
assert.cpp \
|
assert.cpp \
|
||||||
|
|
|
@ -60,25 +60,17 @@ namespace libtorrent
|
||||||
, boost::shared_ptr<socket_type> s
|
, boost::shared_ptr<socket_type> s
|
||||||
, tcp::endpoint const& remote
|
, tcp::endpoint const& remote
|
||||||
, std::string const& url
|
, std::string const& url
|
||||||
, policy::peer* peerinfo)
|
, policy::peer* peerinfo
|
||||||
: peer_connection(ses, t, s, remote, peerinfo)
|
, std::string const& auth
|
||||||
|
, web_seed_entry::headers_t const& extra_headers)
|
||||||
|
: web_connection_base(ses, t, s, remote, url, peerinfo, auth, extra_headers)
|
||||||
, m_url(url)
|
, m_url(url)
|
||||||
, m_first_request(true)
|
|
||||||
, m_response_left(0)
|
|
||||||
, m_body_start(0)
|
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
if (!ses.settings().report_web_seed_downloads)
|
if (!ses.settings().report_web_seed_downloads)
|
||||||
ignore_stats(true);
|
ignore_stats(true);
|
||||||
|
|
||||||
// we want large blocks as well, so
|
|
||||||
// we can request more bytes at once
|
|
||||||
request_large_blocks(true);
|
|
||||||
prefer_whole_pieces(1);
|
|
||||||
|
|
||||||
// we only want left-over bandwidth
|
|
||||||
set_priority(1);
|
|
||||||
shared_ptr<torrent> tor = t.lock();
|
shared_ptr<torrent> tor = t.lock();
|
||||||
TORRENT_ASSERT(tor);
|
TORRENT_ASSERT(tor);
|
||||||
int blocks_per_piece = tor->torrent_file().piece_length() / tor->block_size();
|
int blocks_per_piece = tor->torrent_file().piece_length() / tor->block_size();
|
||||||
|
@ -88,31 +80,11 @@ namespace libtorrent
|
||||||
m_max_out_request_queue = ses.settings().urlseed_pipeline_size
|
m_max_out_request_queue = ses.settings().urlseed_pipeline_size
|
||||||
* blocks_per_piece;
|
* blocks_per_piece;
|
||||||
|
|
||||||
// since this is a web seed, change the timeout
|
prefer_whole_pieces(1);
|
||||||
// according to the settings.
|
|
||||||
set_timeout(ses.settings().urlseed_timeout);
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << "*** http_seed_connection\n";
|
(*m_logger) << "*** http_seed_connection\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string protocol;
|
|
||||||
error_code ec;
|
|
||||||
boost::tie(protocol, m_auth, m_host, m_port, m_path)
|
|
||||||
= parse_url_components(url, ec);
|
|
||||||
TORRENT_ASSERT(!ec);
|
|
||||||
|
|
||||||
if (!m_auth.empty())
|
|
||||||
m_auth = base64encode(m_auth);
|
|
||||||
|
|
||||||
m_server_string = "HTTP seed @ ";
|
|
||||||
m_server_string += m_host;
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_seed_connection::start()
|
|
||||||
{
|
|
||||||
set_upload_only(true);
|
|
||||||
if (is_disconnecting()) return;
|
|
||||||
peer_connection::start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_seed_connection::disconnect(error_code const& ec, int error)
|
void http_seed_connection::disconnect(error_code const& ec, int error)
|
||||||
|
@ -154,20 +126,6 @@ namespace libtorrent
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void http_seed_connection::on_connected()
|
|
||||||
{
|
|
||||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
|
||||||
TORRENT_ASSERT(t);
|
|
||||||
|
|
||||||
// this is always a seed
|
|
||||||
incoming_have_all();
|
|
||||||
|
|
||||||
// it is always possible to request pieces
|
|
||||||
incoming_unchoke();
|
|
||||||
|
|
||||||
reset_recv_buffer(t->block_size() + 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_seed_connection::write_request(peer_request const& r)
|
void http_seed_connection::write_request(peer_request const& r)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
@ -220,29 +178,7 @@ namespace libtorrent
|
||||||
}
|
}
|
||||||
|
|
||||||
request += " HTTP/1.1\r\n";
|
request += " HTTP/1.1\r\n";
|
||||||
request += "Host: ";
|
add_headers(request, ps, using_proxy);
|
||||||
request += m_host;
|
|
||||||
if (m_first_request && !m_ses.settings().user_agent.empty())
|
|
||||||
{
|
|
||||||
request += "\r\nUser-Agent: ";
|
|
||||||
request += m_ses.settings().user_agent;
|
|
||||||
}
|
|
||||||
if (!m_auth.empty())
|
|
||||||
{
|
|
||||||
request += "\r\nAuthorization: Basic ";
|
|
||||||
request += m_auth;
|
|
||||||
}
|
|
||||||
if (ps.type == proxy_settings::http_pw)
|
|
||||||
{
|
|
||||||
request += "\r\nProxy-Authorization: Basic ";
|
|
||||||
request += base64encode(ps.username + ":" + ps.password);
|
|
||||||
}
|
|
||||||
if (using_proxy)
|
|
||||||
{
|
|
||||||
request += "\r\nProxy-Connection: keep-alive";
|
|
||||||
}
|
|
||||||
if (m_first_request || using_proxy)
|
|
||||||
request += "\r\nConnection: keep-alive";
|
|
||||||
request += "\r\n\r\n";
|
request += "\r\n\r\n";
|
||||||
m_first_request = false;
|
m_first_request = false;
|
||||||
|
|
||||||
|
@ -440,43 +376,10 @@ namespace libtorrent
|
||||||
|
|
||||||
void http_seed_connection::get_specific_peer_info(peer_info& p) const
|
void http_seed_connection::get_specific_peer_info(peer_info& p) const
|
||||||
{
|
{
|
||||||
if (is_interesting()) p.flags |= peer_info::interesting;
|
web_connection_base::get_specific_peer_info(p);
|
||||||
if (is_choked()) p.flags |= peer_info::choked;
|
|
||||||
p.flags |= peer_info::local_connection;
|
p.flags |= peer_info::local_connection;
|
||||||
if (!is_connecting() && m_server_string.empty())
|
|
||||||
p.flags |= peer_info::handshake;
|
|
||||||
if (is_connecting() && !is_queued()) p.flags |= peer_info::connecting;
|
|
||||||
if (is_queued()) p.flags |= peer_info::queued;
|
|
||||||
|
|
||||||
p.client = m_server_string;
|
|
||||||
p.connection_type = peer_info::http_seed;
|
p.connection_type = peer_info::http_seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool http_seed_connection::in_handshake() const
|
|
||||||
{
|
|
||||||
return m_server_string.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void http_seed_connection::on_sent(error_code const& error
|
|
||||||
, std::size_t bytes_transferred)
|
|
||||||
{
|
|
||||||
INVARIANT_CHECK;
|
|
||||||
|
|
||||||
if (error) return;
|
|
||||||
m_statistics.sent_bytes(0, bytes_transferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TORRENT_DEBUG
|
|
||||||
void http_seed_connection::check_invariant() const
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
TORRENT_ASSERT(m_num_pieces == std::count(
|
|
||||||
m_have_piece.begin()
|
|
||||||
, m_have_piece.end()
|
|
||||||
, true));
|
|
||||||
*/ }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -593,8 +593,7 @@ namespace aux {
|
||||||
PRINT_SIZEOF(torrent_info)
|
PRINT_SIZEOF(torrent_info)
|
||||||
PRINT_OFFSETOF(torrent_info, m_files)
|
PRINT_OFFSETOF(torrent_info, m_files)
|
||||||
PRINT_OFFSETOF(torrent_info, m_orig_files)
|
PRINT_OFFSETOF(torrent_info, m_orig_files)
|
||||||
PRINT_OFFSETOF(torrent_info, m_url_seeds)
|
PRINT_OFFSETOF(torrent_info, m_web_seeds)
|
||||||
PRINT_OFFSETOF(torrent_info, m_http_seeds)
|
|
||||||
PRINT_OFFSETOF(torrent_info, m_nodes)
|
PRINT_OFFSETOF(torrent_info, m_nodes)
|
||||||
PRINT_OFFSETOF(torrent_info, m_merkle_tree)
|
PRINT_OFFSETOF(torrent_info, m_merkle_tree)
|
||||||
PRINT_OFFSETOF(torrent_info, m_info_section)
|
PRINT_OFFSETOF(torrent_info, m_info_section)
|
||||||
|
|
|
@ -893,15 +893,9 @@ namespace libtorrent
|
||||||
// ans also in the case of share mode, we need to update the priorities
|
// ans also in the case of share mode, we need to update the priorities
|
||||||
update_piece_priorities();
|
update_piece_priorities();
|
||||||
|
|
||||||
std::vector<std::string> const& url_seeds = m_torrent_file->url_seeds();
|
|
||||||
for (std::vector<std::string>::const_iterator i = url_seeds.begin()
|
|
||||||
, end(url_seeds.end()); i != end; ++i)
|
|
||||||
add_web_seed(*i, web_seed_entry::url_seed);
|
|
||||||
|
|
||||||
std::vector<std::string> const& http_seeds = m_torrent_file->http_seeds();
|
std::vector<web_seed_entry> const& web_seeds = m_torrent_file->web_seeds();
|
||||||
for (std::vector<std::string>::const_iterator i = http_seeds.begin()
|
m_web_seeds.insert(m_web_seeds.end(), web_seeds.begin(), web_seeds.end());
|
||||||
, end(http_seeds.end()); i != end; ++i)
|
|
||||||
add_web_seed(*i, web_seed_entry::http_seed);
|
|
||||||
|
|
||||||
if (m_seed_mode)
|
if (m_seed_mode)
|
||||||
{
|
{
|
||||||
|
@ -3571,12 +3565,14 @@ namespace libtorrent
|
||||||
if (web->type == web_seed_entry::url_seed)
|
if (web->type == web_seed_entry::url_seed)
|
||||||
{
|
{
|
||||||
c = new (std::nothrow) web_peer_connection(
|
c = new (std::nothrow) web_peer_connection(
|
||||||
m_ses, shared_from_this(), s, a, web->url, 0);
|
m_ses, shared_from_this(), s, a, web->url, 0, // TODO: pass in web
|
||||||
|
web->auth, web->extra_headers);
|
||||||
}
|
}
|
||||||
else if (web->type == web_seed_entry::http_seed)
|
else if (web->type == web_seed_entry::http_seed)
|
||||||
{
|
{
|
||||||
c = new (std::nothrow) http_seed_connection(
|
c = new (std::nothrow) http_seed_connection(
|
||||||
m_ses, shared_from_this(), s, a, web->url, 0);
|
m_ses, shared_from_this(), s, a, web->url, 0, // TODO: pass in web
|
||||||
|
web->auth, web->extra_headers);
|
||||||
}
|
}
|
||||||
if (!c) return;
|
if (!c) return;
|
||||||
|
|
||||||
|
|
|
@ -440,8 +440,7 @@ namespace libtorrent
|
||||||
: m_files(t.m_files)
|
: m_files(t.m_files)
|
||||||
, m_orig_files(t.m_orig_files)
|
, m_orig_files(t.m_orig_files)
|
||||||
, m_urls(t.m_urls)
|
, m_urls(t.m_urls)
|
||||||
, m_url_seeds(t.m_url_seeds)
|
, m_web_seeds(t.m_web_seeds)
|
||||||
, m_http_seeds(t.m_http_seeds)
|
|
||||||
, m_nodes(t.m_nodes)
|
, m_nodes(t.m_nodes)
|
||||||
, m_merkle_tree(t.m_merkle_tree)
|
, m_merkle_tree(t.m_merkle_tree)
|
||||||
, m_piece_hashes(t.m_piece_hashes)
|
, m_piece_hashes(t.m_piece_hashes)
|
||||||
|
@ -703,7 +702,7 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
using std::swap;
|
using std::swap;
|
||||||
m_urls.swap(ti.m_urls);
|
m_urls.swap(ti.m_urls);
|
||||||
m_url_seeds.swap(ti.m_url_seeds);
|
m_web_seeds.swap(ti.m_web_seeds);
|
||||||
m_files.swap(ti.m_files);
|
m_files.swap(ti.m_files);
|
||||||
m_orig_files.swap(ti.m_orig_files);
|
m_orig_files.swap(ti.m_orig_files);
|
||||||
m_nodes.swap(ti.m_nodes);
|
m_nodes.swap(ti.m_nodes);
|
||||||
|
@ -1065,7 +1064,8 @@ namespace libtorrent
|
||||||
lazy_entry const* url_seeds = torrent_file.dict_find("url-list");
|
lazy_entry const* url_seeds = torrent_file.dict_find("url-list");
|
||||||
if (url_seeds && url_seeds->type() == lazy_entry::string_t)
|
if (url_seeds && url_seeds->type() == lazy_entry::string_t)
|
||||||
{
|
{
|
||||||
m_url_seeds.push_back(maybe_url_encode(url_seeds->string_value()));
|
m_web_seeds.push_back(web_seed_entry(maybe_url_encode(url_seeds->string_value())
|
||||||
|
, web_seed_entry::url_seed));
|
||||||
}
|
}
|
||||||
else if (url_seeds && url_seeds->type() == lazy_entry::list_t)
|
else if (url_seeds && url_seeds->type() == lazy_entry::list_t)
|
||||||
{
|
{
|
||||||
|
@ -1073,7 +1073,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
lazy_entry const* url = url_seeds->list_at(i);
|
lazy_entry const* url = url_seeds->list_at(i);
|
||||||
if (url->type() != lazy_entry::string_t) continue;
|
if (url->type() != lazy_entry::string_t) continue;
|
||||||
m_url_seeds.push_back(maybe_url_encode(url->string_value()));
|
m_web_seeds.push_back(web_seed_entry(maybe_url_encode(url->string_value())
|
||||||
|
, web_seed_entry::url_seed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1081,7 +1082,8 @@ namespace libtorrent
|
||||||
lazy_entry const* http_seeds = torrent_file.dict_find("httpseeds");
|
lazy_entry const* http_seeds = torrent_file.dict_find("httpseeds");
|
||||||
if (http_seeds && http_seeds->type() == lazy_entry::string_t)
|
if (http_seeds && http_seeds->type() == lazy_entry::string_t)
|
||||||
{
|
{
|
||||||
m_http_seeds.push_back(maybe_url_encode(http_seeds->string_value()));
|
m_web_seeds.push_back(web_seed_entry(maybe_url_encode(http_seeds->string_value())
|
||||||
|
, web_seed_entry::http_seed));
|
||||||
}
|
}
|
||||||
else if (http_seeds && http_seeds->type() == lazy_entry::list_t)
|
else if (http_seeds && http_seeds->type() == lazy_entry::list_t)
|
||||||
{
|
{
|
||||||
|
@ -1089,7 +1091,8 @@ namespace libtorrent
|
||||||
{
|
{
|
||||||
lazy_entry const* url = http_seeds->list_at(i);
|
lazy_entry const* url = http_seeds->list_at(i);
|
||||||
if (url->type() != lazy_entry::string_t) continue;
|
if (url->type() != lazy_entry::string_t) continue;
|
||||||
m_http_seeds.push_back(maybe_url_encode(url->string_value()));
|
m_web_seeds.push_back(web_seed_entry(maybe_url_encode(url->string_value())
|
||||||
|
, web_seed_entry::http_seed));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1131,6 +1134,50 @@ namespace libtorrent
|
||||||
< boost::bind(&announce_entry::tier, _2));
|
< boost::bind(&announce_entry::tier, _2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef TORRENT_NO_DEPRECATE
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct filter_web_seed_type
|
||||||
|
{
|
||||||
|
filter_web_seed_type(web_seed_entry::type_t t_) : t(t_) {}
|
||||||
|
void operator() (web_seed_entry const& w)
|
||||||
|
{ if (w.type == t) urls.push_back(w.url); }
|
||||||
|
std::vector<std::string> urls;
|
||||||
|
web_seed_entry::type_t t;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> torrent_info::url_seeds() const
|
||||||
|
{
|
||||||
|
return std::for_each(m_web_seeds.begin(), m_web_seeds.end()
|
||||||
|
, filter_web_seed_type(web_seed_entry::url_seed)).urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<std::string> torrent_info::http_seeds() const
|
||||||
|
{
|
||||||
|
return std::for_each(m_web_seeds.begin(), m_web_seeds.end()
|
||||||
|
, filter_web_seed_type(web_seed_entry::http_seed)).urls;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // TORRENT_NO_DEPRECATE
|
||||||
|
|
||||||
|
void torrent_info::add_url_seed(std::string const& url
|
||||||
|
, std::string const& ext_auth
|
||||||
|
, web_seed_entry::headers_t const& ext_headers)
|
||||||
|
{
|
||||||
|
m_web_seeds.push_back(web_seed_entry(url, web_seed_entry::url_seed
|
||||||
|
, ext_auth, ext_headers));
|
||||||
|
}
|
||||||
|
|
||||||
|
void torrent_info::add_http_seed(std::string const& url
|
||||||
|
, std::string const& auth
|
||||||
|
, web_seed_entry::headers_t const& extra_headers)
|
||||||
|
{
|
||||||
|
m_web_seeds.push_back(web_seed_entry(url, web_seed_entry::http_seed
|
||||||
|
, auth, extra_headers));
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#if !defined TORRENT_NO_DEPRECATE && TORRENT_USE_IOSTREAM
|
#if !defined TORRENT_NO_DEPRECATE && TORRENT_USE_IOSTREAM
|
||||||
// ------- start deprecation -------
|
// ------- start deprecation -------
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,200 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2003, Arvid Norberg
|
||||||
|
All rights reserved.
|
||||||
|
|
||||||
|
Redistribution and use in source and binary forms, with or without
|
||||||
|
modification, are permitted provided that the following conditions
|
||||||
|
are met:
|
||||||
|
|
||||||
|
* Redistributions of source code must retain the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer.
|
||||||
|
* Redistributions in binary form must reproduce the above copyright
|
||||||
|
notice, this list of conditions and the following disclaimer in
|
||||||
|
the documentation and/or other materials provided with the distribution.
|
||||||
|
* Neither the name of the author nor the names of its
|
||||||
|
contributors may be used to endorse or promote products derived
|
||||||
|
from this software without specific prior written permission.
|
||||||
|
|
||||||
|
THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
||||||
|
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||||
|
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
||||||
|
LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
||||||
|
CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
||||||
|
SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
||||||
|
CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
||||||
|
ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libtorrent/pch.hpp"
|
||||||
|
|
||||||
|
#include <vector>
|
||||||
|
#include <limits>
|
||||||
|
#include <boost/bind.hpp>
|
||||||
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include "libtorrent/web_connection_base.hpp"
|
||||||
|
#include "libtorrent/session.hpp"
|
||||||
|
#include "libtorrent/identify_client.hpp"
|
||||||
|
#include "libtorrent/entry.hpp"
|
||||||
|
#include "libtorrent/bencode.hpp"
|
||||||
|
#include "libtorrent/alert_types.hpp"
|
||||||
|
#include "libtorrent/invariant_check.hpp"
|
||||||
|
#include "libtorrent/io.hpp"
|
||||||
|
#include "libtorrent/version.hpp"
|
||||||
|
#include "libtorrent/aux_/session_impl.hpp"
|
||||||
|
#include "libtorrent/parse_url.hpp"
|
||||||
|
#include "libtorrent/peer_info.hpp"
|
||||||
|
|
||||||
|
using boost::shared_ptr;
|
||||||
|
using libtorrent::aux::session_impl;
|
||||||
|
|
||||||
|
namespace libtorrent
|
||||||
|
{
|
||||||
|
web_connection_base::web_connection_base(
|
||||||
|
session_impl& ses
|
||||||
|
, boost::weak_ptr<torrent> t
|
||||||
|
, boost::shared_ptr<socket_type> s
|
||||||
|
, tcp::endpoint const& remote
|
||||||
|
, std::string const& url
|
||||||
|
, policy::peer* peerinfo
|
||||||
|
, std::string const& auth
|
||||||
|
, web_seed_entry::headers_t const& extra_headers)
|
||||||
|
: peer_connection(ses, t, s, remote, peerinfo)
|
||||||
|
, m_first_request(true)
|
||||||
|
, m_external_auth(auth)
|
||||||
|
, m_extra_headers(extra_headers)
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
// we want large blocks as well, so
|
||||||
|
// we can request more bytes at once
|
||||||
|
request_large_blocks(true);
|
||||||
|
|
||||||
|
// we only want left-over bandwidth
|
||||||
|
set_priority(1);
|
||||||
|
|
||||||
|
// since this is a web seed, change the timeout
|
||||||
|
// according to the settings.
|
||||||
|
set_timeout(ses.settings().urlseed_timeout);
|
||||||
|
|
||||||
|
std::string protocol;
|
||||||
|
error_code ec;
|
||||||
|
boost::tie(protocol, m_basic_auth, m_host, m_port, m_path)
|
||||||
|
= parse_url_components(url, ec);
|
||||||
|
TORRENT_ASSERT(!ec);
|
||||||
|
|
||||||
|
if (!m_basic_auth.empty())
|
||||||
|
m_basic_auth = base64encode(m_basic_auth);
|
||||||
|
|
||||||
|
m_server_string = "URL seed @ ";
|
||||||
|
m_server_string += m_host;
|
||||||
|
}
|
||||||
|
|
||||||
|
void web_connection_base::start()
|
||||||
|
{
|
||||||
|
set_upload_only(true);
|
||||||
|
if (is_disconnecting()) return;
|
||||||
|
peer_connection::start();
|
||||||
|
}
|
||||||
|
|
||||||
|
web_connection_base::~web_connection_base()
|
||||||
|
{}
|
||||||
|
|
||||||
|
void web_connection_base::on_connected()
|
||||||
|
{
|
||||||
|
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||||
|
TORRENT_ASSERT(t);
|
||||||
|
|
||||||
|
// this is always a seed
|
||||||
|
incoming_have_all();
|
||||||
|
|
||||||
|
// it is always possible to request pieces
|
||||||
|
incoming_unchoke();
|
||||||
|
|
||||||
|
reset_recv_buffer(t->block_size() + 1024);
|
||||||
|
}
|
||||||
|
|
||||||
|
void web_connection_base::add_headers(std::string& request
|
||||||
|
, proxy_settings const& ps, bool using_proxy) const
|
||||||
|
{
|
||||||
|
request += "Host: ";
|
||||||
|
request += m_host;
|
||||||
|
if (m_first_request) {
|
||||||
|
request += "\r\nUser-Agent: ";
|
||||||
|
request += m_ses.settings().user_agent;
|
||||||
|
}
|
||||||
|
if (!m_external_auth.empty()) {
|
||||||
|
request += "\r\nAuthorization: ";
|
||||||
|
request += m_external_auth;
|
||||||
|
} else if (!m_basic_auth.empty()) {
|
||||||
|
request += "\r\nAuthorization: Basic ";
|
||||||
|
request += m_basic_auth;
|
||||||
|
}
|
||||||
|
if (ps.type == proxy_settings::http_pw) {
|
||||||
|
request += "\r\nProxy-Authorization: Basic ";
|
||||||
|
request += base64encode(ps.username + ":" + ps.password);
|
||||||
|
}
|
||||||
|
for (web_seed_entry::headers_t::const_iterator it = m_extra_headers.begin();
|
||||||
|
it != m_extra_headers.end(); ++it) {
|
||||||
|
request += "\r\n";
|
||||||
|
request += it->first;
|
||||||
|
request += ": ";
|
||||||
|
request += it->second;
|
||||||
|
}
|
||||||
|
if (using_proxy) {
|
||||||
|
request += "\r\nProxy-Connection: keep-alive";
|
||||||
|
}
|
||||||
|
if (m_first_request || using_proxy) {
|
||||||
|
request += "\r\nConnection: keep-alive";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// --------------------------
|
||||||
|
// RECEIVE DATA
|
||||||
|
// --------------------------
|
||||||
|
|
||||||
|
void web_connection_base::get_specific_peer_info(peer_info& p) const
|
||||||
|
{
|
||||||
|
if (is_interesting()) p.flags |= peer_info::interesting;
|
||||||
|
if (is_choked()) p.flags |= peer_info::choked;
|
||||||
|
if (!is_connecting() && m_server_string.empty())
|
||||||
|
p.flags |= peer_info::handshake;
|
||||||
|
if (is_connecting() && !is_queued()) p.flags |= peer_info::connecting;
|
||||||
|
if (is_queued()) p.flags |= peer_info::queued;
|
||||||
|
|
||||||
|
p.client = m_server_string;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool web_connection_base::in_handshake() const
|
||||||
|
{
|
||||||
|
return m_server_string.empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void web_connection_base::on_sent(error_code const& error
|
||||||
|
, std::size_t bytes_transferred)
|
||||||
|
{
|
||||||
|
INVARIANT_CHECK;
|
||||||
|
|
||||||
|
if (error) return;
|
||||||
|
m_statistics.sent_bytes(0, bytes_transferred);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#ifdef TORRENT_DEBUG
|
||||||
|
void web_connection_base::check_invariant() const
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
TORRENT_ASSERT(m_num_pieces == std::count(
|
||||||
|
m_have_piece.begin()
|
||||||
|
, m_have_piece.end()
|
||||||
|
, true));
|
||||||
|
*/ }
|
||||||
|
#endif
|
||||||
|
|
||||||
|
}
|
||||||
|
|
|
@ -61,10 +61,11 @@ namespace libtorrent
|
||||||
, boost::shared_ptr<socket_type> s
|
, boost::shared_ptr<socket_type> s
|
||||||
, tcp::endpoint const& remote
|
, tcp::endpoint const& remote
|
||||||
, std::string const& url
|
, std::string const& url
|
||||||
, policy::peer* peerinfo)
|
, policy::peer* peerinfo
|
||||||
: peer_connection(ses, t, s, remote, peerinfo)
|
, std::string const& auth
|
||||||
|
, web_seed_entry::headers_t const& extra_headers)
|
||||||
|
: web_connection_base(ses, t, s, remote, url, peerinfo, auth, extra_headers)
|
||||||
, m_url(url)
|
, m_url(url)
|
||||||
, m_first_request(true)
|
|
||||||
, m_range_pos(0)
|
, m_range_pos(0)
|
||||||
, m_block_pos(0)
|
, m_block_pos(0)
|
||||||
{
|
{
|
||||||
|
@ -73,12 +74,6 @@ namespace libtorrent
|
||||||
if (!ses.settings().report_web_seed_downloads)
|
if (!ses.settings().report_web_seed_downloads)
|
||||||
ignore_stats(true);
|
ignore_stats(true);
|
||||||
|
|
||||||
// we want large blocks as well, so
|
|
||||||
// we can request more bytes at once
|
|
||||||
request_large_blocks(true);
|
|
||||||
|
|
||||||
// we only want left-over bandwidth
|
|
||||||
set_priority(1);
|
|
||||||
shared_ptr<torrent> tor = t.lock();
|
shared_ptr<torrent> tor = t.lock();
|
||||||
TORRENT_ASSERT(tor);
|
TORRENT_ASSERT(tor);
|
||||||
int blocks_per_piece = tor->torrent_file().piece_length() / tor->block_size();
|
int blocks_per_piece = tor->torrent_file().piece_length() / tor->block_size();
|
||||||
|
@ -87,36 +82,9 @@ namespace libtorrent
|
||||||
// from web seeds
|
// from web seeds
|
||||||
prefer_whole_pieces((1024 * 1024) / tor->torrent_file().piece_length());
|
prefer_whole_pieces((1024 * 1024) / tor->torrent_file().piece_length());
|
||||||
|
|
||||||
// multiply with the blocks per piece since that many requests are
|
|
||||||
// merged into one http request
|
|
||||||
m_max_out_request_queue = ses.settings().urlseed_pipeline_size
|
|
||||||
* blocks_per_piece;
|
|
||||||
|
|
||||||
// since this is a web seed, change the timeout
|
|
||||||
// according to the settings.
|
|
||||||
set_timeout(ses.settings().urlseed_timeout);
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
(*m_logger) << "*** web_peer_connection " << url << "\n";
|
(*m_logger) << "*** web_peer_connection " << url << "\n";
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
std::string protocol;
|
|
||||||
error_code ec;
|
|
||||||
boost::tie(protocol, m_auth, m_host, m_port, m_path)
|
|
||||||
= parse_url_components(url, ec);
|
|
||||||
TORRENT_ASSERT(!ec);
|
|
||||||
|
|
||||||
if (!m_auth.empty())
|
|
||||||
m_auth = base64encode(m_auth);
|
|
||||||
|
|
||||||
m_server_string = "URL seed @ ";
|
|
||||||
m_server_string += m_host;
|
|
||||||
}
|
|
||||||
|
|
||||||
void web_peer_connection::start()
|
|
||||||
{
|
|
||||||
set_upload_only(true);
|
|
||||||
if (is_disconnecting()) return;
|
|
||||||
peer_connection::start();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void web_peer_connection::disconnect(error_code const& ec, int error)
|
void web_peer_connection::disconnect(error_code const& ec, int error)
|
||||||
|
@ -127,10 +95,7 @@ namespace libtorrent
|
||||||
t->add_redundant_bytes(m_block_pos);
|
t->add_redundant_bytes(m_block_pos);
|
||||||
|
|
||||||
peer_connection::disconnect(ec, error);
|
peer_connection::disconnect(ec, error);
|
||||||
if (t)
|
if (t) t->disconnect_web_seed(this);
|
||||||
{
|
|
||||||
t->disconnect_web_seed(this);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<piece_block_progress>
|
boost::optional<piece_block_progress>
|
||||||
|
@ -150,6 +115,8 @@ namespace libtorrent
|
||||||
ret.block_index = (m_requests.front().start + m_block_pos - 1) / t->block_size();
|
ret.block_index = (m_requests.front().start + m_block_pos - 1) / t->block_size();
|
||||||
else
|
else
|
||||||
ret.block_index = (m_requests.front().start + m_block_pos) / t->block_size();
|
ret.block_index = (m_requests.front().start + m_block_pos) / t->block_size();
|
||||||
|
TORRENT_ASSERT(ret.block_index < piece_block::invalid.block_index);
|
||||||
|
TORRENT_ASSERT(ret.piece_index < piece_block::invalid.piece_index);
|
||||||
|
|
||||||
ret.full_block_bytes = t->block_size();
|
ret.full_block_bytes = t->block_size();
|
||||||
const int last_piece = t->torrent_file().num_pieces() - 1;
|
const int last_piece = t->torrent_file().num_pieces() - 1;
|
||||||
|
@ -159,20 +126,6 @@ namespace libtorrent
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
void web_peer_connection::on_connected()
|
|
||||||
{
|
|
||||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
|
||||||
TORRENT_ASSERT(t);
|
|
||||||
|
|
||||||
// this is always a seed
|
|
||||||
incoming_have_all();
|
|
||||||
|
|
||||||
// it is always possible to request pieces
|
|
||||||
incoming_unchoke();
|
|
||||||
|
|
||||||
reset_recv_buffer(t->block_size() + 1024);
|
|
||||||
}
|
|
||||||
|
|
||||||
void web_peer_connection::write_request(peer_request const& r)
|
void web_peer_connection::write_request(peer_request const& r)
|
||||||
{
|
{
|
||||||
INVARIANT_CHECK;
|
INVARIANT_CHECK;
|
||||||
|
@ -229,33 +182,11 @@ namespace libtorrent
|
||||||
// assumed to be encoded in the torrent file
|
// assumed to be encoded in the torrent file
|
||||||
request += using_proxy ? m_url : m_path;
|
request += using_proxy ? m_url : m_path;
|
||||||
request += " HTTP/1.1\r\n";
|
request += " HTTP/1.1\r\n";
|
||||||
request += "Host: ";
|
add_headers(request, ps, using_proxy);
|
||||||
request += m_host;
|
|
||||||
if (m_first_request && !m_ses.settings().user_agent.empty())
|
|
||||||
{
|
|
||||||
request += "\r\nUser-Agent: ";
|
|
||||||
request += m_ses.settings().user_agent;
|
|
||||||
}
|
|
||||||
if (!m_auth.empty())
|
|
||||||
{
|
|
||||||
request += "\r\nAuthorization: Basic ";
|
|
||||||
request += m_auth;
|
|
||||||
}
|
|
||||||
if (ps.type == proxy_settings::http_pw)
|
|
||||||
{
|
|
||||||
request += "\r\nProxy-Authorization: Basic ";
|
|
||||||
request += base64encode(ps.username + ":" + ps.password);
|
|
||||||
}
|
|
||||||
if (using_proxy)
|
|
||||||
{
|
|
||||||
request += "\r\nProxy-Connection: keep-alive";
|
|
||||||
}
|
|
||||||
request += "\r\nRange: bytes=";
|
request += "\r\nRange: bytes=";
|
||||||
request += to_string(size_type(r.piece) * info.piece_length() + r.start).elems;
|
request += to_string(size_type(r.piece) * info.piece_length() + r.start).elems;
|
||||||
request += "-";
|
request += "-";
|
||||||
request += to_string(size_type(r.piece) * info.piece_length() + r.start + r.length - 1).elems;
|
request += to_string(size_type(r.piece) * info.piece_length() + r.start + r.length - 1).elems;
|
||||||
if (m_first_request || using_proxy)
|
|
||||||
request += "\r\nConnection: keep-alive";
|
|
||||||
request += "\r\n\r\n";
|
request += "\r\n\r\n";
|
||||||
m_first_request = false;
|
m_first_request = false;
|
||||||
m_file_requests.push_back(0);
|
m_file_requests.push_back(0);
|
||||||
|
@ -290,34 +221,13 @@ namespace libtorrent
|
||||||
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: ";
|
add_headers(request, ps, using_proxy);
|
||||||
request += m_host;
|
|
||||||
if (m_first_request && !m_ses.settings().user_agent.empty())
|
|
||||||
{
|
|
||||||
request += "\r\nUser-Agent: ";
|
|
||||||
request += m_ses.settings().user_agent;
|
|
||||||
}
|
|
||||||
if (!m_auth.empty())
|
|
||||||
{
|
|
||||||
request += "\r\nAuthorization: Basic ";
|
|
||||||
request += m_auth;
|
|
||||||
}
|
|
||||||
if (ps.type == proxy_settings::http_pw)
|
|
||||||
{
|
|
||||||
request += "\r\nProxy-Authorization: Basic ";
|
|
||||||
request += base64encode(ps.username + ":" + ps.password);
|
|
||||||
}
|
|
||||||
if (using_proxy)
|
|
||||||
{
|
|
||||||
request += "\r\nProxy-Connection: keep-alive";
|
|
||||||
}
|
|
||||||
request += "\r\nRange: bytes=";
|
request += "\r\nRange: bytes=";
|
||||||
request += to_string(f.offset).elems;
|
request += to_string(f.offset).elems;
|
||||||
request += "-";
|
request += "-";
|
||||||
request += to_string(f.offset + f.size - 1).elems;
|
request += to_string(f.offset + f.size - 1).elems;
|
||||||
if (m_first_request || using_proxy)
|
|
||||||
request += "\r\nConnection: keep-alive";
|
|
||||||
request += "\r\n\r\n";
|
request += "\r\n\r\n";
|
||||||
|
fprintf(stderr, "REQ: %s\n", request.c_str());
|
||||||
m_first_request = false;
|
m_first_request = false;
|
||||||
TORRENT_ASSERT(f.file_index >= 0);
|
TORRENT_ASSERT(f.file_index >= 0);
|
||||||
m_file_requests.push_back(f.file_index);
|
m_file_requests.push_back(f.file_index);
|
||||||
|
@ -713,45 +623,10 @@ namespace libtorrent
|
||||||
|
|
||||||
void web_peer_connection::get_specific_peer_info(peer_info& p) const
|
void web_peer_connection::get_specific_peer_info(peer_info& p) const
|
||||||
{
|
{
|
||||||
if (is_interesting()) p.flags |= peer_info::interesting;
|
web_connection_base::get_specific_peer_info(p);
|
||||||
if (is_choked()) p.flags |= peer_info::choked;
|
p.flags |= peer_info::local_connection;
|
||||||
if (is_peer_interested()) p.flags |= peer_info::remote_interested;
|
|
||||||
if (has_peer_choked()) p.flags |= peer_info::remote_choked;
|
|
||||||
if (is_local()) p.flags |= peer_info::local_connection;
|
|
||||||
if (!is_connecting() && m_server_string.empty())
|
|
||||||
p.flags |= peer_info::handshake;
|
|
||||||
if (is_connecting() && !is_queued()) p.flags |= peer_info::connecting;
|
|
||||||
if (is_queued()) p.flags |= peer_info::queued;
|
|
||||||
|
|
||||||
p.client = m_server_string;
|
|
||||||
p.connection_type = peer_info::web_seed;
|
p.connection_type = peer_info::web_seed;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool web_peer_connection::in_handshake() const
|
|
||||||
{
|
|
||||||
return m_server_string.empty();
|
|
||||||
}
|
|
||||||
|
|
||||||
void web_peer_connection::on_sent(error_code const& error
|
|
||||||
, std::size_t bytes_transferred)
|
|
||||||
{
|
|
||||||
INVARIANT_CHECK;
|
|
||||||
|
|
||||||
if (error) return;
|
|
||||||
m_statistics.sent_bytes(0, bytes_transferred);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef TORRENT_DEBUG
|
|
||||||
void web_peer_connection::check_invariant() const
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
TORRENT_ASSERT(m_num_pieces == std::count(
|
|
||||||
m_have_piece.begin()
|
|
||||||
, m_have_piece.end()
|
|
||||||
, true));
|
|
||||||
*/ }
|
|
||||||
#endif
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue