summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-02-20 12:55:23 +0000
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2010-02-20 12:55:23 +0000
commitaee471e52c6f7ac06817600e2c21b400ef375ecb (patch)
tree83d507c3279d5c7b25e8c8c882ffa9c5879e4d28
parentf1ee4045c247b37df62a566e67c2ba2715cda12a (diff)
2010-02-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
User-defined custom request headers specified by --header option now override builtin headers if they have same name. * src/HttpRequest.cc * src/HttpRequest.h * test/HttpRequestTest.cc
-rw-r--r--ChangeLog8
-rw-r--r--src/HttpRequest.cc101
-rw-r--r--src/HttpRequest.h5
-rw-r--r--test/HttpRequestTest.cc4
4 files changed, 73 insertions, 45 deletions
diff --git a/ChangeLog b/ChangeLog
index c9cf2b54..d616f74f 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,11 @@
+2010-02-20 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
+
+ User-defined custom request headers specified by --header option
+ now override builtin headers if they have same name.
+ * src/HttpRequest.cc
+ * src/HttpRequest.h
+ * test/HttpRequestTest.cc
+
2010-02-19 Tatsuhiro Tsujikawa <t-tujikawa@users.sourceforge.net>
Rewirtten util::isNumber()
diff --git a/src/HttpRequest.cc b/src/HttpRequest.cc
index 7e9cc051..27f27382 100644
--- a/src/HttpRequest.cc
+++ b/src/HttpRequest.cc
@@ -49,6 +49,7 @@
#include "AuthConfig.h"
#include "a2functional.h"
#include "TimeA2.h"
+#include "array_fun.h"
namespace aria2 {
@@ -155,59 +156,63 @@ std::string HttpRequest::createRequest()
requestLine += getQuery();
}
requestLine += " HTTP/1.1\r\n";
- strappend(requestLine, "User-Agent: ", userAgent, "\r\n");
-
- requestLine += "Accept: */*"; /* */
- for(std::deque<std::string>::const_iterator i = _acceptTypes.begin();
- i != _acceptTypes.end(); ++i) {
- strappend(requestLine, ",", (*i));
- }
- requestLine += "\r\n";
+ std::vector<std::pair<std::string, std::string> > builtinHds;
+ builtinHds.reserve(20);
+ builtinHds.push_back(std::make_pair("User-Agent:", userAgent));
+ std::string acceptTypes = "*/*";
+ for(std::deque<std::string>::const_iterator i = _acceptTypes.begin(),
+ end = _acceptTypes.end(); i != end; ++i) {
+ strappend(acceptTypes, ",", (*i));
+ }
+ builtinHds.push_back(std::make_pair("Accept:", acceptTypes));
if(_contentEncodingEnabled) {
std::string acceptableEncodings;
#ifdef HAVE_LIBZ
acceptableEncodings += "deflate, gzip";
#endif // HAVE_LIBZ
if(!acceptableEncodings.empty()) {
- strappend(requestLine, "Accept-Encoding: ", acceptableEncodings, "\r\n");
+ builtinHds.push_back
+ (std::make_pair("Accept-Encoding:", acceptableEncodings));
}
}
-
- strappend(requestLine, "Host: ", getHostText(getURIHost(), getPort()), "\r\n");
+ builtinHds.push_back
+ (std::make_pair("Host:", getHostText(getURIHost(), getPort())));
if(_noCache) {
- requestLine += "Pragma: no-cache\r\n";
- requestLine += "Cache-Control: no-cache\r\n";
+ builtinHds.push_back(std::make_pair("Pragma:", "no-cache"));
+ builtinHds.push_back(std::make_pair("Cache-Control:", "no-cache"));
}
if(!request->isKeepAliveEnabled() && !request->isPipeliningEnabled()) {
- requestLine += "Connection: close\r\n";
+ builtinHds.push_back(std::make_pair("Connection:", "close"));
}
if(!segment.isNull() && segment->getLength() > 0 &&
(request->isPipeliningEnabled() || getStartByte() > 0)) {
- requestLine += "Range: bytes=";
- requestLine += util::itos(getStartByte());
- requestLine += "-";
+ std::string rangeHeader = "bytes=";
+ rangeHeader += util::itos(getStartByte());
+ rangeHeader += "-";
if(request->isPipeliningEnabled()) {
- requestLine += util::itos(getEndByte());
+ rangeHeader += util::itos(getEndByte());
}
- requestLine += "\r\n";
+ builtinHds.push_back(std::make_pair("Range:", rangeHeader));
}
if(!_proxyRequest.isNull()) {
if(request->isKeepAliveEnabled() || request->isPipeliningEnabled()) {
- requestLine += "Proxy-Connection: Keep-Alive\r\n";
+ builtinHds.push_back(std::make_pair("Proxy-Connection:", "Keep-Alive"));
} else {
- requestLine += "Proxy-Connection: close\r\n";
+ builtinHds.push_back(std::make_pair("Proxy-Connection:", "close"));
}
}
if(!_proxyRequest.isNull() && !_proxyRequest->getUsername().empty()) {
- requestLine += getProxyAuthString();
+ builtinHds.push_back(getProxyAuthString());
}
if(!_authConfig.isNull()) {
- strappend(requestLine, "Authorization: Basic ",
- Base64::encode(_authConfig->getAuthText()), "\r\n");
+ builtinHds.push_back
+ (std::make_pair("Authorization:",
+ strconcat("Basic ",
+ Base64::encode(_authConfig->getAuthText()))));
}
if(getPreviousURI().size()) {
- strappend(requestLine, "Referer: ", getPreviousURI(), "\r\n");
+ builtinHds.push_back(std::make_pair("Referer:", getPreviousURI()));
}
if(!_cookieStorage.isNull()) {
std::string cookiesValue;
@@ -217,21 +222,33 @@ std::string HttpRequest::createRequest()
Time().getTime(),
getProtocol() == Request::PROTO_HTTPS ?
true : false);
- for(std::deque<Cookie>::const_iterator itr = cookies.begin();
- itr != cookies.end(); ++itr) {
+ for(std::deque<Cookie>::const_iterator itr = cookies.begin(),
+ end = cookies.end(); itr != end; ++itr) {
strappend(cookiesValue, (*itr).toString(), ";");
}
if(!cookiesValue.empty()) {
- strappend(requestLine, "Cookie: ", cookiesValue, "\r\n");
+ builtinHds.push_back(std::make_pair("Cookie:", cookiesValue));
+ }
+ }
+ for(std::vector<std::pair<std::string, std::string> >::iterator i =
+ builtinHds.begin(); i != builtinHds.end(); ++i) {
+ std::vector<std::string>::const_iterator j = _headers.begin();
+ std::vector<std::string>::const_iterator jend = _headers.end();
+ for(; j != jend; ++j) {
+ if(util::startsWith(*j, (*i).first)) {
+ break;
+ }
+ }
+ if(j == jend) {
+ strappend(requestLine, (*i).first, " ", (*i).second, A2STR::CRLF);
}
}
// append additional headers given by user.
- for(std::deque<std::string>::const_iterator i = _headers.begin();
- i != _headers.end(); ++i) {
- strappend(requestLine, (*i), "\r\n");
+ for(std::vector<std::string>::const_iterator i = _headers.begin(),
+ end = _headers.end(); i != end; ++i) {
+ strappend(requestLine, (*i), A2STR::CRLF);
}
-
- requestLine += "\r\n";
+ requestLine += A2STR::CRLF;
return requestLine;
}
@@ -252,19 +269,21 @@ std::string HttpRequest::createProxyRequest() const
// requestLine += "Proxy-Connection: close\r\n";
// }
if(!_proxyRequest->getUsername().empty()) {
- requestLine += getProxyAuthString();
+ std::pair<std::string, std::string> auth = getProxyAuthString();
+ strappend(requestLine, auth.first, " ", auth.second, A2STR::CRLF);
}
- requestLine += "\r\n";
+ requestLine += A2STR::CRLF;
return requestLine;
}
-std::string HttpRequest::getProxyAuthString() const
+std::pair<std::string, std::string> HttpRequest::getProxyAuthString() const
{
- return strconcat("Proxy-Authorization: Basic ",
- Base64::encode(strconcat(_proxyRequest->getUsername(),
- ":",
- _proxyRequest->getPassword())),
- "\r\n");
+ return std::make_pair
+ ("Proxy-Authorization:",
+ strconcat("Basic ",
+ Base64::encode(strconcat(_proxyRequest->getUsername(),
+ ":",
+ _proxyRequest->getPassword()))));
}
void HttpRequest::enableContentEncoding()
diff --git a/src/HttpRequest.h b/src/HttpRequest.h
index 2ba46a3f..56e9d245 100644
--- a/src/HttpRequest.h
+++ b/src/HttpRequest.h
@@ -40,6 +40,7 @@
#include <cassert>
#include <string>
#include <deque>
+#include <vector>
#include "SharedHandle.h"
#include "Request.h"
@@ -69,7 +70,7 @@ private:
std::string userAgent;
- std::deque<std::string> _headers;
+ std::vector<std::string> _headers;
std::deque<std::string> _acceptTypes;
@@ -85,7 +86,7 @@ private:
bool _noCache;
- std::string getProxyAuthString() const;
+ std::pair<std::string, std::string> getProxyAuthString() const;
public:
HttpRequest();
diff --git a/test/HttpRequestTest.cc b/test/HttpRequestTest.cc
index 1e600172..b03e410c 100644
--- a/test/HttpRequestTest.cc
+++ b/test/HttpRequestTest.cc
@@ -663,16 +663,16 @@ void HttpRequestTest::testAddHeader()
httpRequest.setRequest(request);
httpRequest.setAuthConfigFactory(_authConfigFactory, _option.get());
httpRequest.addHeader("X-ARIA2: v0.13\nX-ARIA2-DISTRIBUTE: enabled\n");
-
+ httpRequest.addHeader("Accept: text/html");
std::string expectedText = "GET /archives/aria2-1.0.0.tar.bz2 HTTP/1.1\r\n"
"User-Agent: aria2\r\n"
- "Accept: */*\r\n"
"Host: localhost\r\n"
"Pragma: no-cache\r\n"
"Cache-Control: no-cache\r\n"
"Connection: close\r\n"
"X-ARIA2: v0.13\r\n"
"X-ARIA2-DISTRIBUTE: enabled\r\n"
+ "Accept: text/html\r\n"
"\r\n";
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());