extend piece_picker unit test. extend http_parser unit test and fix resolve_redirect_location

This commit is contained in:
Arvid Norberg 2015-02-15 20:01:30 +00:00
parent 40980df545
commit cb6d3cdd44
3 changed files with 222 additions and 43 deletions

View File

@ -78,29 +78,52 @@ namespace libtorrent
if (location[0] == '/')
{
// it's an absolute path. replace the path component of
// referrer with location
// 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);
// first skip the url scheme of the referer
std::size_t i = url.find("://");
// if the referrer doesn't appear to have a proper URL scheme
// just return the location verbatim (and probably fail)
if (i == std::string::npos)
return location;
url.resize(i);
// then skip the hostname and port, it's fine for this to fail, in
// case the referrer doesn't have a path component, it's just the
// url-scheme and hostname, in which case we just append the location
i = url.find_first_of('/', i + 3);
if (i != std::string::npos)
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)
// first skip the url scheme of the referer
std::size_t start = url.find("://");
// the referrer is not a valid full URL
if (start == std::string::npos)
return location;
url.resize(i);
std::size_t end = url.find_last_of('/');
// if the / we find is part of the scheme, there is no / in the path
// component or hostname.
if (end <= start + 2) end = std::string::npos;
if ((url.empty() || url[url.size()-1] != '/')
&& (location.empty() || location[0] != '/'))
// if this fails, the referrer is just url-scheme and hostname. We can
// just append the location to it.
if (end != std::string::npos)
url.resize(end);
// however, we may still need to insert a '/' in case neither side
// has one. We know the location doesn't start with a / already.
// so, if the referrer doesn't end with one, add it.
if ((url.empty() || url[url.size()-1] != '/'))
url += '/';
url += location;
}

View File

@ -63,10 +63,14 @@ tuple<int, int, bool> feed_bytes(http_parser& parser, char const* str)
ret.get<1>() += protocol;
ret.get<2>() |= error;
// std::cerr << payload << ", " << protocol << ", " << chunk_size << std::endl;
TORRENT_ASSERT(payload + protocol == chunk_size);
TORRENT_ASSERT(payload + protocol == chunk_size || ret.get<2>());
}
TEST_CHECK(prev == make_tuple(0, 0, false) || ret == prev);
TEST_EQUAL(ret.get<0>() + ret.get<1>(), strlen(str));
TEST_CHECK(prev == make_tuple(0, 0, false) || ret == prev || ret.get<2>());
if (!ret.get<2>())
{
TEST_EQUAL(ret.get<0>() + ret.get<1>(), strlen(str));
}
prev = ret;
}
return ret;
@ -269,6 +273,48 @@ int test_main()
parser.reset();
// test invalid content range
char const* invalid_range_response =
"HTTP/1.1 206 OK\n"
"content-range: bytes 4-0\n"
"content-type: test/plain\n"
"\n"
"\ntest";
received = feed_bytes(parser, invalid_range_response);
TEST_CHECK(received.get<2>() == true);
parser.reset();
// test invalid status line
char const* invalid_status_response =
"HTTP/1.1 206\n"
"content-range: bytes 4-0\n"
"content-type: test/plain\n"
"\n"
"\ntest";
received = feed_bytes(parser, invalid_status_response);
TEST_CHECK(received.get<2>() == true);
parser.reset();
// test invalid status line 2
char const* invalid_status_response2 =
"HTTP/1.1\n"
"content-range: bytes 4-0\n"
"content-type: test/plain\n"
"\n"
"\ntest";
received = feed_bytes(parser, invalid_status_response2);
TEST_CHECK(received.get<2>() == true);
parser.reset();
// make sure we support content-range responses
// and that we're case insensitive
char const* one_hundred_response =
@ -391,6 +437,28 @@ int test_main()
TEST_EQUAL(resolve_redirect_location("http://example.com/a/b", "http://test.com/d")
, "http://test.com/d");
TEST_EQUAL(resolve_redirect_location("my-custom-scheme://example.com/a/b", "http://test.com/d")
, "http://test.com/d");
TEST_EQUAL(resolve_redirect_location("http://example.com", "/d")
, "http://example.com/d");
TEST_EQUAL(resolve_redirect_location("http://example.com", "d")
, "http://example.com/d");
TEST_EQUAL(resolve_redirect_location("my-custom-scheme://example.com/a/b", "/d")
, "my-custom-scheme://example.com/d");
TEST_EQUAL(resolve_redirect_location("my-custom-scheme://example.com/a/b", "c/d")
, "my-custom-scheme://example.com/a/c/d");
// if the referrer is invalid, just respond the verbatim location
TEST_EQUAL(resolve_redirect_location("example.com/a/b", "/c/d")
, "/c/d");
// is_ok_status
TEST_EQUAL(is_ok_status(200), true);
TEST_EQUAL(is_ok_status(206), true);
TEST_EQUAL(is_ok_status(299), false);
@ -399,6 +467,8 @@ int test_main()
TEST_EQUAL(is_ok_status(400), false);
TEST_EQUAL(is_ok_status(299), false);
// is_redirect
TEST_EQUAL(is_redirect(299), false);
TEST_EQUAL(is_redirect(100), false);
TEST_EQUAL(is_redirect(300), true);

View File

