Skip to content

Commit 560ef29

Browse files
committed
fix issue with very long tracker- and web seed URLs. Instead of using a fixed length stack allocated request buffer, use a dynamically growing stringstream
1 parent 4e497e1 commit 560ef29

File tree

3 files changed

+25
-23
lines changed

3 files changed

+25
-23
lines changed

ChangeLog

+1
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
* fix issue with very long tracker- and web seed URLs
12
* don't attempt to create empty files on startup, if they already exist
23
* fix force-recheck issue (new files would not be picked up)
34
* fix inconsistency in file_priorities and override_resume_data behavior

src/http_connection.cpp

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

170-
char request[4096];
171-
char* end = request + sizeof(request);
172-
char* ptr = request;
173-
174-
#define APPEND_FMT(fmt) ptr += snprintf(ptr, end - ptr, fmt)
175-
#define APPEND_FMT1(fmt, arg) ptr += snprintf(ptr, end - ptr, fmt, arg)
176-
#define APPEND_FMT2(fmt, arg1, arg2) ptr += snprintf(ptr, end - ptr, fmt, arg1, arg2)
170+
std::stringstream request;
177171

178172
// exclude ssl here, because SSL assumes CONNECT support in the
179173
// proxy and is handled at the lower layer
@@ -183,40 +177,39 @@ void http_connection::get(std::string const& url, time_duration timeout, int pri
183177
{
184178
// if we're using an http proxy and not an ssl
185179
// connection, just do a regular http proxy request
186-
APPEND_FMT1("GET %s HTTP/1.1\r\n", url.c_str());
180+
request << "GET " << url << " HTTP/1.1\r\n";
187181
if (ps->type == settings_pack::http_pw)
188-
APPEND_FMT1("Proxy-Authorization: Basic %s\r\n", base64encode(
189-
ps->username + ":" + ps->password).c_str());
182+
request << "Proxy-Authorization: Basic " << base64encode(
183+
ps->username + ":" + ps->password) << "\r\n";
190184

191185
hostname = ps->hostname;
192186
port = ps->port;
193187

194-
APPEND_FMT1("Host: %s", hostname.c_str());
195-
if (port != default_port) APPEND_FMT1(":%d\r\n", port);
196-
else APPEND_FMT("\r\n");
188+
request << "Host: " << hostname;
189+
if (port != default_port) request << ":" << port << "\r\n";
190+
else request << "\r\n";
197191
}
198192
else
199193
{
200-
APPEND_FMT2("GET %s HTTP/1.1\r\n"
201-
"Host: %s", path.c_str(), hostname.c_str());
202-
if (port != default_port) APPEND_FMT1(":%d\r\n", port);
203-
else APPEND_FMT("\r\n");
194+
request << "GET " << path << " HTTP/1.1\r\nHost: " << hostname;
195+
if (port != default_port) request << ":" << port << "\r\n";
196+
else request << "\r\n";
204197
}
205198

206-
// APPEND_FMT("Accept: */*\r\n");
199+
// request << "Accept: */*\r\n";
207200

208201
if (!m_user_agent.empty())
209-
APPEND_FMT1("User-Agent: %s\r\n", m_user_agent.c_str());
202+
request << "User-Agent: " << m_user_agent << "\r\n";
210203

211204
if (m_bottled)
212-
APPEND_FMT("Accept-Encoding: gzip\r\n");
205+
request << "Accept-Encoding: gzip\r\n";
213206

214207
if (!auth.empty())
215-
APPEND_FMT1("Authorization: Basic %s\r\n", base64encode(auth).c_str());
208+
request << "Authorization: Basic " << base64encode(auth) << "\r\n";
216209

217-
APPEND_FMT("Connection: close\r\n\r\n");
210+
request << "Connection: close\r\n\r\n";
218211

219-
m_sendbuffer.assign(request);
212+
m_sendbuffer.assign(request.str());
220213
m_url = url;
221214
start(hostname, port, timeout, prio
222215
, ps, ssl, handle_redirects, bind_addr, m_resolve_flags

test/test_http_connection.cpp

+8
Original file line numberDiff line numberDiff line change
@@ -201,6 +201,14 @@ void run_suite(std::string const& protocol
201201
run_test(url_base + "password_protected", 3216, 200, 1, error_code(), ps
202202
, "testuser:testpass");
203203

204+
// try a very long path
205+
std::string path;
206+
for (int i = 0; i < 6000; ++i)
207+
{
208+
path += static_cast<char>(i % 26) + 'a';
209+
}
210+
run_test(url_base + path, 0, 404, 1, err(), ps);
211+
204212
// only run the tests to handle NX_DOMAIN if we have a proper internet
205213
// connection that doesn't inject false DNS responses (like Comcast does)
206214
hostent* h = gethostbyname("non-existent-domain.se");

0 commit comments

Comments
 (0)