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