2008-04-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>

Added --header option. You can specify any number of additional 
HTTP headers
	like:
	aria2 --header="X-A: 300" --header="X-B: 900" http://host/file
	Unlike other commad-line option, you can use --header option 
multiple times.
	* src/HelpItemFactory.cc
	* src/HttpRequest.{cc, h}
	* src/HttpRequestCommand.cc
	* src/OptionHandlerFactory.cc
	* src/OptionHandlerImpl.h
	* src/option_processing.cc
	* src/prefs.h
	* src/usage_text.h
	* test/HttpRequestTest.cc (testUserHeaders)
pull/1/head
Tatsuhiro Tsujikawa 2008-04-20 06:30:44 +00:00
parent c1c5e7369f
commit 3eb74629cb
11 changed files with 98 additions and 1 deletions

View File

@ -1,3 +1,19 @@
2008-04-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Added --header option. You can specify any number of additional HTTP headers
like:
aria2 --header="X-A: 300" --header="X-B: 900" http://host/file
Unlike other commad-line option, you can use --header option multiple times.
* src/HelpItemFactory.cc
* src/HttpRequest.{cc, h}
* src/HttpRequestCommand.cc
* src/OptionHandlerFactory.cc
* src/OptionHandlerImpl.h
* src/option_processing.cc
* src/prefs.h
* src/usage_text.h
* test/HttpRequestTest.cc (testUserHeaders)
2008-04-20 Tatsuhiro Tsujikawa <tujikawa at rednoah dot com>
Eliminates the time lag between sequential downloads and commands in

View File

@ -432,6 +432,11 @@ TagContainerHandle HelpItemFactory::createHelpItems()
item->addTag(TAG_ADVANCED);
tc->addItem(item);
}
{
HelpItemHandle item(new HelpItem(PREF_HEADER, TEXT_HEADER));
item->addTag(TAG_ADVANCED);
tc->addItem(item);
}
{
HelpItemHandle item(new HelpItem("help", TEXT_HELP, TAG_BASIC));
char buf[64];

View File

@ -44,6 +44,7 @@
#include "prefs.h"
#include "AuthConfigFactory.h"
#include "AuthConfig.h"
#include <numeric>
namespace aria2 {
@ -190,6 +191,12 @@ std::string HttpRequest::createRequest() const
if(cookiesValue.size()) {
requestLine += std::string("Cookie: ")+cookiesValue+"\r\n";
}
// append additional headers given by user.
for(std::deque<std::string>::const_iterator i = _userHeaders.begin();
i != _userHeaders.end(); ++i) {
requestLine += (*i)+"\r\n";
}
requestLine += "\r\n";
return requestLine;
}
@ -218,6 +225,13 @@ std::string HttpRequest::getProxyAuthString() const {
Base64::encode(AuthConfigFactorySingleton::instance()->createAuthConfigForHttpProxy(request)->getAuthText())+"\r\n";
}
void HttpRequest::setUserHeaders(const std::string& userHeadersString)
{
std::deque<std::string> headers;
Util::slice(headers, userHeadersString, '\n', true);
_userHeaders = headers;
}
void HttpRequest::configure(const Option* option)
{
authEnabled = option->get(PREF_HTTP_AUTH_ENABLED) == V_TRUE;

View File

@ -66,6 +66,8 @@ private:
std::string userAgent;
std::deque<std::string> _userHeaders;
std::string getHostText(const std::string& host, uint16_t port) const;
std::string getProxyAuthString() const;
@ -164,6 +166,8 @@ public:
{
this->userAgent = userAgent;
}
void setUserHeaders(const std::string& userHeaders);
};
typedef SharedHandle<HttpRequest> HttpRequestHandle;

View File

@ -84,6 +84,7 @@ bool HttpRequestCommand::executeInternal() {
httpRequest->setUserAgent(e->option->get(PREF_USER_AGENT));
httpRequest->setRequest(req);
httpRequest->setEntityLength(_requestGroup->getTotalLength());
httpRequest->setUserHeaders(e->option->get(PREF_HEADER));
httpRequest->configure(e->option);
_httpConnection->sendRequest(httpRequest);

View File

@ -126,7 +126,7 @@ OptionHandlers OptionHandlerFactory::createOptionHandlers()
handlers.push_back(SH(new NumberOptionHandler(PREF_STOP, 0, INT32_MAX)));
handlers.push_back(SH(new ParameterOptionHandler(PREF_BT_MIN_CRYPTO_LEVEL, V_PLAIN, V_ARC4)));
handlers.push_back(SH(new BooleanOptionHandler(PREF_BT_REQUIRE_CRYPTO)));
handlers.push_back(SH(new CumulativeOptionHandler(PREF_HEADER, "\n")));
return handlers;
}

View File

@ -192,6 +192,25 @@ public:
}
};
class CumulativeOptionHandler : public NameMatchOptionHandler {
private:
std::string _delim;
public:
CumulativeOptionHandler(const std::string& optName,
const std::string& delim):
NameMatchOptionHandler(optName),
_delim(delim) {}
virtual ~CumulativeOptionHandler() {}
virtual void parseArg(Option* option, const std::string& optarg)
{
std::string value = option->get(_optName);
value += optarg+_delim;
option->put(_optName, value);
}
};
class ParameterOptionHandler : public NameMatchOptionHandler {
private:
std::deque<std::string> _validParamValues;

View File

@ -204,6 +204,7 @@ Option* option_processing(int argc, char* const argv[])
{ PREF_NO_CONF, no_argument, &lopt, 212 },
{ PREF_CONF_PATH, required_argument, &lopt, 213 },
{ PREF_STOP, required_argument, &lopt, 214 },
{ PREF_HEADER, required_argument, &lopt, 215 },
#if defined ENABLE_BITTORRENT || ENABLE_METALINK
{ PREF_SHOW_FILES, no_argument, NULL, 'S' },
{ PREF_SELECT_FILE, required_argument, &lopt, 21 },
@ -402,6 +403,9 @@ Option* option_processing(int argc, char* const argv[])
case 214:
cmdstream << PREF_STOP << "=" << optarg << "\n";
break;
case 215:
cmdstream << PREF_HEADER << "=" << optarg << "\n";
break;
}
break;
}

