mirror of https://github.com/aria2/aria2
Accept HTTP 304 reply as success when If-None-Match request-header
field is specified using --header option. When --conditional-get is used, --allow-overwrite is now required to overwrite existing file.pull/1/head
parent
7a6ec762ef
commit
1b9329c67c
|
@ -322,6 +322,11 @@ void HttpRequest::addHeader(const std::string& headersString)
|
|||
headers_.insert(headers_.end(), headers.begin(), headers.end());
|
||||
}
|
||||
|
||||
void HttpRequest::clearHeader()
|
||||
{
|
||||
headers_.clear();
|
||||
}
|
||||
|
||||
void HttpRequest::addAcceptType(const std::string& type)
|
||||
{
|
||||
acceptTypes_.push_back(type);
|
||||
|
@ -431,4 +436,20 @@ void HttpRequest::setIfModifiedSinceHeader(const std::string& hd)
|
|||
ifModSinceHeader_ = hd;
|
||||
}
|
||||
|
||||
bool HttpRequest::conditionalRequest() const
|
||||
{
|
||||
if(!ifModSinceHeader_.empty()) {
|
||||
return true;
|
||||
}
|
||||
for(std::vector<std::string>::const_iterator i = headers_.begin(),
|
||||
eoi = headers_.end(); i != eoi; ++i) {
|
||||
std::string hd = util::toLower(*i);
|
||||
if(util::startsWith(hd, "if-modified-since") ||
|
||||
util::startsWith(hd, "if-none-match")) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -168,6 +168,8 @@ public:
|
|||
// accepts multiline headers, delimited by LF
|
||||
void addHeader(const std::string& headers);
|
||||
|
||||
void clearHeader();
|
||||
|
||||
void addAcceptType(const std::string& type);
|
||||
|
||||
template<typename InputIterator>
|
||||
|
@ -249,6 +251,11 @@ public:
|
|||
{
|
||||
return ifModSinceHeader_;
|
||||
}
|
||||
|
||||
// Returns true if request is conditional:more specifically, the
|
||||
// request is considered to be conditional if the client sent
|
||||
// "If-Modified-Since" or "If-None-Match" request-header field.
|
||||
bool conditionalRequest() const;
|
||||
};
|
||||
|
||||
} // namespace aria2
|
||||
|
|
|
@ -70,8 +70,8 @@ void HttpResponse::validateResponse() const
|
|||
return;
|
||||
}
|
||||
if(statusCode == 304) {
|
||||
if(httpRequest_->getIfModifiedSinceHeader().empty()) {
|
||||
throw DL_ABORT_EX2("Got 304 without If-Modified-Since",
|
||||
if(!httpRequest_->conditionalRequest()) {
|
||||
throw DL_ABORT_EX2("Got 304 without If-Modified-Since or If-None-Match",
|
||||
error_code::HTTP_PROTOCOL_ERROR);
|
||||
}
|
||||
} else if(statusCode == 301 ||
|
||||
|
|
|
@ -174,26 +174,22 @@ bool HttpResponseCommand::executeInternal()
|
|||
}
|
||||
|
||||
int statusCode = httpResponse->getStatusCode();
|
||||
if(!httpResponse->getHttpRequest()->getIfModifiedSinceHeader().empty()) {
|
||||
if(statusCode == 304) {
|
||||
uint64_t totalLength = httpResponse->getEntityLength();
|
||||
getFileEntry()->setLength(totalLength);
|
||||
getRequestGroup()->initPieceStorage();
|
||||
getPieceStorage()->markAllPiecesDone();
|
||||
// Just set checksum verification done.
|
||||
getDownloadContext()->setChecksumVerified(true);
|
||||
A2_LOG_NOTICE(fmt(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(getRequestGroup()->getGID()).c_str(),
|
||||
getRequestGroup()->getFirstFilePath().c_str()));
|
||||
poolConnection();
|
||||
getFileEntry()->poolRequest(getRequest());
|
||||
return true;
|
||||
} else if(statusCode == 200 || statusCode == 206) {
|
||||
// Remote file is newer than local file. We allow overwrite.
|
||||
getOption()->put(PREF_ALLOW_OVERWRITE, A2_V_TRUE);
|
||||
}
|
||||
|
||||
if(statusCode == 304) {
|
||||
uint64_t totalLength = httpResponse->getEntityLength();
|
||||
getFileEntry()->setLength(totalLength);
|
||||
getRequestGroup()->initPieceStorage();
|
||||
getPieceStorage()->markAllPiecesDone();
|
||||
// Just set checksum verification done.
|
||||
getDownloadContext()->setChecksumVerified(true);
|
||||
A2_LOG_NOTICE(fmt(MSG_DOWNLOAD_ALREADY_COMPLETED,
|
||||
util::itos(getRequestGroup()->getGID()).c_str(),
|
||||
getRequestGroup()->getFirstFilePath().c_str()));
|
||||
poolConnection();
|
||||
getFileEntry()->poolRequest(getRequest());
|
||||
return true;
|
||||
}
|
||||
if(statusCode != 304 && statusCode >= 300) {
|
||||
if(statusCode >= 300) {
|
||||
if(statusCode == 404) {
|
||||
getRequestGroup()->increaseAndValidateFileNotFoundCount();
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ class HttpRequestTest : public CppUnit::TestFixture {
|
|||
CPPUNIT_TEST(testAddHeader);
|
||||
CPPUNIT_TEST(testAddAcceptType);
|
||||
CPPUNIT_TEST(testEnableAcceptEncoding);
|
||||
CPPUNIT_TEST(testConditionalRequest);
|
||||
CPPUNIT_TEST_SUITE_END();
|
||||
private:
|
||||
SharedHandle<Option> option_;
|
||||
|
@ -64,6 +65,7 @@ public:
|
|||
void testAddHeader();
|
||||
void testAddAcceptType();
|
||||
void testEnableAcceptEncoding();
|
||||
void testConditionalRequest();
|
||||
};
|
||||
|
||||
|
||||
|
@ -843,4 +845,19 @@ void HttpRequestTest::testCreateRequest_ipv6LiteralAddr()
|
|||
CPPUNIT_ASSERT(proxyRequest.find("CONNECT [::1]:80 ") != std::string::npos);
|
||||
}
|
||||
|
||||
void HttpRequestTest::testConditionalRequest()
|
||||
{
|
||||
HttpRequest httpRequest;
|
||||
CPPUNIT_ASSERT(!httpRequest.conditionalRequest());
|
||||
httpRequest.setIfModifiedSinceHeader("dummy");
|
||||
CPPUNIT_ASSERT(httpRequest.conditionalRequest());
|
||||
httpRequest.setIfModifiedSinceHeader("");
|
||||
CPPUNIT_ASSERT(!httpRequest.conditionalRequest());
|
||||
httpRequest.addHeader("If-None-Match: *");
|
||||
CPPUNIT_ASSERT(httpRequest.conditionalRequest());
|
||||
httpRequest.clearHeader();
|
||||
httpRequest.addHeader("If-Modified-Since: dummy");
|
||||
CPPUNIT_ASSERT(httpRequest.conditionalRequest());
|
||||
}
|
||||
|
||||
} // namespace aria2
|
||||
|
|
Loading…
Reference in New Issue