Skip to content

Commit 865ff09

Browse files
committed
merge RC_1_1 into master
2 parents bb6f2b9 + 560ef29 commit 865ff09

11 files changed

+138
-74
lines changed

ChangeLog

+3
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,9 @@
7676
* resume data no longer has timestamps of files
7777
* require C++11 to build libtorrent
7878

79+
* fix issue with very long tracker- and web seed URLs
80+
* don't attempt to create empty files on startup, if they already exist
81+
* fix force-recheck issue (new files would not be picked up)
7982
* fix inconsistency in file_priorities and override_resume_data behavior
8083

8184
1.1.4 release

include/libtorrent/torrent.hpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -1024,7 +1024,7 @@ namespace libtorrent {
10241024

10251025
// renames the file with the given index to the new name
10261026
// the name may include a directory path
1027-
// returns false on failure
1027+
// posts alert to indicate success or failure
10281028
void rename_file(file_index_t index, std::string name);
10291029

10301030
// unless this returns true, new connections must wait

src/http_connection.cpp

+16-23
Original file line numberDiff line numberDiff line change
@@ -163,13 +163,7 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
163163
bool ssl = false;
164164
if (protocol == "https") ssl = true;
165165

166-
char request[4096];
167-
char* end = request + sizeof(request);
168-
char* ptr = request;
169-
170-
#define APPEND_FMT(fmt) ptr += std::snprintf(ptr, std::size_t(end - ptr), fmt)
171-
#define APPEND_FMT1(fmt, arg) ptr += std::snprintf(ptr, std::size_t(end - ptr), fmt, arg)
172-
#define APPEND_FMT2(fmt, arg1, arg2) ptr += std::snprintf(ptr, std::size_t(end - ptr), fmt, arg1, arg2)
166+
std::stringstream request;
173167

174168
// exclude ssl here, because SSL assumes CONNECT support in the
175169
// proxy and is handled at the lower layer
@@ -179,40 +173,39 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
179173
{
180174
// if we're using an http proxy and not an ssl
181175
// connection, just do a regular http proxy request
182-
APPEND_FMT1("GET %s HTTP/1.1\r\n", url.c_str());
176+
request << "GET " << url << " HTTP/1.1\r\n";
183177
if (ps->type == settings_pack::http_pw)
184-
APPEND_FMT1("Proxy-Authorization: Basic %s\r\n", base64encode(
185-
ps->username + ":" + ps->password).c_str());
178+
request << "Proxy-Authorization: Basic " << base64encode(
179+
ps->username + ":" + ps->password) << "\r\n";
186180

187181
hostname = ps->hostname;
188182
port = ps->port;
189183

190-
APPEND_FMT1("Host: %s", hostname.c_str());
191-
if (port != default_port) APPEND_FMT1(":%d\r\n", port);
192-
else APPEND_FMT("\r\n");
184+
request << "Host: " << hostname;
185+
if (port != default_port) request << ":" << port << "\r\n";
186+
else request << "\r\n";
193187
}
194188
else
195189
{
196-
APPEND_FMT2("GET %s HTTP/1.1\r\n"
197-
"Host: %s", path.c_str(), hostname.c_str());
198-
if (port != default_port) APPEND_FMT1(":%d\r\n", port);
199-
else APPEND_FMT("\r\n");
190+
request << "GET " << path << " HTTP/1.1\r\nHost: " << hostname;
191+
if (port != default_port) request << ":" << port << "\r\n";
192+
else request << "\r\n";
200193
}
201194

202-
// APPEND_FMT("Accept: */*\r\n");
195+
// request << "Accept: */*\r\n";
203196

204197
if (!m_user_agent.empty())
205-
APPEND_FMT1("User-Agent: %s\r\n", m_user_agent.c_str());
198+
request << "User-Agent: " << m_user_agent << "\r\n";
206199

207200
if (m_bottled)
208-
APPEND_FMT("Accept-Encoding: gzip\r\n");
201+
request << "Accept-Encoding: gzip\r\n";
209202

210203
if (!auth.empty())
211-
APPEND_FMT1("Authorization: Basic %s\r\n", base64encode(auth).c_str());
204+
request << "Authorization: Basic " << base64encode(auth) << "\r\n";
212205

213-
APPEND_FMT("Connection: close\r\n\r\n");
206+
request << "Connection: close\r\n\r\n";
214207

215-
m_sendbuffer.assign(request);
208+
m_sendbuffer.assign(request.str());
216209
m_url = url;
217210
start(hostname, port, timeout, prio
218211
, ps, ssl, handle_redirects, bind_addr, m_resolve_flags

src/storage.cpp

+1-1
Original file line numberDiff line numberDiff line change
@@ -242,7 +242,7 @@ namespace libtorrent {
242242
// it's supposed to be, truncate it
243243
// if the file is empty, just create it either way.
244244
if ((!err && size > files().file_size(file_index))
245-
|| files().file_size(file_index) == 0)
245+
|| (files().file_size(file_index) == 0 && err == boost::system::errc::no_such_file_or_directory))
246246
{
247247
std::string file_path = files().file_path(file_index, m_save_path);
248248
std::string dir = parent_path(file_path);

src/torrent.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -2227,6 +2227,10 @@ namespace libtorrent {
22272227
TORRENT_ASSERT(m_outstanding_check_files == false);
22282228
m_add_torrent_params.reset();
22292229

2230+
// this will clear the stat cache, to make us actually query the
2231+
// filesystem for files again
2232+
m_ses.disk_thread().async_release_files(m_storage, []{});
2233+
22302234
aux::vector<std::string, file_index_t> links;
22312235
m_ses.disk_thread().async_check_files(m_storage, nullptr
22322236
, links, std::bind(&torrent::on_force_recheck
@@ -2657,6 +2661,7 @@ namespace libtorrent {
26572661
void torrent::announce_with_tracker(std::uint8_t e)
26582662
{
26592663
TORRENT_ASSERT(is_single_thread());
2664+
TORRENT_ASSERT(e == tracker_request::stopped || state() != torrent_status::checking_files);
26602665
INVARIANT_CHECK;
26612666

26622667
if (m_trackers.empty())
@@ -8831,6 +8836,7 @@ namespace libtorrent {
88318836
void torrent::start_announcing()
88328837
{
88338838
TORRENT_ASSERT(is_single_thread());
8839+
TORRENT_ASSERT(state() != torrent_status::checking_files);
88348840
if (is_paused())
88358841
{
88368842
#ifndef TORRENT_DISABLE_LOGGING

test/setup_transfer.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -640,7 +640,8 @@ std::shared_ptr<lt::torrent_info> make_torrent(const int file_sizes[]
640640
return std::make_shared<torrent_info>(buf, from_span);
641641
}
642642

643-
void create_random_files(std::string const& path, const int file_sizes[], int num_files)
643+
void create_random_files(std::string const& path, const int file_sizes[], int num_files
644+
, file_storage* fs)
644645
{
645646
error_code ec;
646647
aux::vector<char> random_data(300000);
@@ -657,6 +658,7 @@ void create_random_files(std::string const& path, const int file_sizes[], int nu
657658
full_path = combine_path(full_path, filename);
658659

659660
int to_write = file_sizes[i];
661+
if (fs) fs->add_file(full_path, to_write);
660662
file f(full_path, open_mode::write_only, ec);
661663
if (ec) std::printf("failed to create file \"%s\": (%d) %s\n"
662664
, full_path.c_str(), ec.value(), ec.message().c_str());

test/setup_transfer.hpp

+9-4
Original file line numberDiff line numberDiff line change
@@ -37,9 +37,14 @@ POSSIBILITY OF SUCH DAMAGE.
3737
#include "test.hpp"
3838
#include "libtorrent/session.hpp"
3939
#include "libtorrent/units.hpp"
40-
#include "libtorrent/span.hpp"
41-
#include "libtorrent/alert.hpp"
42-
#include "libtorrent/add_torrent_params.hpp"
40+
41+
namespace libtorrent
42+
{
43+
class alert;
44+
struct add_torrent_params;
45+
class file_storage;
46+
class session;
47+
}
4348

4449
EXPORT int print_failures();
4550
EXPORT unsigned char random_byte();
@@ -89,7 +94,7 @@ EXPORT lt::file_storage make_file_storage(const int file_sizes[], int num_files
8994
EXPORT std::shared_ptr<lt::torrent_info> make_torrent(const int file_sizes[]
9095
, int num_files, int piece_size);
9196
EXPORT void create_random_files(std::string const& path, const int file_sizes[]
92-
, int num_files);
97+
, int num_files, libtorrent::file_storage* fs = nullptr);
9398

9499
EXPORT std::shared_ptr<lt::torrent_info> create_torrent(std::ostream* file = 0
95100
, char const* name = "temporary", int piece_size = 16 * 1024, int num_pieces = 13

test/test_checking.cpp

+60-43
Original file line numberDiff line numberDiff line change
@@ -30,18 +30,20 @@ POSSIBILITY OF SUCH DAMAGE.
3030
3131
*/
3232

33+
#include <sys/stat.h> // for chmod
34+
3335
#include "libtorrent/session.hpp"
3436
#include "test.hpp"
3537
#include "setup_transfer.hpp"
3638
#include "libtorrent/create_torrent.hpp"
37-
#include <sys/stat.h> // for chmod
39+
#include "libtorrent/alert_types.hpp"
3840
#include "libtorrent/torrent_info.hpp"
3941
#include "libtorrent/torrent_status.hpp"
4042
#include "libtorrent/hex.hpp" // to_hex
4143
#include "libtorrent/aux_/path.hpp"
4244

4345
static const int file_sizes[] =
44-
{ 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
46+
{ 0, 5, 16 - 5, 16000, 17, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
4547
,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4};
4648
const int num_files = sizeof(file_sizes)/sizeof(file_sizes[0]);
4749

@@ -56,67 +58,47 @@ enum
5658
corrupt_files = 2,
5759

5860
incomplete_files = 4,
61+
62+
// make the files not be there when starting up, move the files in place and
63+
// force-recheck. Make sure the stat cache is cleared and let us pick up the
64+
// new files
65+
force_recheck = 8,
5966
};
6067

6168
void test_checking(int flags = read_only_files)
6269
{
6370
using namespace lt;
6471

65-
std::printf("\n==== TEST CHECKING %s%s%s=====\n\n"
72+
std::printf("\n==== TEST CHECKING %s%s%s%s=====\n\n"
6673
, (flags & read_only_files) ? "read-only-files ":""
6774
, (flags & corrupt_files) ? "corrupt ":""
68-
, (flags & incomplete_files) ? "incomplete ":"");
69-
70-
// make the files writable again
71-
for (int i = 0; i < num_files; ++i)
72-
{
73-
char name[1024];
74-
std::snprintf(name, sizeof(name), "test%d", i);
75-
char dirname[200];
76-
std::snprintf(dirname, sizeof(dirname), "test_dir%d", i / 5);
77-
std::string path = combine_path(combine_path("tmp1_checking", "test_torrent_dir"), dirname);
78-
path = combine_path(path, name);
79-
#ifdef TORRENT_WINDOWS
80-
SetFileAttributesA(path.c_str(), FILE_ATTRIBUTE_NORMAL);
81-
#else
82-
chmod(path.c_str(), S_IRUSR | S_IWUSR);
83-
#endif
84-
}
75+
, (flags & incomplete_files) ? "incomplete ":""
76+
, (flags & force_recheck) ? "force_recheck ":"");
8577

86-
// in case the previous run was terminated
8778
error_code ec;
88-
remove_all("tmp1_checking", ec);
89-
if (ec) std::printf("ERROR: removing tmp1_checking: (%d) %s\n"
90-
, ec.value(), ec.message().c_str());
91-
92-
create_directory("tmp1_checking", ec);
93-
if (ec) std::printf("ERROR: creating directory tmp1_checking: (%d) %s\n"
94-
, ec.value(), ec.message().c_str());
95-
create_directory(combine_path("tmp1_checking", "test_torrent_dir"), ec);
96-
if (ec) std::printf("ERROR: creating directory test_torrent_dir: (%d) %s\n"
79+
create_directory("test_torrent_dir", ec);
80+
if (ec) fprintf(stdout, "ERROR: creating directory test_torrent_dir: (%d) %s\n"
9781
, ec.value(), ec.message().c_str());
9882

9983
file_storage fs;
10084
std::srand(10);
10185
int piece_size = 0x4000;
10286

103-
create_random_files(combine_path("tmp1_checking", "test_torrent_dir")
104-
, file_sizes, num_files);
87+
create_random_files("test_torrent_dir", file_sizes, num_files, &fs);
10588

106-
add_files(fs, combine_path("tmp1_checking", "test_torrent_dir"));
10789
lt::create_torrent t(fs, piece_size, 0x4000
10890
, lt::create_torrent::optimize_alignment);
10991

11092
// calculate the hash for all pieces
111-
set_piece_hashes(t, "tmp1_checking", ec);
93+
set_piece_hashes(t, ".", ec);
11294
if (ec) std::printf("ERROR: set_piece_hashes: (%d) %s\n"
11395
, ec.value(), ec.message().c_str());
11496

11597
std::vector<char> buf;
11698
bencode(std::back_inserter(buf), t.generate());
11799
auto ti = std::make_shared<torrent_info>(buf, ec, from_span);
118100

119-
std::printf("generated torrent: %s tmp1_checking/test_torrent_dir\n"
101+
std::printf("generated torrent: %s test_torrent_dir\n"
120102
, aux::to_hex(ti->info_hash()).c_str());
121103

122104
// truncate every file in half
@@ -128,7 +110,7 @@ void test_checking(int flags = read_only_files)
128110
std::snprintf(name, sizeof(name), "test%d", i);
129111
char dirname[200];
130112
std::snprintf(dirname, sizeof(dirname), "test_dir%d", i / 5);
131-
std::string path = combine_path(combine_path("tmp1_checking", "test_torrent_dir"), dirname);
113+
std::string path = combine_path("test_torrent_dir", dirname);
132114
path = combine_path(path, name);
133115

134116
error_code ec;
@@ -148,9 +130,9 @@ void test_checking(int flags = read_only_files)
148130
// increase the size of some files. When they're read only that forces
149131
// the checker to open them in write-mode to truncate them
150132
static const int file_sizes2[] =
151-
{ 5, 16 - 5, 16001, 30, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
133+
{ 0, 5, 16 - 5, 16001, 30, 10, 8000, 8000, 1,1,1,1,1,100,1,1,1,1,100,1,1,1,1,1,1
152134
,1,1,1,1,1,1,13,65000,34,75,2,30,400,500,23000,900,43000,400,4300,6, 4};
153-
create_random_files(combine_path("tmp1_checking", "test_torrent_dir"), file_sizes2, num_files);
135+
create_random_files("test_torrent_dir", file_sizes2, num_files);
154136
}
155137

156138
// make the files read only
@@ -164,7 +146,7 @@ void test_checking(int flags = read_only_files)
164146
char dirname[200];
165147
std::snprintf(dirname, sizeof(dirname), "test_dir%d", i / 5);
166148

167-
std::string path = combine_path(combine_path("tmp1_checking", "test_torrent_dir"), dirname);
149+
std::string path = combine_path("test_torrent_dir", dirname);
168150
path = combine_path(path, name);
169151
std::printf(" %s\n", path.c_str());
170152

@@ -176,6 +158,16 @@ void test_checking(int flags = read_only_files)
176158
}
177159
}
178160

161+
if (flags & force_recheck)
162+
{
163+
remove_all("test_torrent_dir_tmp", ec);
164+
if (ec) std::printf("ERROR: removing \"test_torrent_dir_tmp\": (%d) %s\n"
165+
, ec.value(), ec.message().c_str());
166+
rename("test_torrent_dir", "test_torrent_dir_tmp", ec);
167+
if (ec) std::printf("ERROR: renaming dir \"test_torrent_dir\": (%d) %s\n"
168+
, ec.value(), ec.message().c_str());
169+
}
170+
179171
auto const mask = alert::all_categories
180172
& ~(alert::progress_notification
181173
| alert::performance_warning
@@ -192,11 +184,30 @@ void test_checking(int flags = read_only_files)
192184
lt::session ses1(pack);
193185

194186
add_torrent_params p;
195-
p.save_path = "tmp1_checking";
187+
p.save_path = ".";
196188
p.ti = ti;
197189
torrent_handle tor1 = ses1.add_torrent(p, ec);
198190
TEST_CHECK(!ec);
199191

192+
if (flags & force_recheck)
193+
{
194+
// first make sure the session tries to check for the file and can't find
195+
// them
196+
libtorrent::alert const* a = wait_for_alert(
197+
ses1, torrent_checked_alert::alert_type, "checking");
198+
TEST_CHECK(a);
199+
200+
// now, move back the files and force-recheck. make sure we pick up the
201+
// files this time
202+
remove_all("test_torrent_dir", ec);
203+
if (ec) fprintf(stdout, "ERROR: removing \"test_torrent_dir\": (%d) %s\n"
204+
, ec.value(), ec.message().c_str());
205+
rename("test_torrent_dir_tmp", "test_torrent_dir", ec);
206+
if (ec) fprintf(stdout, "ERROR: renaming dir \"test_torrent_dir_tmp\": (%d) %s\n"
207+
, ec.value(), ec.message().c_str());
208+
tor1.force_recheck();
209+
}
210+
200211
torrent_status st;
201212
for (int i = 0; i < 20; ++i)
202213
{
@@ -217,6 +228,7 @@ void test_checking(int flags = read_only_files)
217228
if (st.errc) break;
218229
std::this_thread::sleep_for(lt::milliseconds(500));
219230
}
231+
220232
if (flags & incomplete_files)
221233
{
222234
TEST_CHECK(!st.is_seeding);
@@ -273,7 +285,7 @@ void test_checking(int flags = read_only_files)
273285
char dirname[200];
274286
std::snprintf(dirname, sizeof(dirname), "test_dir%d", i / 5);
275287

276-
std::string path = combine_path(combine_path("tmp1_checking", "test_torrent_dir"), dirname);
288+
std::string path = combine_path("test_torrent_dir", dirname);
277289
path = combine_path(path, name);
278290
#ifdef TORRENT_WINDOWS
279291
SetFileAttributesA(path.c_str(), FILE_ATTRIBUTE_NORMAL);
@@ -283,8 +295,8 @@ void test_checking(int flags = read_only_files)
283295
}
284296
}
285297

286-
remove_all("tmp1_checking", ec);
287-
if (ec) std::printf("ERROR: removing tmp1_checking: (%d) %s\n"
298+
remove_all("test_torrent_dir", ec);
299+
if (ec) std::printf("ERROR: removing test_torrent_dir: (%d) %s\n"
288300
, ec.value(), ec.message().c_str());
289301
}
290302

@@ -313,3 +325,8 @@ TORRENT_TEST(corrupt)
313325
test_checking(corrupt_files);
314326
}
315327

328+
TORRENT_TEST(force_recheck)
329+
{
330+
test_checking(force_recheck);
331+
}
332+

0 commit comments

Comments
 (0)