summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--net/websockets/websocket_job.cc62
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_,