transfer-encoding: support segmented download

Partial content responses (code 206) with content-range works at higher
level than content-length and transfer-encoding and is totally
compatible with both. In other words, transfer-encoding specifies the
encoding in which the request part is sent  while content-range species
the position of this part within the whole "representation".

Also, do range validation test for the response.

This parially reverts 5ccd5b6.

Fixes GH-1576.
pull/1587/head
Ali MJ Al-Nasrawy 2020-03-15 00:12:14 +03:00
parent 6d5ab2f124
commit 2924a029ab
5 changed files with 5 additions and 11 deletions

View File

@ -452,12 +452,9 @@ fin:
// are present, delete content-length and content-range. RFC 7230 // are present, delete content-length and content-range. RFC 7230
// says that sender must not send both transfer-encoding and // says that sender must not send both transfer-encoding and
// content-length. If both present, transfer-encoding overrides // content-length. If both present, transfer-encoding overrides
// content-length. There is no text about transfer-encoding and // content-length.
// content-range. But there is no reason to send transfer-encoding
// when range is set.
if (result_->defined(HttpHeader::TRANSFER_ENCODING)) { if (result_->defined(HttpHeader::TRANSFER_ENCODING)) {
result_->remove(HttpHeader::CONTENT_LENGTH); result_->remove(HttpHeader::CONTENT_LENGTH);
result_->remove(HttpHeader::CONTENT_RANGE);
} }
return true; return true;

View File

@ -74,7 +74,7 @@ void HttpResponse::validateResponse() const
switch (statusCode) { switch (statusCode) {
case 200: // OK case 200: // OK
case 206: // Partial Content case 206: // Partial Content
if (!httpHeader_->defined(HttpHeader::TRANSFER_ENCODING)) { {
// compare the received range against the requested range // compare the received range against the requested range
auto responseRange = httpHeader_->getRange(); auto responseRange = httpHeader_->getRange();
if (!httpRequest_->isRangeSatisfied(responseRange)) { if (!httpRequest_->isRangeSatisfied(responseRange)) {

View File

@ -272,9 +272,6 @@ bool HttpResponseCommand::executeInternal()
// update last modified time // update last modified time
updateLastModifiedTime(httpResponse->getLastModifiedTime()); updateLastModifiedTime(httpResponse->getLastModifiedTime());
// If both transfer-encoding and total length is specified, we
// should have ignored total length. In this case, we can not do
// segmented downloading
if (totalLength == 0 || shouldInflateContentEncoding(httpResponse.get())) { if (totalLength == 0 || shouldInflateContentEncoding(httpResponse.get())) {
// we ignore content-length when inflate is required // we ignore content-length when inflate is required
fe->setLength(0); fe->setLength(0);

View File

@ -224,7 +224,7 @@ void HttpHeaderProcessorTest::testGetHttpResponseHeader_teAndCl()
CPPUNIT_ASSERT_EQUAL(std::string("chunked"), CPPUNIT_ASSERT_EQUAL(std::string("chunked"),
httpHeader->find(HttpHeader::TRANSFER_ENCODING)); httpHeader->find(HttpHeader::TRANSFER_ENCODING));
CPPUNIT_ASSERT(!httpHeader->defined(HttpHeader::CONTENT_LENGTH)); CPPUNIT_ASSERT(!httpHeader->defined(HttpHeader::CONTENT_LENGTH));
CPPUNIT_ASSERT(!httpHeader->defined(HttpHeader::CONTENT_RANGE)); CPPUNIT_ASSERT(httpHeader->defined(HttpHeader::CONTENT_RANGE));
} }
void HttpHeaderProcessorTest::testBeyondLimit() void HttpHeaderProcessorTest::testBeyondLimit()

View File

@ -451,12 +451,12 @@ void HttpResponseTest::testValidateResponse_chunked()
"bytes 0-10485760/10485761"); "bytes 0-10485760/10485761");
httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked"); httpResponse.getHttpHeader()->put(HttpHeader::TRANSFER_ENCODING, "chunked");
// if transfer-encoding is specified, then range validation is skipped. // if transfer-encoding is specified, range validation is still necessary.
try { try {
httpResponse.validateResponse(); httpResponse.validateResponse();
CPPUNIT_FAIL("exception must be thrown.");
} }
catch (Exception& e) { catch (Exception& e) {
CPPUNIT_FAIL("exception must not be thrown.");
} }
} }