@ -769,56 +769,142 @@ int test_main()
// ========================================================
// sweep up, we_have()
print_title("test cursors. sweep up, we_have");
p = setup_picker("7654321", " ", "", "");
for (int i = 0; i < 7; ++i)
{
TEST_EQUAL(p->cursor(), i);
TEST_EQUAL(p->reverse_cursor(), 7);
p->we_have(i);
}
TEST_CHECK(p->is_finished());
TEST_CHECK(p->is_seeding());
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
// sweep up, set_piece_priority()
print_title("test cursors. sweep up, set_piece_priority");
p = setup_picker("7654321", " ", "", "");
for (int i = 0; i < 7; ++i)
{
TEST_EQUAL(p->cursor(), i);
TEST_EQUAL(p->reverse_cursor(), 7);
p->set_piece_priority(i, 0);
}
TEST_CHECK(p->is_finished());
TEST_CHECK(!p->is_seeding());
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
// sweep down, we_have()
print_title("test cursors. sweep down, we_have");
p = setup_picker("7654321", " ", "", "");
for (int i = 6; i >= 0; --i)
{
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), i + 1);
p->we_have(i);
}
TEST_CHECK(p->is_finished());
TEST_CHECK(p->is_seeding());
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
// sweep down, set_piece_priority()
print_title("test cursors. sweep down, set_piece_priority");
p = setup_picker("7654321", " ", "", "");
for (int i = 6; i >= 0; --i)
{
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), i + 1);
p->set_piece_priority(i, 0);
}
TEST_CHECK(p->is_finished());
TEST_CHECK(!p->is_seeding());
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
print_title("test cursors. sweep up, we_dont_have");
p = setup_picker("7654321", "*******", "", "");
TEST_CHECK(p->is_finished());
TEST_CHECK(p->is_seeding());
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
for (int i = 0; i < 7; ++i)
{
p->we_dont_have(i);
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), i + 1);
}
TEST_CHECK(!p->is_finished());
TEST_CHECK(!p->is_seeding());
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), 7);
print_title("test cursors. sweep down, we_dont_have");
p = setup_picker("7654321", "*******", "", "");
TEST_CHECK(p->is_finished());
TEST_CHECK(p->is_seeding());
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
for (int i = 6; i >= 0; --i)
{
p->we_dont_have(i);
TEST_EQUAL(p->cursor(), i);
TEST_EQUAL(p->reverse_cursor(), 7);
}
TEST_CHECK(!p->is_finished());
TEST_CHECK(!p->is_seeding());
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), 7);
// test cursors
print_title("test cursors");
p = setup_picker("7654321", " ", "", "");
TEST_CHECK(p->cursor() == 0);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), 7);
p->we_have(1);
TEST_CHECK(p->cursor() == 0);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), 7);
p->we_have(0);
TEST_CHECK(p->cursor() == 2);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 2);
TEST_EQUAL(p->reverse_cursor(), 7);
p->we_have(5);
TEST_CHECK(p->cursor() == 2);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 2);
TEST_EQUAL(p->reverse_cursor(), 7);
p->we_have(6);
TEST_CHECK(p->cursor() == 2);
TEST_CHECK(p->reverse_cursor() == 5);
TEST_EQUAL(p->cursor(), 2);
TEST_EQUAL(p->reverse_cursor(), 5);
p->we_have(4);
p->we_have(3);
p->we_have(2);
TEST_CHECK(p->cursor() == 7);
TEST_CHECK(p->reverse_cursor() == 0);
p->we_dont_have(3);
TEST_CHECK(p->cursor() == 3);
TEST_CHECK(p->reverse_cursor() == 4);
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
p = setup_picker("7654321", " ", "", "");
TEST_CHECK(p->cursor() == 0);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor() , 0);
TEST_EQUAL(p->reverse_cursor(), 7);
p->set_piece_priority(1, 0);
TEST_CHECK(p->cursor() == 0);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 0);
TEST_EQUAL(p->reverse_cursor(), 7);
p->set_piece_priority(0, 0);
TEST_CHECK(p->cursor() == 2);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 2);
TEST_EQUAL(p->reverse_cursor(), 7);
p->set_piece_priority(5, 0);
TEST_CHECK(p->cursor() == 2);
TEST_CHECK(p->reverse_cursor() == 7);
TEST_EQUAL(p->cursor(), 2);
TEST_EQUAL(p->reverse_cursor(), 7);
p->set_piece_priority(6, 0);
TEST_CHECK(p->cursor() == 2);
TEST_CHECK(p->reverse_cursor() == 5);
TEST_EQUAL(p->cursor(), 2);
TEST_EQUAL(p->reverse_cursor(), 5);
p->set_piece_priority(4, 0);
p->set_piece_priority(3, 0);
p->set_piece_priority(2, 0);
TEST_CHECK(p->cursor() == 7);
TEST_CHECK(p->reverse_cursor() == 0);
TEST_EQUAL(p->cursor(), 7);
TEST_EQUAL(p->reverse_cursor(), 0);
p->set_piece_priority(3, 1);
TEST_CHECK(p->cursor() == 3);
TEST_CHECK(p->reverse_cursor() == 4);
TEST_EQUAL(p->cursor(), 3);
TEST_EQUAL(p->reverse_cursor(), 4);
// ========================================================