Index: Source/platform/network/HTTPParsers.cpp |
diff --git a/Source/platform/network/HTTPParsers.cpp b/Source/platform/network/HTTPParsers.cpp |
index 3763f841a982adc2bdb7d428899166039bd6517f..69b1490318d05ec860844fa6f0448d1a12b5c67c 100644 |
--- a/Source/platform/network/HTTPParsers.cpp |
+++ b/Source/platform/network/HTTPParsers.cpp |
@@ -607,74 +607,88 @@ size_t parseHTTPRequestLine(const char* data, size_t length, String& failureReas |
return end - data; |
} |
-size_t parseHTTPHeader(const char* start, size_t length, String& failureReason, AtomicString& nameStr, AtomicString& valueStr) |
+static bool parseHTTPHeaderName(const char* s, size_t start, size_t size, String& failureReason, size_t* position, AtomicString* name) |
{ |
- const char* p = start; |
- const char* end = start + length; |
- |
- Vector<char> name; |
- Vector<char> value; |
- nameStr = nullAtom; |
- valueStr = nullAtom; |
- |
- for (; p < end; p++) { |
- switch (*p) { |
+ size_t nameBegin = start; |
+ for (size_t i = start; i < size; ++i) { |
+ switch (s[i]) { |
case '\r': |
- if (name.isEmpty()) { |
- if (p + 1 < end && *(p + 1) == '\n') |
- return (p + 2) - start; |
- failureReason = "CR doesn't follow LF at " + trimInputSample(p, end - p); |
- return 0; |
- } |
- failureReason = "Unexpected CR in name at " + trimInputSample(name.data(), name.size()); |
- return 0; |
+ failureReason = "Unexpected CR in name at " + trimInputSample(&s[nameBegin], i - nameBegin); |
+ return false; |
case '\n': |
- failureReason = "Unexpected LF in name at " + trimInputSample(name.data(), name.size()); |
- return 0; |
+ failureReason = "Unexpected LF in name at " + trimInputSample(&s[nameBegin], i - nameBegin); |
+ return false; |
case ':': |
- break; |
+ *position = i; |
+ *name = AtomicString::fromUTF8(&s[nameBegin], i - nameBegin); |
+ return true; |
default: |
- name.append(*p); |
- continue; |
- } |
- if (*p == ':') { |
- ++p; |
break; |
} |
} |
+ failureReason = "Unterminated header name"; |
+ return false; |
+} |
- for (; p < end && *p == 0x20; p++) { } |
+static bool parseHTTPHeaderValue(const char* s, size_t start, size_t size, String& failureReason, size_t* position, AtomicString* value) |
+{ |
+ size_t i = start; |
+ for (i = start; i < size && s[i] == ' '; ++i) { |
tyoshino (SeeGerritForStatus)
2014/06/04 08:24:12
remove "i = start"?
yhirano
2014/06/04 09:14:03
Done.
|
+ } |
+ size_t valueBegin = i; |
- for (; p < end; p++) { |
- switch (*p) { |
- case '\r': |
- break; |
- case '\n': |
- failureReason = "Unexpected LF in value at " + trimInputSample(value.data(), value.size()); |
- return 0; |
- default: |
- value.append(*p); |
+ for (; i < size && s[i] != '\r'; ++i) { |
+ if (s[i] == '\n') { |
+ failureReason = "Unexpected LF in value at " + trimInputSample(&s[valueBegin], i - valueBegin); |
+ return false; |
} |
- if (*p == '\r') { |
- ++p; |
- break; |
+ } |
+ if (i == size) { |
+ failureReason = "Unterminated header value"; |
+ return false; |
+ } |
+ ASSERT(i < size && s[i] == '\r'); |
+ if (i + 1 >= size || s[i + 1] != '\n') { |
+ failureReason = "CR doesn't follow LF after value at " + trimInputSample(&s[i + 1], size - i - 1); |
tyoshino (SeeGerritForStatus)
2014/06/04 08:24:12
not your mistake but this should be
"LF doesn't fo
yhirano
2014/06/04 09:14:03
Done.
|
+ return false; |
+ } |
+ |
+ *position = i + 1; |
tyoshino (SeeGerritForStatus)
2014/06/04 08:24:12
is this correct?
yhirano
2014/06/04 09:14:03
Currently parseHTTPHeader returns (the number of c
|
+ *value = AtomicString::fromUTF8(&s[valueBegin], i - valueBegin); |
+ return true; |
+} |
+ |
+// Note that the header is already parsed and re-formatted in chromium side. |
+// We assume that the input is more restricted than RFC2616. |
+size_t parseHTTPHeader(const char* s, size_t size, String& failureReason, AtomicString& name, AtomicString& value) |
+{ |
+ name = nullAtom; |
+ value = nullAtom; |
+ if (size >= 1 && s[0] == '\r') { |
+ if (size >= 2 && s[1] == '\n') { |
+ // Skip an empty line. |
+ return 2; |
} |
+ failureReason = "CR doesn't follow LF at " + trimInputSample(0, size); |
tyoshino (SeeGerritForStatus)
2014/06/04 08:24:12
ditto
yhirano
2014/06/04 09:14:03
Done.
|
+ return 0; |
} |
- if (p >= end || *p != '\n') { |
- failureReason = "CR doesn't follow LF after value at " + trimInputSample(p, end - p); |
+ size_t current = 0; |
+ if (!parseHTTPHeaderName(s, current, size, failureReason, ¤t, &name)) { |
return 0; |
} |
- nameStr = AtomicString::fromUTF8(name.data(), name.size()); |
- valueStr = AtomicString::fromUTF8(value.data(), value.size()); |
- if (nameStr.isNull()) { |
+ if (name.isEmpty()) { |
failureReason = "Invalid UTF-8 sequence in header name"; |
tyoshino (SeeGerritForStatus)
2014/06/04 08:24:12
It's better to say that that header name was missi
yhirano
2014/06/04 09:14:03
I added some messages:
- "Header name is missing"
|
return 0; |
} |
- if (valueStr.isNull()) { |
- failureReason = "Invalid UTF-8 sequence in header value"; |
+ |
+ ASSERT(s[current] == ':'); |
+ ++current; |
+ |
+ if (!parseHTTPHeaderValue(s, current, size, failureReason, ¤t, &value)) { |
return 0; |
} |
- return p - start; |
+ |
+ return current; |
} |
size_t parseHTTPRequestBody(const char* data, size_t length, Vector<unsigned char>& body) |