• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 // Copyright 2018 The Chromium Authors
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_HTTP2_HANDSHAKE_STREAM_H_
6 #define NET_WEBSOCKETS_WEBSOCKET_HTTP2_HANDSHAKE_STREAM_H_
7 
8 #include <stdint.h>
9 
10 #include <memory>
11 #include <set>
12 #include <string>
13 #include <vector>
14 
15 #include "base/memory/raw_ptr.h"
16 #include "base/memory/weak_ptr.h"
17 #include "base/strings/string_piece.h"
18 #include "net/base/completion_once_callback.h"
19 #include "net/base/io_buffer.h"
20 #include "net/base/net_errors.h"
21 #include "net/base/net_export.h"
22 #include "net/base/request_priority.h"
23 #include "net/log/net_log_with_source.h"
24 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
25 #include "net/websockets/websocket_basic_stream_adapters.h"
26 #include "net/websockets/websocket_handshake_stream_base.h"
27 #include "net/websockets/websocket_stream.h"
28 #include "third_party/abseil-cpp/absl/types/optional.h"
29 
30 namespace net {
31 
32 class HttpNetworkSession;
33 class HttpRequestHeaders;
34 class HttpResponseHeaders;
35 class HttpResponseInfo;
36 class HttpStream;
37 class IOBuffer;
38 class IPEndPoint;
39 class SSLCertRequestInfo;
40 class SSLInfo;
41 class SpdySession;
42 class SpdyStream;
43 class SpdyStreamRequest;
44 struct AlternativeService;
45 struct HttpRequestInfo;
46 struct LoadTimingInfo;
47 struct NetErrorDetails;
48 struct WebSocketExtensionParams;
49 
50 class NET_EXPORT_PRIVATE WebSocketHttp2HandshakeStream
51     : public WebSocketHandshakeStreamBase,
52       public WebSocketSpdyStreamAdapter::Delegate {
53  public:
54   // |connect_delegate| and |request| must out-live this object.
55   WebSocketHttp2HandshakeStream(
56       base::WeakPtr<SpdySession> session,
57       WebSocketStream::ConnectDelegate* connect_delegate,
58       std::vector<std::string> requested_sub_protocols,
59       std::vector<std::string> requested_extensions,
60       WebSocketStreamRequestAPI* request,
61       std::set<std::string> dns_aliases);
62 
63   WebSocketHttp2HandshakeStream(const WebSocketHttp2HandshakeStream&) = delete;
64   WebSocketHttp2HandshakeStream& operator=(
65       const WebSocketHttp2HandshakeStream&) = delete;
66 
67   ~WebSocketHttp2HandshakeStream() override;
68 
69   // HttpStream methods.
70   void RegisterRequest(const HttpRequestInfo* request_info) override;
71   int InitializeStream(bool can_send_early,
72                        RequestPriority priority,
73                        const NetLogWithSource& net_log,
74                        CompletionOnceCallback callback) override;
75   int SendRequest(const HttpRequestHeaders& request_headers,
76                   HttpResponseInfo* response,
77                   CompletionOnceCallback callback) override;
78   int ReadResponseHeaders(CompletionOnceCallback callback) override;
79   int ReadResponseBody(IOBuffer* buf,
80                        int buf_len,
81                        CompletionOnceCallback callback) override;
82   void Close(bool not_reusable) override;
83   bool IsResponseBodyComplete() const override;
84   bool IsConnectionReused() const override;
85   void SetConnectionReused() override;
86   bool CanReuseConnection() const override;
87   int64_t GetTotalReceivedBytes() const override;
88   int64_t GetTotalSentBytes() const override;
89   bool GetAlternativeService(
90       AlternativeService* alternative_service) const override;
91   bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override;
92   void GetSSLInfo(SSLInfo* ssl_info) override;
93   void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override;
94   int GetRemoteEndpoint(IPEndPoint* endpoint) override;
95   void Drain(HttpNetworkSession* session) override;
96   void SetPriority(RequestPriority priority) override;
97   void PopulateNetErrorDetails(NetErrorDetails* details) override;
98   std::unique_ptr<HttpStream> RenewStreamForAuth() override;
99   const std::set<std::string>& GetDnsAliases() const override;
100   base::StringPiece GetAcceptChViaAlps() const override;
101 
102   // WebSocketHandshakeStreamBase methods.
103 
104   // This is called from the top level once correct handshake response headers
105   // have been received. It creates an appropriate subclass of WebSocketStream
106   // depending on what extensions were negotiated. This object is unusable after
107   // Upgrade() has been called and should be disposed of as soon as possible.
108   std::unique_ptr<WebSocketStream> Upgrade() override;
109 
110   bool CanReadFromStream() const override;
111 
112   base::WeakPtr<WebSocketHandshakeStreamBase> GetWeakPtr() override;
113 
114   // WebSocketSpdyStreamAdapter::Delegate methods.
115   void OnHeadersSent() override;
116   void OnHeadersReceived(
117       const spdy::Http2HeaderBlock& response_headers) override;
118   void OnClose(int status) override;
119 
120   // Called by |spdy_stream_request_| when requested stream is ready.
121   void StartRequestCallback(int rv);
122 
123  private:
124   // Validates the response and sends the finished handshake event.
125   int ValidateResponse();
126 
127   // Check that the headers are well-formed and have a 200 status code,
128   // in which case returns OK, otherwise returns ERR_INVALID_RESPONSE.
129   int ValidateUpgradeResponse(const HttpResponseHeaders* headers);
130 
131   void OnFailure(const std::string& message,
132                  int net_error,
133                  absl::optional<int> response_code);
134 
135   HandshakeResult result_ = HandshakeResult::HTTP2_INCOMPLETE;
136 
137   // The connection to open the Websocket stream on.
138   base::WeakPtr<SpdySession> session_;
139 
140   // Owned by another object.
141   // |connect_delegate| will live during the lifetime of this object.
142   const raw_ptr<WebSocketStream::ConnectDelegate, DanglingUntriaged>
143       connect_delegate_;
144 
145   raw_ptr<HttpResponseInfo> http_response_info_ = nullptr;
146 
147   spdy::Http2HeaderBlock http2_request_headers_;
148 
149   // The sub-protocols we requested.
150   std::vector<std::string> requested_sub_protocols_;
151 
152   // The extensions we requested.
153   std::vector<std::string> requested_extensions_;
154 
155   const raw_ptr<WebSocketStreamRequestAPI, DanglingUntriaged> stream_request_;
156 
157   raw_ptr<const HttpRequestInfo, DanglingUntriaged> request_info_ = nullptr;
158 
159   RequestPriority priority_;
160 
161   NetLogWithSource net_log_;
162 
163   // SpdyStreamRequest that will create the stream.
164   std::unique_ptr<SpdyStreamRequest> spdy_stream_request_;
165 
166   // SpdyStream corresponding to the request.
167   base::WeakPtr<SpdyStream> stream_;
168 
169   // WebSocketSpdyStreamAdapter holding a WeakPtr to |stream_|.
170   // This can be passed on to WebSocketBasicStream when created.
171   std::unique_ptr<WebSocketSpdyStreamAdapter> stream_adapter_;
172 
173   // True if |stream_| has been created then closed.
174   bool stream_closed_ = false;
175 
176   // The error code corresponding to the reason for closing the stream.
177   // Only meaningful if |stream_closed_| is true.
178   int stream_error_ = OK;
179 
180   // True if complete response headers have been received.
181   bool response_headers_complete_ = false;
182 
183   // Save callback provided in asynchronous HttpStream methods.
184   CompletionOnceCallback callback_;
185 
186   // The sub-protocol selected by the server.
187   std::string sub_protocol_;
188 
189   // The extension(s) selected by the server.
190   std::string extensions_;
191 
192   // The extension parameters. The class is defined in the implementation file
193   // to avoid including extension-related header files here.
194   std::unique_ptr<WebSocketExtensionParams> extension_params_;
195 
196   // Stores any DNS aliases for the remote endpoint. Includes all known aliases,
197   // e.g. from A, AAAA, or HTTPS, not just from the address used for the
198   // connection, in no particular order. These are stored in the stream instead
199   // of the session due to complications related to IP-pooling.
200   std::set<std::string> dns_aliases_;
201 
202   base::WeakPtrFactory<WebSocketHttp2HandshakeStream> weak_ptr_factory_{this};
203 };
204 
205 }  // namespace net
206 
207 #endif  // NET_WEBSOCKETS_WEBSOCKET_HTTP2_HANDSHAKE_STREAM_H_
208