diff options
author | ukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 09:11:36 +0000 |
---|---|---|
committer | ukai@chromium.org <ukai@chromium.org@0039d316-1c4b-4281-b951-d872f2087c98> | 2010-03-25 09:11:36 +0000 |
commit | 6cca3e8d0074773db63858def6cbcfb34670134c (patch) | |
tree | f911e7f50a049f35faccf3554eb415a903d6ab27 /net/websockets | |
parent | f699753491b9b1b2f3ff0aaf8ecd9e2867b06138 (diff) | |
download | chromium_src-6cca3e8d0074773db63858def6cbcfb34670134c.zip chromium_src-6cca3e8d0074773db63858def6cbcfb34670134c.tar.gz chromium_src-6cca3e8d0074773db63858def6cbcfb34670134c.tar.bz2 |
Use FilterHeaders() instead of HttpUtil::StripHeaders().
We want to pass original response headers to WebKit, but just dropping set
cookie headers. HttpUtil::StripHeaders() strips malformed headers too,
so handshake in websocket/tests/long-invalid-header.html will success
unexpectedly.
Use FilterHeaders() to preserve malformed headers in response headers.
BUG=39062
TEST=handshake fails when malformed header is received.
Review URL: http://codereview.chromium.org/1254001
git-svn-id: svn://svn.chromium.org/chrome/trunk/src@42588 0039d316-1c4b-4281-b951-d872f2087c98
Diffstat (limited to 'net/websockets')
-rw-r--r-- | net/websockets/websocket_job.cc | 62 |
1 files changed, 57 insertions, 5 deletions
diff --git a/net/websockets/websocket_job.cc b/net/websockets/websocket_job.cc index e43a68a..6e20c17 100644 --- a/net/websockets/websocket_job.cc +++ b/net/websockets/websocket_job.cc @@ -4,6 +4,9 @@ #include "net/websockets/websocket_job.h" +#include <algorithm> + +#include "base/string_tokenizer.h" #include "googleurl/src/gurl.h" #include "net/base/net_errors.h" #include "net/base/cookie_policy.h" @@ -68,6 +71,54 @@ static void FetchResponseCookies( } } +static bool GetHeaderName(std::string::const_iterator line_begin, + std::string::const_iterator line_end, + std::string::const_iterator* name_begin, + std::string::const_iterator* name_end) { + std::string::const_iterator colon = std::find(line_begin, line_end, ':'); + if (colon == line_end) { + return false; + } + *name_begin = line_begin; + *name_end = colon; + if (*name_begin == *name_end || HttpUtil::IsLWS(**name_begin)) + return false; + HttpUtil::TrimLWS(name_begin, name_end); + return true; +} + +// Similar to HttpUtil::StripHeaders, but it preserves malformed headers, that +// is, lines that are not formatted as "<name>: <value>\r\n". +static std::string FilterHeaders( + const std::string& headers, + const char* const headers_to_remove[], + size_t headers_to_remove_len) { + std::string filtered_headers; + + StringTokenizer lines(headers.begin(), headers.end(), "\r\n"); + while (lines.GetNext()) { + std::string::const_iterator line_begin = lines.token_begin(); + std::string::const_iterator line_end = lines.token_end(); + std::string::const_iterator name_begin; + std::string::const_iterator name_end; + bool should_remove = false; + if (GetHeaderName(line_begin, line_end, &name_begin, &name_end)) { + for (size_t i = 0; i < headers_to_remove_len; ++i) { + if (LowerCaseEqualsASCII(name_begin, name_end, headers_to_remove[i])) { + should_remove = true; + break; + } + } + } + if (!should_remove) { + filtered_headers.append(line_begin, line_end); + filtered_headers.append("\r\n"); + } + } + return filtered_headers; +} + + // static void WebSocketJob::EnsureInit() { Singleton<WebSocketJobInitSingleton>::get(); @@ -259,7 +310,8 @@ void WebSocketJob::OnCanGetCookiesCompleted(int policy) { &handshake_request_status_line, &handshake_request_header); - // Remove cookie headers. + // Remove cookie headers. We should not send out malformed headers, so + // use HttpUtil::StripHeaders() instead of FilterHeaders(). handshake_request_header = HttpUtil::StripHeaders( handshake_request_header, kCookieHeaders, arraysize(kCookieHeaders)); @@ -345,11 +397,11 @@ void WebSocketJob::SaveNextCookie() { handshake_response_header_length_, &handshake_response_status_line, &handshake_response_header); - // Remove cookie headers. + // Remove cookie headers, with malformed headers preserved. + // Actual handshake should be done in WebKit. std::string filtered_handshake_response_header = - HttpUtil::StripHeaders( - handshake_response_header, - kSetCookieHeaders, arraysize(kSetCookieHeaders)); + FilterHeaders(handshake_response_header, + kSetCookieHeaders, arraysize(kSetCookieHeaders)); std::string remaining_data = std::string(handshake_response_.data() + handshake_response_header_length_, |