mirror of https://github.com/aria2/aria2
Percent-encode non-printable ASCII and non-ASCII chars in FileEntry.
Percent-encode non-printable ASCII and non-ASCII chars in URI using util::percentEncodeMini() when URI is added to FileEntry. Removed percent-encode from Request. Also do percent-encoding when setting referer and redirected URI.pull/1/head
parent
491e8bc519
commit
7368c9c9d8
|
@ -155,7 +155,7 @@ FileEntry::getRequest
|
||||||
req.reset();
|
req.reset();
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
req->setReferer(referer);
|
req->setReferer(util::percentEncodeMini(referer));
|
||||||
req->setMethod(method);
|
req->setMethod(method);
|
||||||
spentUris_.push_back(uri);
|
spentUris_.push_back(uri);
|
||||||
inFlightRequests_.push_back(req);
|
inFlightRequests_.push_back(req);
|
||||||
|
@ -518,8 +518,9 @@ size_t FileEntry::setUris(const std::vector<std::string>& uris)
|
||||||
bool FileEntry::addUri(const std::string& uri)
|
bool FileEntry::addUri(const std::string& uri)
|
||||||
{
|
{
|
||||||
uri::UriStruct us;
|
uri::UriStruct us;
|
||||||
if(uri::parse(us, uri)) {
|
std::string peUri = util::percentEncodeMini(uri);
|
||||||
uris_.push_back(uri);
|
if(uri::parse(us, peUri)) {
|
||||||
|
uris_.push_back(peUri);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
@ -529,9 +530,10 @@ bool FileEntry::addUri(const std::string& uri)
|
||||||
bool FileEntry::insertUri(const std::string& uri, size_t pos)
|
bool FileEntry::insertUri(const std::string& uri, size_t pos)
|
||||||
{
|
{
|
||||||
uri::UriStruct us;
|
uri::UriStruct us;
|
||||||
if(uri::parse(us, uri)) {
|
std::string peUri = util::percentEncodeMini(uri);
|
||||||
|
if(uri::parse(us, peUri)) {
|
||||||
pos = std::min(pos, uris_.size());
|
pos = std::min(pos, uris_.size());
|
||||||
uris_.insert(uris_.begin()+pos, uri);
|
uris_.insert(uris_.begin()+pos, peUri);
|
||||||
return true;
|
return true;
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
|
|
|
@ -160,7 +160,8 @@ bool HttpResponse::isRedirect() const
|
||||||
void HttpResponse::processRedirect()
|
void HttpResponse::processRedirect()
|
||||||
{
|
{
|
||||||
|
|
||||||
if(httpRequest_->getRequest()->redirectUri(getRedirectURI())) {
|
if(httpRequest_->getRequest()->redirectUri
|
||||||
|
(util::percentEncodeMini(getRedirectURI()))) {
|
||||||
A2_LOG_INFO(fmt(MSG_REDIRECT,
|
A2_LOG_INFO(fmt(MSG_REDIRECT,
|
||||||
cuid_,
|
cuid_,
|
||||||
httpRequest_->getRequest()->getCurrentUri().c_str()));
|
httpRequest_->getRequest()->getCurrentUri().c_str()));
|
||||||
|
|
|
@ -85,27 +85,6 @@ std::string removeFragment(const std::string& uri)
|
||||||
}
|
}
|
||||||
} // namespace
|
} // namespace
|
||||||
|
|
||||||
namespace {
|
|
||||||
std::string percentEncode(const std::string& src)
|
|
||||||
{
|
|
||||||
std::string result;
|
|
||||||
for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;
|
|
||||||
++i) {
|
|
||||||
// Non-Printable ASCII and non-ASCII chars + some ASCII chars.
|
|
||||||
unsigned char c = *i;
|
|
||||||
if(in(c, 0x00u, 0x20u) || c >= 0x7fu ||
|
|
||||||
// Chromium escapes following characters. Firefox4 escapes
|
|
||||||
// more.
|
|
||||||
c == '"' || c == '<' || c == '>') {
|
|
||||||
result += fmt("%%%02X", c);
|
|
||||||
} else {
|
|
||||||
result += c;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
} // namespace
|
|
||||||
|
|
||||||
bool Request::setUri(const std::string& uri) {
|
bool Request::setUri(const std::string& uri) {
|
||||||
supportsPersistentConnection_ = true;
|
supportsPersistentConnection_ = true;
|
||||||
uri_ = uri;
|
uri_ = uri;
|
||||||
|
@ -121,7 +100,7 @@ bool Request::resetUri() {
|
||||||
|
|
||||||
void Request::setReferer(const std::string& uri)
|
void Request::setReferer(const std::string& uri)
|
||||||
{
|
{
|
||||||
referer_ = previousUri_ = percentEncode(removeFragment(uri));
|
referer_ = previousUri_ = removeFragment(uri);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Request::redirectUri(const std::string& uri) {
|
bool Request::redirectUri(const std::string& uri) {
|
||||||
|
@ -145,7 +124,7 @@ bool Request::redirectUri(const std::string& uri) {
|
||||||
}
|
}
|
||||||
|
|
||||||
bool Request::parseUri(const std::string& srcUri) {
|
bool Request::parseUri(const std::string& srcUri) {
|
||||||
currentUri_ = percentEncode(removeFragment(srcUri));
|
currentUri_ = removeFragment(srcUri);
|
||||||
uri::UriStruct us;
|
uri::UriStruct us;
|
||||||
if(uri::parse(us, currentUri_)) {
|
if(uri::parse(us, currentUri_)) {
|
||||||
protocol_.swap(us.protocol);
|
protocol_.swap(us.protocol);
|
||||||
|
|
19
src/util.cc
19
src/util.cc
|
@ -447,6 +447,25 @@ std::string percentEncode(const std::string& target)
|
||||||
target.size());
|
target.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::string percentEncodeMini(const std::string& src)
|
||||||
|
{
|
||||||
|
std::string result;
|
||||||
|
for(std::string::const_iterator i = src.begin(), eoi = src.end(); i != eoi;
|
||||||
|
++i) {
|
||||||
|
// Non-Printable ASCII and non-ASCII chars + some ASCII chars.
|
||||||
|
unsigned char c = *i;
|
||||||
|
if(in(c, 0x00u, 0x20u) || c >= 0x7fu ||
|
||||||
|
// Chromium escapes following characters. Firefox4 escapes
|
||||||
|
// more.
|
||||||
|
c == '"' || c == '<' || c == '>') {
|
||||||
|
result += fmt("%%%02X", c);
|
||||||
|
} else {
|
||||||
|
result += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
std::string torrentPercentEncode(const unsigned char* target, size_t len) {
|
std::string torrentPercentEncode(const unsigned char* target, size_t len) {
|
||||||
std::string dest;
|
std::string dest;
|
||||||
for(size_t i = 0; i < len; ++i) {
|
for(size_t i = 0; i < len; ++i) {
|
||||||
|
|
|
@ -170,6 +170,8 @@ std::string percentEncode(const unsigned char* target, size_t len);
|
||||||
|
|
||||||
std::string percentEncode(const std::string& target);
|
std::string percentEncode(const std::string& target);
|
||||||
|
|
||||||
|
std::string percentEncodeMini(const std::string& target);
|
||||||
|
|
||||||
bool inRFC3986ReservedChars(const char c);
|
bool inRFC3986ReservedChars(const char c);
|
||||||
|
|
||||||
bool inRFC3986UnreservedChars(const char c);
|
bool inRFC3986UnreservedChars(const char c);
|
||||||
|
|
|
@ -218,6 +218,15 @@ void FileEntryTest::testAddUri()
|
||||||
FileEntry file;
|
FileEntry file;
|
||||||
CPPUNIT_ASSERT(file.addUri("http://good"));
|
CPPUNIT_ASSERT(file.addUri("http://good"));
|
||||||
CPPUNIT_ASSERT(!file.addUri("bad"));
|
CPPUNIT_ASSERT(!file.addUri("bad"));
|
||||||
|
// Test for percent-encode
|
||||||
|
CPPUNIT_ASSERT(file.addUri("http://host:80/file<with%2 %20space/"
|
||||||
|
"file with space;param%?a=/?"));
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("http://host:80"
|
||||||
|
"/file%3Cwith%2%20%20space/"
|
||||||
|
"file%20with%20space;param%"
|
||||||
|
"?a=/?"),
|
||||||
|
file.getRemainingUris()[1]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileEntryTest::testAddUris()
|
void FileEntryTest::testAddUris()
|
||||||
|
@ -239,6 +248,15 @@ void FileEntryTest::testInsertUri()
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/3"), uris[1]);
|
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/3"), uris[1]);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/1"), uris[2]);
|
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/1"), uris[2]);
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/4"), uris[3]);
|
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/4"), uris[3]);
|
||||||
|
// Test for percent-encode
|
||||||
|
CPPUNIT_ASSERT(file.insertUri("http://host:80/file<with%2 %20space/"
|
||||||
|
"file with space;param%?a=/?", 0));
|
||||||
|
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("http://host:80"
|
||||||
|
"/file%3Cwith%2%20%20space/"
|
||||||
|
"file%20with%20space;param%"
|
||||||
|
"?a=/?"),
|
||||||
|
file.getRemainingUris()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
void FileEntryTest::testRemoveUri()
|
void FileEntryTest::testRemoveUri()
|
||||||
|
|
|
@ -494,6 +494,14 @@ void HttpResponseTest::testProcessRedirect()
|
||||||
|
|
||||||
httpHeader->clearField();
|
httpHeader->clearField();
|
||||||
|
|
||||||
|
// Test for percent-encode
|
||||||
|
httpHeader->put("Location", "http://example.org/white space#aria2");
|
||||||
|
httpResponse.processRedirect();
|
||||||
|
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
|
||||||
|
request->getCurrentUri());
|
||||||
|
|
||||||
|
httpHeader->clearField();
|
||||||
|
|
||||||
// Give unsupported scheme
|
// Give unsupported scheme
|
||||||
httpHeader->put("Location", "unsupported://mirror/aria2-1.0.0.tar.bz2");
|
httpHeader->put("Location", "unsupported://mirror/aria2-1.0.0.tar.bz2");
|
||||||
try {
|
try {
|
||||||
|
|
|
@ -15,7 +15,6 @@ class RequestTest:public CppUnit::TestFixture {
|
||||||
CPPUNIT_TEST(testSetUri1);
|
CPPUNIT_TEST(testSetUri1);
|
||||||
CPPUNIT_TEST(testSetUri2);
|
CPPUNIT_TEST(testSetUri2);
|
||||||
CPPUNIT_TEST(testSetUri7);
|
CPPUNIT_TEST(testSetUri7);
|
||||||
CPPUNIT_TEST(testSetUri17);
|
|
||||||
CPPUNIT_TEST(testSetUri_supportsPersistentConnection);
|
CPPUNIT_TEST(testSetUri_supportsPersistentConnection);
|
||||||
CPPUNIT_TEST(testRedirectUri);
|
CPPUNIT_TEST(testRedirectUri);
|
||||||
CPPUNIT_TEST(testRedirectUri2);
|
CPPUNIT_TEST(testRedirectUri2);
|
||||||
|
@ -31,7 +30,6 @@ public:
|
||||||
void testSetUri1();
|
void testSetUri1();
|
||||||
void testSetUri2();
|
void testSetUri2();
|
||||||
void testSetUri7();
|
void testSetUri7();
|
||||||
void testSetUri17();
|
|
||||||
void testSetUri_supportsPersistentConnection();
|
void testSetUri_supportsPersistentConnection();
|
||||||
void testRedirectUri();
|
void testRedirectUri();
|
||||||
void testRedirectUri2();
|
void testRedirectUri2();
|
||||||
|
@ -94,27 +92,6 @@ void RequestTest::testSetUri7() {
|
||||||
CPPUNIT_ASSERT(!v);
|
CPPUNIT_ASSERT(!v);
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestTest::testSetUri17()
|
|
||||||
{
|
|
||||||
Request req;
|
|
||||||
bool v = req.setUri("http://host:80/file<with%2 %20space/"
|
|
||||||
"file with space;param%?a=/?");
|
|
||||||
CPPUNIT_ASSERT(v);
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http"), req.getProtocol());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("host"), req.getHost());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("/file%3Cwith%2%20%20space"),
|
|
||||||
req.getDir());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("file%20with%20space;param%"),
|
|
||||||
req.getFile());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("?a=/?"), req.getQuery());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://host:80/file%3Cwith%2%20%20space"
|
|
||||||
"/file%20with%20space;param%?a=/?"),
|
|
||||||
req.getCurrentUri());
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://host:80/file<with%2 %20space"
|
|
||||||
"/file with space;param%?a=/?"),
|
|
||||||
req.getUri());
|
|
||||||
}
|
|
||||||
|
|
||||||
void RequestTest::testRedirectUri()
|
void RequestTest::testRedirectUri()
|
||||||
{
|
{
|
||||||
Request req;
|
Request req;
|
||||||
|
@ -155,11 +132,6 @@ void RequestTest::testRedirectUri()
|
||||||
"relativepath/to/file"),
|
"relativepath/to/file"),
|
||||||
req.getCurrentUri());
|
req.getCurrentUri());
|
||||||
CPPUNIT_ASSERT_EQUAL((unsigned int)3, req.getRedirectCount());
|
CPPUNIT_ASSERT_EQUAL((unsigned int)3, req.getRedirectCount());
|
||||||
|
|
||||||
// White space in path and fragment is appended.
|
|
||||||
CPPUNIT_ASSERT(req.redirectUri("http://example.org/white space#aria2"));
|
|
||||||
CPPUNIT_ASSERT_EQUAL(std::string("http://example.org/white%20space"),
|
|
||||||
req.getCurrentUri());
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void RequestTest::testRedirectUri2()
|
void RequestTest::testRedirectUri2()
|
||||||
|
|
Loading…
Reference in New Issue