forked from premiere/premiere-libtorrent
merged web seed redirect fix from RC_1_0
This commit is contained in:
parent
5b73194a0d
commit
34440224fc
|
@ -27,6 +27,7 @@
|
||||||
* almost completely changed the storage interface (for custom storage)
|
* almost completely changed the storage interface (for custom storage)
|
||||||
* added support for hashing pieces in multiple threads
|
* added support for hashing pieces in multiple threads
|
||||||
|
|
||||||
|
* fixed crash when web seeds redirect
|
||||||
* fix compiler warnings
|
* fix compiler warnings
|
||||||
|
|
||||||
1.0 release
|
1.0 release
|
||||||
|
|
|
@ -62,6 +62,9 @@ namespace libtorrent
|
||||||
// return true if the status code is a redirect
|
// return true if the status code is a redirect
|
||||||
bool is_redirect(int http_status);
|
bool is_redirect(int http_status);
|
||||||
|
|
||||||
|
std::string resolve_redirect_location(std::string referrer
|
||||||
|
, std::string location);
|
||||||
|
|
||||||
class TORRENT_EXTRA_EXPORT http_parser
|
class TORRENT_EXTRA_EXPORT http_parser
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
|
@ -120,7 +120,7 @@ namespace libtorrent
|
||||||
|
|
||||||
std::string m_url;
|
std::string m_url;
|
||||||
|
|
||||||
web_seed_entry& m_web;
|
web_seed_entry* m_web;
|
||||||
|
|
||||||
// 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
|
||||||
|
|
|
@ -819,7 +819,7 @@ void http_connection::on_read(error_code const& e
|
||||||
{
|
{
|
||||||
int code = m_parser.status_code();
|
int code = m_parser.status_code();
|
||||||
|
|
||||||
if (code >= 300 && code < 400)
|
if (is_redirect(code))
|
||||||
{
|
{
|
||||||
// attempt a redirect
|
// attempt a redirect
|
||||||
std::string const& location = m_parser.header("location");
|
std::string const& location = m_parser.header("location");
|
||||||
|
@ -837,39 +837,14 @@ void http_connection::on_read(error_code const& e
|
||||||
// in its handler. For now, just kill the connection.
|
// in its handler. For now, just kill the connection.
|
||||||
// async_shutdown(m_sock, shared_from_this());
|
// async_shutdown(m_sock, shared_from_this());
|
||||||
m_sock.close(ec);
|
m_sock.close(ec);
|
||||||
using boost::tuples::ignore;
|
|
||||||
boost::tie(ignore, ignore, ignore, ignore, ignore)
|
|
||||||
= parse_url_components(location, ec);
|
|
||||||
if (!ec)
|
|
||||||
{
|
|
||||||
get(location, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1
|
|
||||||
, m_user_agent, m_bind_addr, m_resolve_flags
|
|
||||||
#if TORRENT_USE_I2P
|
|
||||||
, m_i2p_conn
|
|
||||||
#endif
|
|
||||||
);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// some broken web servers send out relative paths
|
|
||||||
// in the location header.
|
|
||||||
std::string url = m_url;
|
|
||||||
// remove the leaf filename
|
|
||||||
std::size_t i = url.find_last_of('/');
|
|
||||||
if (i != std::string::npos)
|
|
||||||
url.resize(i);
|
|
||||||
if ((url.empty() || url[url.size()-1] != '/')
|
|
||||||
&& (location.empty() || location[0] != '/'))
|
|
||||||
url += '/';
|
|
||||||
url += location;
|
|
||||||
|
|
||||||
get(url, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1
|
std::string url = resolve_redirect_location(m_url, location);
|
||||||
, m_user_agent, m_bind_addr, m_resolve_flags
|
get(url, m_completion_timeout, m_priority, &m_proxy, m_redirects - 1
|
||||||
|
, m_user_agent, m_bind_addr, m_resolve_flags
|
||||||
#if TORRENT_USE_I2P
|
#if TORRENT_USE_I2P
|
||||||
, m_i2p_conn
|
, m_i2p_conn
|
||||||
#endif
|
#endif
|
||||||
);
|
);
|
||||||
}
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -38,6 +38,7 @@ POSSIBILITY OF SUCH DAMAGE.
|
||||||
#include "libtorrent/http_parser.hpp"
|
#include "libtorrent/http_parser.hpp"
|
||||||
#include "libtorrent/assert.hpp"
|
#include "libtorrent/assert.hpp"
|
||||||
#include "libtorrent/escape_string.hpp"
|
#include "libtorrent/escape_string.hpp"
|
||||||
|
#include "libtorrent/parse_url.hpp" // for parse_url_components
|
||||||
|
|
||||||
using namespace libtorrent;
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
@ -58,6 +59,54 @@ namespace libtorrent
|
||||||
&& http_status < 400;
|
&& http_status < 400;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string resolve_redirect_location(std::string referrer
|
||||||
|
, std::string location)
|
||||||
|
{
|
||||||
|
if (location.empty()) return referrer;
|
||||||
|
|
||||||
|
error_code ec;
|
||||||
|
using boost::tuples::ignore;
|
||||||
|
boost::tie(ignore, ignore, ignore, ignore, ignore)
|
||||||
|
= parse_url_components(location, ec);
|
||||||
|
|
||||||
|
// if location is a full URL, just return it
|
||||||
|
if (!ec) return location;
|
||||||
|
|
||||||
|
// otherwise it's likely to be just the path, or a relative path
|
||||||
|
std::string url = referrer;
|
||||||
|
|
||||||
|
if (location[0] == '/')
|
||||||
|
{
|
||||||
|
// it's an absolute path. replace the path component of
|
||||||
|
// referrer with location
|
||||||
|
|
||||||
|
// 8 is to skip the ur;l scheme://. We want the first slash
|
||||||
|
// that's part of the path.
|
||||||
|
std::size_t i = url.find_first_of('/', 8);
|
||||||
|
if (i == std::string::npos)
|
||||||
|
return location;
|
||||||
|
url.resize(i);
|
||||||
|
url += location;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// some web servers send out relative paths
|
||||||
|
// in the location header.
|
||||||
|
// remove the leaf filename
|
||||||
|
std::size_t i = url.find_last_of('/');
|
||||||
|
if (i == std::string::npos)
|
||||||
|
return location;
|
||||||
|
|
||||||
|
url.resize(i);
|
||||||
|
|
||||||
|
if ((url.empty() || url[url.size()-1] != '/')
|
||||||
|
&& (location.empty() || location[0] != '/'))
|
||||||
|
url += '/';
|
||||||
|
url += location;
|
||||||
|
}
|
||||||
|
return url;
|
||||||
|
}
|
||||||
|
|
||||||
http_parser::~http_parser() {}
|
http_parser::~http_parser() {}
|
||||||
|
|
||||||
http_parser::http_parser(int flags)
|
http_parser::http_parser(int flags)
|
||||||
|
|
|
@ -70,7 +70,7 @@ web_peer_connection::web_peer_connection(
|
||||||
, web_seed_entry& web)
|
, web_seed_entry& web)
|
||||||
: web_connection_base(ses, sett, allocator, disk_thread, t, s, web)
|
: web_connection_base(ses, sett, allocator, disk_thread, t, s, web)
|
||||||
, m_url(web.url)
|
, m_url(web.url)
|
||||||
, m_web(web)
|
, m_web(&web)
|
||||||
, m_received_body(0)
|
, m_received_body(0)
|
||||||
, m_range_pos(0)
|
, m_range_pos(0)
|
||||||
, m_chunk_pos(0)
|
, m_chunk_pos(0)
|
||||||
|
@ -111,11 +111,11 @@ web_peer_connection::web_peer_connection(
|
||||||
void web_peer_connection::on_connected()
|
void web_peer_connection::on_connected()
|
||||||
{
|
{
|
||||||
incoming_have_all();
|
incoming_have_all();
|
||||||
if (m_web.restart_request.piece != -1)
|
if (m_web->restart_request.piece != -1)
|
||||||
{
|
{
|
||||||
// increase the chances of requesting the block
|
// increase the chances of requesting the block
|
||||||
// we have partial data for already, to finish it
|
// we have partial data for already, to finish it
|
||||||
incoming_suggest(m_web.restart_request.piece);
|
incoming_suggest(m_web->restart_request.piece);
|
||||||
}
|
}
|
||||||
web_connection_base::on_connected();
|
web_connection_base::on_connected();
|
||||||
}
|
}
|
||||||
|
@ -127,7 +127,7 @@ void web_peer_connection::disconnect(error_code const& ec, peer_connection_inter
|
||||||
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
boost::shared_ptr<torrent> t = associated_torrent().lock();
|
||||||
|
|
||||||
if (!m_requests.empty() && !m_file_requests.empty()
|
if (!m_requests.empty() && !m_file_requests.empty()
|
||||||
&& !m_piece.empty())
|
&& !m_piece.empty() && m_web)
|
||||||
{
|
{
|
||||||
#if 0
|
#if 0
|
||||||
std::cerr << this << " SAVE-RESTART-DATA: data: " << m_piece.size()
|
std::cerr << this << " SAVE-RESTART-DATA: data: " << m_piece.size()
|
||||||
|
@ -135,15 +135,15 @@ void web_peer_connection::disconnect(error_code const& ec, peer_connection_inter
|
||||||
<< " off: " << m_requests.front().start
|
<< " off: " << m_requests.front().start
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
#endif
|
#endif
|
||||||
m_web.restart_request = m_requests.front();
|
m_web->restart_request = m_requests.front();
|
||||||
if (!m_web.restart_piece.empty())
|
if (!m_web->restart_piece.empty())
|
||||||
{
|
{
|
||||||
// we're about to replace a different restart piece
|
// we're about to replace a different restart piece
|
||||||
// buffer. So it was wasted download
|
// buffer. So it was wasted download
|
||||||
if (t) t->add_redundant_bytes(m_web.restart_piece.size()
|
if (t) t->add_redundant_bytes(m_web->restart_piece.size()
|
||||||
, torrent::piece_closing);
|
, torrent::piece_closing);
|
||||||
}
|
}
|
||||||
m_web.restart_piece.swap(m_piece);
|
m_web->restart_piece.swap(m_piece);
|
||||||
|
|
||||||
// we have to do this to not count this data as redundant. The
|
// we have to do this to not count this data as redundant. The
|
||||||
// upper layer will call downloading_piece_progress and assume
|
// upper layer will call downloading_piece_progress and assume
|
||||||
|
@ -152,7 +152,7 @@ void web_peer_connection::disconnect(error_code const& ec, peer_connection_inter
|
||||||
m_block_pos = 0;
|
m_block_pos = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!m_web.supports_keepalive && error == 0)
|
if (m_web && !m_web->supports_keepalive && error == 0)
|
||||||
{
|
{
|
||||||
// if the web server doesn't support keepalive and we were
|
// if the web server doesn't support keepalive and we were
|
||||||
// disconnected as a graceful EOF, reconnect right away
|
// disconnected as a graceful EOF, reconnect right away
|
||||||
|
@ -250,9 +250,9 @@ void web_peer_connection::write_request(peer_request const& r)
|
||||||
pr.piece = r.piece + request_offset / piece_size;
|
pr.piece = r.piece + request_offset / piece_size;
|
||||||
m_requests.push_back(pr);
|
m_requests.push_back(pr);
|
||||||
|
|
||||||
if (m_web.restart_request == m_requests.front())
|
if (m_web->restart_request == m_requests.front())
|
||||||
{
|
{
|
||||||
m_piece.swap(m_web.restart_piece);
|
m_piece.swap(m_web->restart_piece);
|
||||||
m_block_pos += m_piece.size();
|
m_block_pos += m_piece.size();
|
||||||
peer_request& front = m_requests.front();
|
peer_request& front = m_requests.front();
|
||||||
TORRENT_ASSERT(front.length > int(m_piece.size()));
|
TORRENT_ASSERT(front.length > int(m_piece.size()));
|
||||||
|
@ -270,7 +270,7 @@ void web_peer_connection::write_request(peer_request const& r)
|
||||||
// just to keep the accounting straight for the upper layer.
|
// just to keep the accounting straight for the upper layer.
|
||||||
// it doesn't know we just re-wrote the request
|
// it doesn't know we just re-wrote the request
|
||||||
incoming_piece_fragment(m_piece.size());
|
incoming_piece_fragment(m_piece.size());
|
||||||
m_web.restart_request.piece = -1;
|
m_web->restart_request.piece = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
|
@ -576,7 +576,7 @@ void web_peer_connection::on_receive(error_code const& error
|
||||||
{
|
{
|
||||||
incoming_choke();
|
incoming_choke();
|
||||||
if (m_num_responses == 1)
|
if (m_num_responses == 1)
|
||||||
m_web.supports_keepalive = false;
|
m_web->supports_keepalive = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
|
@ -623,6 +623,7 @@ void web_peer_connection::on_receive(error_code const& error
|
||||||
{
|
{
|
||||||
// we should not try this server again.
|
// we should not try this server again.
|
||||||
t->remove_web_seed(this, errors::missing_location, op_bittorrent, 2);
|
t->remove_web_seed(this, errors::missing_location, op_bittorrent, 2);
|
||||||
|
m_web = NULL;
|
||||||
TORRENT_ASSERT(is_disconnecting());
|
TORRENT_ASSERT(is_disconnecting());
|
||||||
#ifdef TORRENT_DEBUG
|
#ifdef TORRENT_DEBUG
|
||||||
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
||||||
|
@ -660,6 +661,7 @@ void web_peer_connection::on_receive(error_code const& error
|
||||||
if (i == std::string::npos)
|
if (i == std::string::npos)
|
||||||
{
|
{
|
||||||
t->remove_web_seed(this, errors::invalid_redirection, op_bittorrent, 2);
|
t->remove_web_seed(this, errors::invalid_redirection, op_bittorrent, 2);
|
||||||
|
m_web = NULL;
|
||||||
TORRENT_ASSERT(is_disconnecting());
|
TORRENT_ASSERT(is_disconnecting());
|
||||||
#ifdef TORRENT_DEBUG
|
#ifdef TORRENT_DEBUG
|
||||||
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
||||||
|
@ -670,11 +672,17 @@ void web_peer_connection::on_receive(error_code const& error
|
||||||
}
|
}
|
||||||
location.resize(i);
|
location.resize(i);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
location = resolve_redirect_location(m_url, location);
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef TORRENT_VERBOSE_LOGGING
|
#ifdef TORRENT_VERBOSE_LOGGING
|
||||||
peer_log("*** LOCATION: %s", location.c_str());
|
peer_log("*** LOCATION: %s", location.c_str());
|
||||||
#endif
|
#endif
|
||||||
t->add_web_seed(location, web_seed_entry::url_seed, m_external_auth, m_extra_headers);
|
t->add_web_seed(location, web_seed_entry::url_seed, m_external_auth, m_extra_headers);
|
||||||
t->remove_web_seed(this, errors::redirecting, op_bittorrent, 2);
|
t->remove_web_seed(this, errors::redirecting, op_bittorrent, 2);
|
||||||
|
m_web = NULL;
|
||||||
TORRENT_ASSERT(is_disconnecting());
|
TORRENT_ASSERT(is_disconnecting());
|
||||||
#ifdef TORRENT_DEBUG
|
#ifdef TORRENT_DEBUG
|
||||||
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
||||||
|
@ -722,6 +730,7 @@ void web_peer_connection::on_receive(error_code const& error
|
||||||
received_bytes(0, bytes_transferred);
|
received_bytes(0, bytes_transferred);
|
||||||
// we should not try this server again.
|
// we should not try this server again.
|
||||||
t->remove_web_seed(this, errors::invalid_range, op_bittorrent);
|
t->remove_web_seed(this, errors::invalid_range, op_bittorrent);
|
||||||
|
m_web = NULL;
|
||||||
TORRENT_ASSERT(is_disconnecting());
|
TORRENT_ASSERT(is_disconnecting());
|
||||||
#ifdef TORRENT_DEBUG
|
#ifdef TORRENT_DEBUG
|
||||||
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
||||||
|
@ -742,6 +751,7 @@ void web_peer_connection::on_receive(error_code const& error
|
||||||
received_bytes(0, bytes_transferred);
|
received_bytes(0, bytes_transferred);
|
||||||
// we should not try this server again.
|
// we should not try this server again.
|
||||||
t->remove_web_seed(this, errors::no_content_length, op_bittorrent, 2);
|
t->remove_web_seed(this, errors::no_content_length, op_bittorrent, 2);
|
||||||
|
m_web = NULL;
|
||||||
TORRENT_ASSERT(is_disconnecting());
|
TORRENT_ASSERT(is_disconnecting());
|
||||||
#ifdef TORRENT_DEBUG
|
#ifdef TORRENT_DEBUG
|
||||||
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
TORRENT_ASSERT(statistics().last_payload_downloaded()
|
||||||
|
|
|
@ -137,6 +137,7 @@ test-suite libtorrent :
|
||||||
[ run test_checking.cpp ]
|
[ run test_checking.cpp ]
|
||||||
[ run test_url_seed.cpp ]
|
[ run test_url_seed.cpp ]
|
||||||
[ run test_web_seed.cpp ]
|
[ run test_web_seed.cpp ]
|
||||||
|
[ run test_web_seed_redirect.cpp ]
|
||||||
[ run test_web_seed_socks4.cpp ]
|
[ run test_web_seed_socks4.cpp ]
|
||||||
[ run test_web_seed_socks5.cpp ]
|
[ run test_web_seed_socks5.cpp ]
|
||||||
[ run test_web_seed_socks5_pw.cpp ]
|
[ run test_web_seed_socks5_pw.cpp ]
|
||||||
|
|
|
@ -351,6 +351,24 @@ int test_main()
|
||||||
parse_url_components("http:", ec);
|
parse_url_components("http:", ec);
|
||||||
TEST_CHECK(ec == error_code(errors::unsupported_url_protocol));
|
TEST_CHECK(ec == error_code(errors::unsupported_url_protocol));
|
||||||
ec.clear();
|
ec.clear();
|
||||||
|
|
||||||
|
// test resolve_redirect_location
|
||||||
|
|
||||||
|
TEST_EQUAL(resolve_redirect_location("http://example.com/a/b", "a")
|
||||||
|
, "http://example.com/a/a");
|
||||||
|
|
||||||
|
TEST_EQUAL(resolve_redirect_location("http://example.com/a/b", "c/d/e/")
|
||||||
|
, "http://example.com/a/c/d/e/");
|
||||||
|
|
||||||
|
TEST_EQUAL(resolve_redirect_location("http://example.com/a/b", "../a")
|
||||||
|
, "http://example.com/a/../a");
|
||||||
|
|
||||||
|
TEST_EQUAL(resolve_redirect_location("http://example.com/a/b", "/c")
|
||||||
|
, "http://example.com/c");
|
||||||
|
|
||||||
|
TEST_EQUAL(resolve_redirect_location("http://example.com/a/b", "http://test.com/d")
|
||||||
|
, "http://test.com/d");
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -0,0 +1,109 @@
|
||||||
|
/*
|
||||||
|
|
||||||
|
Copyright (c) 2008-2014, 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 "test.hpp"
|
||||||
|
#include "setup_transfer.hpp"
|
||||||
|
#include "web_seed_suite.hpp"
|
||||||
|
#include "libtorrent/create_torrent.hpp"
|
||||||
|
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
const int proxy = libtorrent::proxy_settings::none;
|
||||||
|
|
||||||
|
//static unsigned char random_byte()
|
||||||
|
//{ return std::rand() & 0xff; }
|
||||||
|
|
||||||
|
int test_main()
|
||||||
|
{
|
||||||
|
using namespace libtorrent;
|
||||||
|
|
||||||
|
error_code ec;
|
||||||
|
|
||||||
|
file_storage fs;
|
||||||
|
int piece_size = 0x4000;
|
||||||
|
|
||||||
|
char random_data[16000];
|
||||||
|
std::generate(random_data, random_data + sizeof(random_data), random_byte);
|
||||||
|
file f("test_file", file::write_only, ec);
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "failed to create file \"test_file\": (%d) %s\n"
|
||||||
|
, ec.value(), ec.message().c_str());
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
file::iovec_t b = { random_data, size_t(16000)};
|
||||||
|
f.writev(0, &b, 1, ec);
|
||||||
|
fs.add_file("test_file", 16000);
|
||||||
|
|
||||||
|
int port = start_web_server();
|
||||||
|
|
||||||
|
// generate a torrent with pad files to make sure they
|
||||||
|
// are not requested web seeds
|
||||||
|
libtorrent::create_torrent t(fs, piece_size, 0x4000);
|
||||||
|
|
||||||
|
char tmp[512];
|
||||||
|
snprintf(tmp, sizeof(tmp), "http://127.0.0.1:%d/redirect", port);
|
||||||
|
t.add_url_seed(tmp);
|
||||||
|
|
||||||
|
// calculate the hash for all pieces
|
||||||
|
set_piece_hashes(t, ".", ec);
|
||||||
|
|
||||||
|
if (ec)
|
||||||
|
{
|
||||||
|
fprintf(stderr, "error creating hashes for test torrent: %s\n"
|
||||||
|
, ec.message().c_str());
|
||||||
|
TEST_CHECK(false);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<char> buf;
|
||||||
|
bencode(std::back_inserter(buf), t.generate());
|
||||||
|
boost::shared_ptr<torrent_info> torrent_file(new torrent_info(&buf[0]
|
||||||
|
, buf.size(), ec));
|
||||||
|
|
||||||
|
{
|
||||||
|
session ses(fingerprint(" ", 0,0,0,0), 0);
|
||||||
|
session_settings settings;
|
||||||
|
settings.max_queued_disk_bytes = 256 * 1024;
|
||||||
|
ses.set_settings(settings);
|
||||||
|
ses.set_alert_mask(~(alert::progress_notification | alert::stats_notification));
|
||||||
|
|
||||||
|
// disable keep-alive because otherwise the test will choke on seeing
|
||||||
|
// the disconnect (from the redirect)
|
||||||
|
test_transfer(ses, torrent_file, 0, 0, "http", true, false, false, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
stop_web_server();
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -79,7 +79,7 @@ static sha1_hash file_hash(std::string const& name)
|
||||||
static char const* proxy_name[] = {"", "_socks4", "_socks5", "_socks5_pw", "_http", "_http_pw", "_i2p"};
|
static char const* proxy_name[] = {"", "_socks4", "_socks5", "_socks5_pw", "_http", "_http_pw", "_i2p"};
|
||||||
|
|
||||||
// proxy: 0=none, 1=socks4, 2=socks5, 3=socks5_pw 4=http 5=http_pw
|
// proxy: 0=none, 1=socks4, 2=socks5, 3=socks5_pw 4=http 5=http_pw
|
||||||
static void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_file
|
void test_transfer(lt::session& ses, boost::shared_ptr<torrent_info> torrent_file
|
||||||
, int proxy, int port, char const* protocol, bool url_seed
|
, int proxy, int port, char const* protocol, bool url_seed
|
||||||
, bool chunked_encoding, bool test_ban, bool keepalive)
|
, bool chunked_encoding, bool test_ban, bool keepalive)
|
||||||
{
|
{
|
||||||
|
|
|
@ -35,3 +35,9 @@ int EXPORT run_http_suite(int proxy, char const* protocol
|
||||||
, bool test_url_seed, bool chunked_encoding = false, bool test_ban = false
|
, bool test_url_seed, bool chunked_encoding = false, bool test_ban = false
|
||||||
, bool keepalive = true, bool test_rename = false);
|
, bool keepalive = true, bool test_rename = false);
|
||||||
|
|
||||||
|
void EXPORT test_transfer(libtorrent::session& ses
|
||||||
|
, boost::shared_ptr<libtorrent::torrent_info> torrent_file
|
||||||
|
, int proxy = 0, int port = 0, char const* protocol = "http"
|
||||||
|
, bool url_seed = true, bool chunked_encoding = false
|
||||||
|
, bool test_ban = false, bool keepalive = true);
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue