diff options
| author | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-08-30 15:05:30 +0000 |
|---|---|---|
| committer | Tatsuhiro Tsujikawa <tatsuhiro.t@gmail.com> | 2009-08-30 15:05:30 +0000 |
| commit | ce25b54cfe3ba23408da19fcd87539bec879b943 (patch) | |
| tree | b60b7edf6f808aee791b72ecdc64131d3d36665d /src | |
| parent | 19ae8f9d07ba6a8f1d3b6f501a01f9285b6875e9 (diff) | |
2009-08-31 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Added support for IPv6 literal address in URI. Now aria2 can
handle URI such as http://[::1]/
* src/HttpRequest.cc
* src/HttpRequest.h
* src/Request.cc
* src/Request.h
* test/HttpRequestTest.cc
* test/OptionHandlerTest.cc
* test/RequestTest.cc
Diffstat (limited to 'src')
| -rw-r--r-- | src/HttpRequest.cc | 6 | ||||
| -rw-r--r-- | src/HttpRequest.h | 7 | ||||
| -rw-r--r-- | src/Request.cc | 48 | ||||
| -rw-r--r-- | src/Request.h | 14 |
4 files changed, 56 insertions, 19 deletions
diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc index 3c4e8f06..63bdc557 100644 --- a/src/HttpRequest.cc +++ b/src/HttpRequest.cc @@ -117,7 +117,7 @@ bool HttpRequest::isRangeSatisfied(const RangeHandle& range) const } } -std::string HttpRequest::getHostText(const std::string& host, uint16_t port) const +static std::string getHostText(const std::string& host, uint16_t port) { std::string hosttext = host; if(!(port == 80 || port == 443)) { @@ -172,7 +172,7 @@ std::string HttpRequest::createRequest() } } - strappend(requestLine, "Host: ", getHostText(getHost(), getPort()), "\r\n"); + strappend(requestLine, "Host: ", getHostText(getURIHost(), getPort()), "\r\n"); requestLine += "Pragma: no-cache\r\n"; requestLine += "Cache-Control: no-cache\r\n"; @@ -235,7 +235,7 @@ std::string HttpRequest::createRequest() std::string HttpRequest::createProxyRequest() const { assert(!_proxyRequest.isNull()); - std::string hostport = getHost(); + std::string hostport = getURIHost(); strappend(hostport, ":", Util::uitos(getPort())); std::string requestLine = "CONNECT "; diff --git a/src/HttpRequest.h b/src/HttpRequest.h index 18a0768b..b32b614b 100644 --- a/src/HttpRequest.h +++ b/src/HttpRequest.h @@ -83,8 +83,6 @@ private: SharedHandle<Request> _proxyRequest; - std::string getHostText(const std::string& host, uint16_t port) const; - std::string getProxyAuthString() const; public: HttpRequest(); @@ -149,6 +147,11 @@ public: return request->getPreviousUrl(); } + std::string getURIHost() const + { + return request->getURIHost(); + } + SharedHandle<Range> getRange() const; /** diff --git a/src/Request.cc b/src/Request.cc index ee9d7c0a..e055811f 100644 --- a/src/Request.cc +++ b/src/Request.cc @@ -71,7 +71,8 @@ Request::Request(): _keepAliveHint(false), _pipeliningHint(false), _maxPipelinedRequest(1), - method(METHOD_GET) + method(METHOD_GET), + _ipv6LiteralAddress(false) {} static std::string removeFragment(const std::string url) @@ -160,6 +161,7 @@ bool Request::parseUrl(const std::string& url) { _query = A2STR::NIL; _username = A2STR::NIL; _password = A2STR::NIL; + _ipv6LiteralAddress = false; // find query part std::string queryTemp; std::string::size_type startQueryIndex = tempUrl.find("?"); @@ -193,22 +195,40 @@ bool Request::parseUrl(const std::string& url) { _password = Util::urldecode(userPass.second); hostPart.erase(0, atmarkp+1); } - std::pair<std::string, std::string> hostAndPort; - Util::split(hostAndPort, hostPart, ':'); - host = hostAndPort.first; - if(hostAndPort.second != A2STR::NIL) { - try { - unsigned int tempPort = Util::parseUInt(hostAndPort.second); - if(65535 < tempPort) { + { + std::string::size_type colonpos; + // Detect IPv6 literal address in square brackets + if(Util::startsWith(hostPart, "[")) { + std::string::size_type rbracketpos = hostPart.find("]"); + if(rbracketpos == std::string::npos) { return false; } - port = tempPort; - } catch(RecoverableException& e) { - return false; + _ipv6LiteralAddress = true; + colonpos = hostPart.find(":", rbracketpos+1); + } else { + colonpos = hostPart.find_last_of(":"); + } + if(colonpos == std::string::npos) { + colonpos = hostPart.size(); + // If port is not specified, then we set it to default port of + // its protocol.. + port = defPort; + } else { + try { + unsigned int tempPort = Util::parseUInt(hostPart.substr(colonpos+1)); + if(65535 < tempPort) { + return false; + } + port = tempPort; + } catch(RecoverableException& e) { + return false; + } + } + if(_ipv6LiteralAddress) { + host = hostPart.substr(1, colonpos-2); + } else { + host = hostPart.substr(0, colonpos); } - } else { - // If port is not specified, then we set it to default port of its protocol.. - port = defPort; } // find directory and file part std::string::size_type direp = tempUrl.find_last_of("/"); diff --git a/src/Request.h b/src/Request.h index cab16999..5c88cf62 100644 --- a/src/Request.h +++ b/src/Request.h @@ -41,6 +41,7 @@ #include "SharedHandle.h" #include "PeerStat.h" +#include "a2functional.h" namespace aria2 { @@ -82,6 +83,8 @@ private: std::string _password; + bool _ipv6LiteralAddress; + SharedHandle<PeerStat> _peerStat; bool parseUrl(const std::string& url); @@ -116,10 +119,21 @@ public: void setReferer(const std::string& url); const std::string& getProtocol() const { return protocol; } const std::string& getHost() const { return host; } + // Same as getHost(), but for IPv6 literal addresses, enclose them + // with square brackets and return. + std::string getURIHost() const + { + if(isIPv6LiteralAddress()) { + return strconcat("[", getHost(), "]"); + } else { + return getHost(); + } + } uint16_t getPort() const { return port; } const std::string& getDir() const { return dir; } const std::string& getFile() const { return file;} const std::string& getQuery() const { return _query; } + bool isIPv6LiteralAddress() const { return _ipv6LiteralAddress; } void supportsPersistentConnection(bool f) { |