View File

@ -163,6 +163,8 @@
#define PREF_ENABLE_HTTP_PIPELINING "enable-http-pipelining"
// value: 1*digit
#define PREF_MAX_HTTP_PIPELINING "max-http-pipelining"
// value: string
#define PREF_HEADER "header"
/**
* HTTP proxy related preferences

View File

@ -330,3 +330,9 @@ _(" --conf-path=PATH Change the configuration file path to PATH.")
#define TEXT_STOP \
_(" --stop=SEC Stop application after SEC seconds has passed.\n" \
" If 0 is given, this feature is disabled.")
#define TEXT_HEADER \
_(" --header=HEADER Append HEADER to HTTP request header. You can use\n"\
" this option repeatedly to specify more than one\n"\
" header:\n"\
" aria2c --header=\"X-A: b78\" --header=\"X-B: 9J1\"\n"\
" http://host/file")

View File

@ -22,6 +22,7 @@ class HttpRequestTest : public CppUnit::TestFixture {
CPPUNIT_TEST(testCreateProxyRequest);
CPPUNIT_TEST(testIsRangeSatisfied);
CPPUNIT_TEST(testUserAgent);
CPPUNIT_TEST(testUserHeaders);
CPPUNIT_TEST_SUITE_END();
private:
@ -36,6 +37,7 @@ public:
void testCreateProxyRequest();
void testIsRangeSatisfied();
void testUserAgent();
void testUserHeaders();
};
@ -557,4 +559,28 @@ void HttpRequestTest::testUserAgent()
CPPUNIT_ASSERT_EQUAL(expectedTextForProxy, httpRequest.createProxyRequest());
}
void HttpRequestTest::testUserHeaders()
{
SharedHandle<Request> request(new Request());
request->setUrl("http://localhost/archives/aria2-1.0.0.tar.bz2");
HttpRequest httpRequest;
httpRequest.setRequest(request);
httpRequest.setUserHeaders("X-ARIA2: v0.13\nX-ARIA2-DISTRIBUTE: enabled\n");
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"
"\r\n";
CPPUNIT_ASSERT_EQUAL(expectedText, httpRequest.createRequest());
}
} // namespace aria2