Chromium Code Reviews| Index: net/server/http_server.cc |
| diff --git a/net/server/http_server.cc b/net/server/http_server.cc |
| index df77c3672daa423fe54127495aa18b7a4262a104..ba50d4bc0fb8d64259dd48b86fad83f363556a39 100644 |
| --- a/net/server/http_server.cc |
| +++ b/net/server/http_server.cc |
| @@ -142,8 +142,22 @@ void HttpServer::DidRead(StreamListenSocket* socket, |
| // Sets peer address if exists. |
| socket->GetPeerAddress(&request.peer); |
| - std::string connection_header = request.GetHeaderValue("connection"); |
| - if (connection_header == "Upgrade") { |
| + bool connection_upgrade = false; |
| + { |
|
pfeldman
2014/05/08 13:38:18
There is no need for this.
|
| + std::string connection_header = request.GetHeaderValue("connection"); |
|
pfeldman
2014/05/08 13:38:18
if (request.HasHeaderValue("connection", "upgrade"
|
| + StringToLowerASCII(&connection_header); |
| + std::vector<std::string> conn_items; |
| + Tokenize(connection_header, ",", &conn_items); |
| + for (std::vector<std::string>::iterator it = conn_items.begin(); |
| + it != conn_items.end(); ++it) { |
| + base::TrimString(*it, " \t", &*it); |
| + if (*it == "upgrade") { |
| + connection_upgrade = true; |
| + break; |
| + } |
| + } |
| + } |
| + if (connection_upgrade) { |
| connection->web_socket_.reset(WebSocket::CreateWebSocket(connection, |
| request, |
| &pos)); |
| @@ -205,7 +219,7 @@ HttpServer::~HttpServer() { |
| // Input character types. |
| enum header_parse_inputs { |
| - INPUT_SPACE, |
| + INPUT_LWS, |
| INPUT_CR, |
| INPUT_LF, |
| INPUT_COLON, |
| @@ -244,7 +258,8 @@ int parser_state[MAX_STATES][MAX_INPUTS] = { |
| int charToInput(char ch) { |
| switch(ch) { |
| case ' ': |
| - return INPUT_SPACE; |
| + case '\t': |
| + return INPUT_LWS; |
| case '\r': |
| return INPUT_CR; |
| case '\n': |
| @@ -270,6 +285,7 @@ bool HttpServer::ParseHeaders(HttpConnection* connection, |
| int next_state = parser_state[state][input]; |
| bool transition = (next_state != state); |
| + HttpServerRequestInfo::HeadersMap::iterator it; |
| if (transition) { |
| // Do any actions based on state transitions. |
| switch (state) { |
| @@ -292,9 +308,15 @@ bool HttpServer::ParseHeaders(HttpConnection* connection, |
| break; |
| case ST_VALUE: |
| base::TrimWhitespaceASCII(buffer, base::TRIM_LEADING, &header_value); |
| - // TODO(mbelshe): Deal better with duplicate headers |
| - DCHECK(info->headers.find(header_name) == info->headers.end()); |
| - info->headers[header_name] = header_value; |
| + it = info->headers.find(header_name); |
| + // See last paragraph ("Multiple message-header fields...") |
| + // of www.w3.org/Protocols/rfc2616/rfc2616-sec4.html#sec4.2 |
| + if (it == info->headers.end()) { |
| + info->headers[header_name] = header_value; |
| + } else { |
| + it->second.append(","); |
| + it->second.append(header_value); |
| + } |
| buffer.clear(); |
| break; |
| case ST_SEPARATOR: |