Chromium Code Reviews| 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) |