1// Copyright 2013 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#ifndef NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_
6#define NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_
7
8#include <string>
9#include <vector>
10
11#include "base/memory/ref_counted.h"
12#include "base/memory/scoped_ptr.h"
13#include "net/base/net_export.h"
14#include "net/http/http_basic_state.h"
15#include "net/websockets/websocket_handshake_stream_base.h"
16#include "url/gurl.h"
17
18namespace net {
19
20class ClientSocketHandle;
21class HttpResponseHeaders;
22class HttpResponseInfo;
23class HttpStreamParser;
24
25struct WebSocketExtensionParams;
26
27class NET_EXPORT_PRIVATE WebSocketBasicHandshakeStream
28    : public WebSocketHandshakeStreamBase {
29 public:
30  // |connect_delegate| and |failure_message| must out-live this object.
31  WebSocketBasicHandshakeStream(
32      scoped_ptr<ClientSocketHandle> connection,
33      WebSocketStream::ConnectDelegate* connect_delegate,
34      bool using_proxy,
35      std::vector<std::string> requested_sub_protocols,
36      std::vector<std::string> requested_extensions,
37      std::string* failure_message);
38
39  virtual ~WebSocketBasicHandshakeStream();
40
41  // HttpStreamBase methods
42  virtual int InitializeStream(const HttpRequestInfo* request_info,
43                               RequestPriority priority,
44                               const BoundNetLog& net_log,
45                               const CompletionCallback& callback) OVERRIDE;
46  virtual int SendRequest(const HttpRequestHeaders& request_headers,
47                          HttpResponseInfo* response,
48                          const CompletionCallback& callback) OVERRIDE;
49  virtual int ReadResponseHeaders(const CompletionCallback& callback) OVERRIDE;
50  virtual int ReadResponseBody(IOBuffer* buf,
51                               int buf_len,
52                               const CompletionCallback& callback) OVERRIDE;
53  virtual void Close(bool not_reusable) OVERRIDE;
54  virtual bool IsResponseBodyComplete() const OVERRIDE;
55  virtual bool CanFindEndOfResponse() const OVERRIDE;
56  virtual bool IsConnectionReused() const OVERRIDE;
57  virtual void SetConnectionReused() OVERRIDE;
58  virtual bool IsConnectionReusable() const OVERRIDE;
59  virtual int64 GetTotalReceivedBytes() const OVERRIDE;
60  virtual bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const
61      OVERRIDE;
62  virtual void GetSSLInfo(SSLInfo* ssl_info) OVERRIDE;
63  virtual void GetSSLCertRequestInfo(
64      SSLCertRequestInfo* cert_request_info) OVERRIDE;
65  virtual bool IsSpdyHttpStream() const OVERRIDE;
66  virtual void Drain(HttpNetworkSession* session) OVERRIDE;
67  virtual void SetPriority(RequestPriority priority) OVERRIDE;
68
69  // This is called from the top level once correct handshake response headers
70  // have been received. It creates an appropriate subclass of WebSocketStream
71  // depending on what extensions were negotiated. This object is unusable after
72  // Upgrade() has been called and should be disposed of as soon as possible.
73  virtual scoped_ptr<WebSocketStream> Upgrade() OVERRIDE;
74
75  // Set the value used for the next Sec-WebSocket-Key header
76  // deterministically. The key is only used once, and then discarded.
77  // For tests only.
78  void SetWebSocketKeyForTesting(const std::string& key);
79
80 private:
81  // A wrapper for the ReadResponseHeaders callback that checks whether or not
82  // the connection has been accepted.
83  void ReadResponseHeadersCallback(const CompletionCallback& callback,
84                                   int result);
85
86  void OnFinishOpeningHandshake();
87
88  // Validates the response and sends the finished handshake event.
89  int ValidateResponse(int rv);
90
91  // Check that the headers are well-formed for a 101 response, and returns
92  // OK if they are, otherwise returns ERR_INVALID_RESPONSE.
93  int ValidateUpgradeResponse(const HttpResponseHeaders* headers);
94
95  HttpStreamParser* parser() const { return state_.parser(); }
96
97  void set_failure_message(const std::string& failure_message);
98
99  // The request URL.
100  GURL url_;
101
102  // HttpBasicState holds most of the handshake-related state.
103  HttpBasicState state_;
104
105  // Owned by another object.
106  // |connect_delegate| will live during the lifetime of this object.
107  WebSocketStream::ConnectDelegate* connect_delegate_;
108
109  // This is stored in SendRequest() for use by ReadResponseHeaders().
110  HttpResponseInfo* http_response_info_;
111
112  // The key to be sent in the next Sec-WebSocket-Key header. Usually NULL (the
113  // key is generated on the fly).
114  scoped_ptr<std::string> handshake_challenge_for_testing_;
115
116  // The required value for the Sec-WebSocket-Accept header.
117  std::string handshake_challenge_response_;
118
119  // The sub-protocols we requested.
120  std::vector<std::string> requested_sub_protocols_;
121
122  // The extensions we requested.
123  std::vector<std::string> requested_extensions_;
124
125  // The sub-protocol selected by the server.
126  std::string sub_protocol_;
127
128  // The extension(s) selected by the server.
129  std::string extensions_;
130
131  // The extension parameters. The class is defined in the implementation file
132  // to avoid including extension-related header files here.
133  scoped_ptr<WebSocketExtensionParams> extension_params_;
134
135  std::string* failure_message_;
136
137  DISALLOW_COPY_AND_ASSIGN(WebSocketBasicHandshakeStream);
138};
139
140}  // namespace net
141
142#endif  // NET_WEBSOCKETS_WEBSOCKET_BASIC_HANDSHAKE_STREAM_H_
143