2007-11-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

urlencode the given url inside Request::parseUrl(...)
	* src/Request.{h, cc}
	* src/Util.{h, cc}
	* test/RequestTest.cc

	Removed #!metalink3! notation support because it is deleted from
	the metalink specification.
	* src/Request.{h, cc}
	* test/RequestTest.cc
pull/1/head
Tatsuhiro Tsujikawa 2007-11-11 04:25:56 +00:00
parent b5ad009809
commit 4f59dc84bf
6 changed files with 80 additions and 50 deletions

View File

@ -1,3 +1,15 @@
2007-11-11 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
urlencode the given url inside Request::parseUrl(...)
* src/Request.{h, cc}
* src/Util.{h, cc}
* test/RequestTest.cc
Removed #!metalink3! notation support because it is deleted from
the metalink specification.
* src/Request.{h, cc}
* test/RequestTest.cc
2007-11-10 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Don't connect server before checking file integrity at startup, if

View File

@ -66,14 +66,9 @@ bool Request::parseUrl(const string& url) {
string tempUrl;
string::size_type sharpIndex = url.find("#");
if(sharpIndex != string::npos) {
if(FeatureConfig::getInstance()->isSupported("metalink") &&
url.find(METALINK_MARK) == sharpIndex) {
tempUrl = url.substr(sharpIndex+strlen(METALINK_MARK));
tempUrl = urlencode(url.substr(0, sharpIndex));
} else {
tempUrl = url.substr(0, sharpIndex);
}
} else {
tempUrl = url;
tempUrl = urlencode(url);
}
currentUrl = tempUrl;
string query;
@ -83,9 +78,6 @@ bool Request::parseUrl(const string& url) {
file = "";
_username = "";
_password = "";
if(tempUrl.find_first_not_of(SAFE_CHARS) != string::npos) {
return false;
}
// find query part
string::size_type startQueryIndex = tempUrl.find("?");
if(startQueryIndex != string::npos) {
@ -152,3 +144,31 @@ bool Request::parseUrl(const string& url) {
file += query;
return true;
}
bool Request::isHexNumber(const char c) const
{
return '0' <= c && c <= '9' || 'A' <= c && c <= 'F' || 'a' <= c && c <= 'f';
}
string Request::urlencode(const string& src) const
{
int32_t lastIndex = src.size()-1;
string result = src+" ";
for(int32_t index = lastIndex; index >= 0; --index) {
const char c = result[index];
// '/' is not urlencoded because src is expected to be a path.
if(Util::shouldUrlencode(c)) {
if(c == '%') {
if(!isHexNumber(result[index+1]) || !isHexNumber(result[index+2])) {
result.replace(index, 1, "%25");
}
} else {
char temp[4];
sprintf(temp, "%%%02x", c);
temp[3] = '\0';
result.replace(index, 1, temp);
}
}
}
return result.substr(0, result.size()-2);
}

View File

@ -46,8 +46,6 @@
"%"\
"#"
#define METALINK_MARK "#!metalink3!"
class Request {
public:
enum TRACKER_EVENT {
@ -83,6 +81,11 @@ private:
string _password;
bool parseUrl(const string& url);
bool isHexNumber(const char c) const;
string urlencode(const string& src) const;
public:
CookieBoxHandle cookieBox;
public:

View File

@ -247,18 +247,26 @@ string Util::replace(const string& target, const string& oldstr, const string& n
return result;
}
bool Util::shouldUrlencode(const char c)
{
return !(// ALPHA
'A' <= c && c <= 'Z' || 'a' <= c && c <= 'z' ||
// DIGIT
'0' <= c && c <= '9' ||
// safe
'$' == c || '-' == c || '_' == c || '.' == c ||
// extra
'!' == c || '*' == c || '\'' == c ||'(' == c ||
')' == c || ',' == c ||
// reserved
';' == c || '/' == c || '?' == c || ':' == c ||
'@' == c || '&' == c || '=' == c || '+' == c);
}
string Util::urlencode(const unsigned char* target, int32_t len) {
string dest;
for(int32_t i = 0; i < len; i++) {
if(!('0' <= target[i] && target[i] <= '9' ||
'A' <= target[i] && target[i] <= 'Z' ||
'a' <= target[i] && target[i] <= 'z' ||
'$' == target[i] || '-' == target[i] ||
'_' == target[i] || '.' == target[i] ||
'+' == target[i] || '!' == target[i] ||
'*' == target[i] || '\'' == target[i] ||
'(' == target[i] || ')' == target[i] ||
',' == target[i])) {
if(shouldUrlencode(target[i])) {
char temp[4];
sprintf(temp, "%%%02x", target[i]);
temp[sizeof(temp)-1] = '\0';

View File

@ -89,6 +89,8 @@ public:
return urlencode((const unsigned char*)target.c_str(), target.size());
}
static bool shouldUrlencode(const char c);
static string urldecode(const string& target);
static string torrentUrlencode(const unsigned char* target, int32_t len);

View File

@ -23,15 +23,14 @@ class RequestTest:public CppUnit::TestFixture {
CPPUNIT_TEST(testSetUrl14);
CPPUNIT_TEST(testSetUrl15);
CPPUNIT_TEST(testSetUrl16);
CPPUNIT_TEST(testSetUrl17);
CPPUNIT_TEST(testSetUrl_username);
CPPUNIT_TEST(testSetUrl_usernamePassword);
CPPUNIT_TEST(testSetUrl_zeroUsername);
CPPUNIT_TEST(testRedirectUrl);
CPPUNIT_TEST(testRedirectUrl2);
CPPUNIT_TEST(testResetUrl);
CPPUNIT_TEST(testSafeChar);
CPPUNIT_TEST(testInnerLink);
CPPUNIT_TEST(testMetalink);
CPPUNIT_TEST_SUITE_END();
public:
@ -51,15 +50,14 @@ public:
void testSetUrl14();
void testSetUrl15();
void testSetUrl16();
void testSetUrl17();
void testSetUrl_username();
void testSetUrl_usernamePassword();
void testSetUrl_zeroUsername();
void testRedirectUrl();
void testRedirectUrl2();
void testResetUrl();
void testSafeChar();
void testInnerLink();
void testMetalink();
};
@ -245,6 +243,17 @@ void RequestTest::testSetUrl16()
CPPUNIT_ASSERT_EQUAL(string("file"), req.getFile());
}
void RequestTest::testSetUrl17()
{
Request req;
bool v = req.setUrl("http://host:80/file<with%2 %20space/file with space;param?a=/?");
CPPUNIT_ASSERT(v);
CPPUNIT_ASSERT_EQUAL(string("http"), req.getProtocol());
CPPUNIT_ASSERT_EQUAL(string("host"), req.getHost());
CPPUNIT_ASSERT_EQUAL(string("/file%3cwith%252%20%20space"), req.getDir());
CPPUNIT_ASSERT_EQUAL(string("file%20with%20space;param?a=/?"), req.getFile());
}
void RequestTest::testRedirectUrl() {
Request req;
req.setKeepAlive(true);
@ -310,12 +319,6 @@ void RequestTest::testResetUrl() {
CPPUNIT_ASSERT_EQUAL(string("index.html"), req.getFile());
}
void RequestTest::testSafeChar() {
Request req;
bool v = req.setUrl("http://aria.rednoah.com/|<>");
CPPUNIT_ASSERT(!v);
}
void RequestTest::testInnerLink() {
Request req;
bool v = req.setUrl("http://aria.rednoah.com/index.html#download");
@ -323,24 +326,6 @@ void RequestTest::testInnerLink() {
CPPUNIT_ASSERT_EQUAL(string("index.html"), req.getFile());
}
void RequestTest::testMetalink() {
Request req;
bool v = req.setUrl("http://aria.rednoah.com/download/aria.tar.bz2#!metalink3!http://aria2.sourceforge.net/download/aria.metalink");
CPPUNIT_ASSERT(v);
#ifdef ENABLE_METALINK
CPPUNIT_ASSERT_EQUAL(string("aria2.sourceforge.net"), req.getHost());
CPPUNIT_ASSERT_EQUAL(string("/download"), req.getDir());
CPPUNIT_ASSERT_EQUAL(string("aria.metalink"), req.getFile());
bool v2 = req.setUrl("http://aria.rednoah.com/download/aria.tar.bz2#!metalink3!");
CPPUNIT_ASSERT(!v2);
#else
CPPUNIT_ASSERT_EQUAL(string("aria.rednoah.com"), req.getHost());
CPPUNIT_ASSERT_EQUAL(string("/download"), req.getDir());
CPPUNIT_ASSERT_EQUAL(string("aria.tar.bz2"), req.getFile());
#endif // ENABLE_METALINK
}
void RequestTest::testSetUrl_zeroUsername()
{
Request req;