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