summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2015-11-04 00:28:44 +0900
committerTatsuhiro Tsujikawa <tatsuhiro.t@gmail.com>2015-11-04 00:28:44 +0900
commit5ccd5b6953c95986407a735a41e8c36cf05944d1 (patch)
treea834c56d9feb27ed1084239462c1106c13b91076 /src
parent4bbc71c8e6c6aa7b5441e30da3a5efc5b810073a (diff)
Remove content-length and content-range if transfer-encoding is given
See GH-473
Diffstat (limited to 'src')
-rw-r--r--src/HttpHeader.cc5
-rw-r--r--src/HttpHeader.h2
-rw-r--r--src/HttpHeaderProcessor.cc19
-rw-r--r--src/HttpResponseCommand.cc3
4 files changed, 27 insertions, 2 deletions
diff --git a/src/HttpHeader.cc b/src/HttpHeader.cc
index 6b4739b5..a9fe23a6 100644
--- a/src/HttpHeader.cc
+++ b/src/HttpHeader.cc
@@ -53,6 +53,11 @@ void HttpHeader::put(int hdKey, const std::string& value)
table_.insert(vt);
}
+void HttpHeader::remove(int hdKey)
+{
+ table_.erase(hdKey);
+}
+
bool HttpHeader::defined(int hdKey) const
{
return table_.count(hdKey);
diff --git a/src/HttpHeader.h b/src/HttpHeader.h
index 897251b5..5697af9e 100644
--- a/src/HttpHeader.h
+++ b/src/HttpHeader.h
@@ -106,6 +106,8 @@ public:
std::multimap<int, std::string>::const_iterator>
equalRange(int hdKey) const;
+ void remove(int hdKey);
+
Range getRange() const;
int getStatusCode() const;
diff --git a/src/HttpHeaderProcessor.cc b/src/HttpHeaderProcessor.cc
index 5a5fab35..52dfc758 100644
--- a/src/HttpHeaderProcessor.cc
+++ b/src/HttpHeaderProcessor.cc
@@ -446,7 +446,24 @@ fin:
lastBytesProcessed_ = i;
headers_.append(&data[0], &data[i]);
- return state_ == HEADERS_COMPLETE;
+
+ if (state_ != HEADERS_COMPLETE) {
+ return false;
+ }
+
+ // If both transfer-encoding and (content-length or content-range)
+ // are present, delete content-length and content-range. RFC 7230
+ // says that sender must not send both transfer-encoding and
+ // content-length. If both present, transfer-encoding overrides
+ // content-length. There is no text about transfer-encoding and
+ // content-range. But there is no reason to send transfer-encoding
+ // when range is set.
+ if (result_->defined(HttpHeader::TRANSFER_ENCODING)) {
+ result_->remove(HttpHeader::CONTENT_LENGTH);
+ result_->remove(HttpHeader::CONTENT_RANGE);
+ }
+
+ return true;
}
bool HttpHeaderProcessor::parse(const std::string& data)
diff --git a/src/HttpResponseCommand.cc b/src/HttpResponseCommand.cc
index b259cbeb..d8dfffe9 100644
--- a/src/HttpResponseCommand.cc
+++ b/src/HttpResponseCommand.cc
@@ -263,7 +263,8 @@ bool HttpResponseCommand::executeInternal()
updateLastModifiedTime(httpResponse->getLastModifiedTime());
// If both transfer-encoding and total length is specified, we
- // assume we can do segmented downloading
+ // should have ignored total length. In this case, we can not do
+ // segmented downloading
if (totalLength == 0 || shouldInflateContentEncoding(httpResponse.get())) {
// we ignore content-length when inflate is required
fe->setLength(0);