1ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved. 2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be 3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file. 4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// 5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// WebSocketHandshake*Handler handles WebSocket handshake request message 6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// from WebKit renderer process, and WebSocket handshake response message 7c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// from WebSocket server. 8c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// It modifies messages for the following reason: 9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// - We don't trust WebKit renderer process, so we'll not expose HttpOnly 10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// cookies to the renderer process, so handles HttpOnly cookies in 11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// browser process. 12c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 13c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#ifndef NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_HANDLER_H_ 14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#define NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_HANDLER_H_ 153345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick#pragma once 16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <string> 18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <vector> 19c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 20ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen#include "base/memory/ref_counted.h" 21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_request_info.h" 22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/http/http_response_info.h" 23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/spdy/spdy_framer.h" 24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochnamespace net { 26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 27c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebSocketHandshakeRequestHandler { 28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebSocketHandshakeRequestHandler(); 30c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch ~WebSocketHandshakeRequestHandler() {} 31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Parses WebSocket handshake request from renderer process. 33c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // It assumes a WebSocket handshake request message is given at once, and 34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // no other data is added to the request message. 35c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ParseRequest(const char* data, int length); 36c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 37c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t original_length() const; 38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Appends the header value pair for |name| and |value|, if |name| doesn't 40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // exist. 41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void AppendHeaderIfMissing(const std::string& name, 42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& value); 43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Removes the headers that matches (case insensitive). 44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RemoveHeaders(const char* const headers_to_remove[], 45c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t headers_to_remove_len); 46c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 47c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Gets request info to open WebSocket connection. 48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Also, fill challange data in |challenge|. 49c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch HttpRequestInfo GetRequestInfo(const GURL& url, std::string* challenge); 50c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Gets request as SpdyHeaderBlock. 51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Also, fill challenge data in |challenge|. 52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool GetRequestHeaderBlock(const GURL& url, 53c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch spdy::SpdyHeaderBlock* headers, 54c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string* challenge); 55c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Gets WebSocket handshake raw request message to open WebSocket 56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // connection. 57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string GetRawRequest(); 58c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Calling raw_length is valid only after GetRawRquest() call. 59c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t raw_length() const; 60c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string status_line_; 63c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string headers_; 64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string key3_; 65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int original_length_; 66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int raw_length_; 67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 68c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(WebSocketHandshakeRequestHandler); 69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 71c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass WebSocketHandshakeResponseHandler { 72c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public: 73c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch WebSocketHandshakeResponseHandler(); 743f50c38dc070f4bb515c1b64450dae14f316474eKristian Monsen ~WebSocketHandshakeResponseHandler(); 75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Parses WebSocket handshake response from WebSocket server. 77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns number of bytes in |data| used for WebSocket handshake response 78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // message, including response key. If it already got whole WebSocket 79c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // handshake response message, returns zero. In other words, 80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // [data + returned value, data + length) will be WebSocket frame data 81c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // after handshake response message. 82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // TODO(ukai): fail fast when response gives wrong status code. 83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t ParseRawResponse(const char* data, int length); 84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Returns true if it already parses full handshake response message. 85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool HasResponse() const; 86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Parses WebSocket handshake response info given as HttpResponseInfo. 87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ParseResponseInfo(const HttpResponseInfo& response_info, 88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& challenge); 89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Parses WebSocket handshake response as SpdyHeaderBlock. 90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch bool ParseResponseHeaderBlock(const spdy::SpdyHeaderBlock& headers, 91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch const std::string& challenge); 92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Gets the headers value. 94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void GetHeaders(const char* const headers_to_get[], 95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t headers_to_get_len, 96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::vector<std::string>* values); 97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Removes the headers that matches (case insensitive). 98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch void RemoveHeaders(const char* const headers_to_remove[], 99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch size_t headers_to_remove_len); 100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 1013345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick // Gets raw WebSocket handshake response received from WebSocket server. 1023345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick std::string GetRawResponse() const; 1033345a6884c488ff3a535c2c9acdd33d74b37e311Iain Merrick 104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch // Gets WebSocket handshake response message sent to renderer process. 105c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string GetResponse(); 106c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 107c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private: 108c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string original_; 109c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch int original_header_length_; 110c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string status_line_; 111c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string headers_; 112c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string header_separator_; 113c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch std::string key_; 114c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 115c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch DISALLOW_COPY_AND_ASSIGN(WebSocketHandshakeResponseHandler); 116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}; 117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch} // namespace net 119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch 120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#endif // NET_WEBSOCKETS_WEBSOCKET_HANDSHAKE_HANDLER_H_ 121