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