| // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #ifndef NET_HTTP_HTTP_STREAM_REQUEST_H_ |
| #define NET_HTTP_HTTP_STREAM_REQUEST_H_ |
| |
| #include <memory> |
| |
| #include "base/macros.h" |
| #include "base/optional.h" |
| #include "net/base/load_states.h" |
| #include "net/base/net_error_details.h" |
| #include "net/base/net_export.h" |
| #include "net/base/request_priority.h" |
| #include "net/http/http_response_info.h" |
| #include "net/log/net_log_with_source.h" |
| #include "net/proxy_resolution/proxy_info.h" |
| #include "net/socket/connection_attempts.h" |
| #include "net/socket/next_proto.h" |
| #include "net/spdy/spdy_session_key.h" |
| #include "net/ssl/ssl_config.h" |
| #include "net/ssl/ssl_info.h" |
| #include "net/websockets/websocket_handshake_stream_base.h" |
| #include "url/gurl.h" |
| |
| namespace net { |
| |
| class BidirectionalStreamImpl; |
| class HttpAuthController; |
| class HttpStream; |
| class SSLCertRequestInfo; |
| |
| // The HttpStreamRequest is the client's handle to the worker object which |
| // handles the creation of an HttpStream. While the HttpStream is being |
| // created, this object is the creator's handle for interacting with the |
| // HttpStream creation process. The request is cancelled by deleting it, after |
| // which no callbacks will be invoked. |
| class NET_EXPORT_PRIVATE HttpStreamRequest { |
| public: |
| // Indicates which type of stream is requested. |
| enum StreamType { |
| BIDIRECTIONAL_STREAM, |
| HTTP_STREAM, |
| }; |
| |
| // The HttpStreamRequest::Delegate is a set of callback methods for a |
| // HttpStreamRequestJob. Generally, only one of these methods will be |
| // called as a result of a stream request. |
| class NET_EXPORT_PRIVATE Delegate { |
| public: |
| virtual ~Delegate() {} |
| |
| // This is the success case for RequestStream. |
| // |stream| is now owned by the delegate. |
| // |used_ssl_config| indicates the actual SSL configuration used for this |
| // stream, since the HttpStreamRequest may have modified the configuration |
| // during stream processing. |
| // |used_proxy_info| indicates the actual ProxyInfo used for this stream, |
| // since the HttpStreamRequest performs the proxy resolution. |
| virtual void OnStreamReady(const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<HttpStream> stream) = 0; |
| |
| // This is the success case for RequestWebSocketHandshakeStream. |
| // |stream| is now owned by the delegate. |
| // |used_ssl_config| indicates the actual SSL configuration used for this |
| // stream, since the HttpStreamRequest may have modified the configuration |
| // during stream processing. |
| // |used_proxy_info| indicates the actual ProxyInfo used for this stream, |
| // since the HttpStreamRequest performs the proxy resolution. |
| virtual void OnWebSocketHandshakeStreamReady( |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<WebSocketHandshakeStreamBase> stream) = 0; |
| |
| virtual void OnBidirectionalStreamImplReady( |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<BidirectionalStreamImpl> stream) = 0; |
| |
| // This is the failure to create a stream case. |
| // |used_ssl_config| indicates the actual SSL configuration used for this |
| // stream, since the HttpStreamRequest may have modified the configuration |
| // during stream processing. |
| virtual void OnStreamFailed(int status, |
| const NetErrorDetails& net_error_details, |
| const SSLConfig& used_ssl_config) = 0; |
| |
| // Called when we have a certificate error for the request. |
| // |used_ssl_config| indicates the actual SSL configuration used for this |
| // stream, since the HttpStreamRequest may have modified the configuration |
| // during stream processing. |
| virtual void OnCertificateError(int status, |
| const SSLConfig& used_ssl_config, |
| const SSLInfo& ssl_info) = 0; |
| |
| // This is the failure case where we need proxy authentication during |
| // proxy tunnel establishment. For the tunnel case, we were unable to |
| // create the HttpStream, so the caller provides the auth and then resumes |
| // the HttpStreamRequest. |
| // |
| // For the non-tunnel case, the caller will discover the authentication |
| // failure when reading response headers. At that point, it will handle the |
| // authentication failure and restart the HttpStreamRequest entirely. |
| // |
| // Ownership of |auth_controller| and |proxy_response| are owned |
| // by the HttpStreamRequest. |proxy_response| is not guaranteed to be usable |
| // after the lifetime of this callback. The delegate may take a reference |
| // to |auth_controller| if it is needed beyond the lifetime of this |
| // callback. |
| // |
| // |used_ssl_config| indicates the actual SSL configuration used for this |
| // stream, since the HttpStreamRequest may have modified the configuration |
| // during stream processing. |
| virtual void OnNeedsProxyAuth(const HttpResponseInfo& proxy_response, |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| HttpAuthController* auth_controller) = 0; |
| |
| // This is the failure for SSL Client Auth |
| // Ownership of |cert_info| is retained by the HttpStreamRequest. The |
| // delegate may take a reference if it needs the cert_info beyond the |
| // lifetime of this callback. |
| virtual void OnNeedsClientAuth(const SSLConfig& used_ssl_config, |
| SSLCertRequestInfo* cert_info) = 0; |
| |
| // This is the failure of the CONNECT request through an HTTPS proxy. |
| // Headers can be read from |response_info|, while the body can be read |
| // from |stream|. |
| // |
| // |used_ssl_config| indicates the actual SSL configuration used for this |
| // stream, since the HttpStreamRequest may have modified the configuration |
| // during stream processing. |
| // |
| // |used_proxy_info| indicates the actual ProxyInfo used for this stream, |
| // since the HttpStreamRequest performs the proxy resolution. |
| // |
| // Ownership of |stream| is transferred to the delegate. |
| virtual void OnHttpsProxyTunnelResponse( |
| const HttpResponseInfo& response_info, |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<HttpStream> stream) = 0; |
| |
| // Called when finding all QUIC alternative services are marked broken for |
| // the origin in this request which advertises supporting QUIC. |
| virtual void OnQuicBroken() = 0; |
| }; |
| |
| class NET_EXPORT_PRIVATE Helper { |
| public: |
| virtual ~Helper() {} |
| |
| // Returns the LoadState for Request. |
| virtual LoadState GetLoadState() const = 0; |
| |
| // Called when Request is destructed. |
| virtual void OnRequestComplete() = 0; |
| |
| // Called to resume the HttpStream creation process when necessary |
| // Proxy authentication credentials are collected. |
| virtual int RestartTunnelWithProxyAuth() = 0; |
| |
| // Called when the priority of transaction changes. |
| virtual void SetPriority(RequestPriority priority) = 0; |
| |
| // Called when SpdySessionPool notifies the Request |
| // that it can be served on a SpdySession created by another Request, |
| // therefore the Jobs can be destroyed. |
| virtual void OnStreamReadyOnPooledConnection( |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& proxy_info, |
| std::unique_ptr<HttpStream> stream) = 0; |
| virtual void OnBidirectionalStreamImplReadyOnPooledConnection( |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<BidirectionalStreamImpl> stream) = 0; |
| }; |
| |
| // Request will notify |job_controller| when it's destructed. |
| // Thus |job_controller| is valid for the lifetime of the |this| Request. |
| HttpStreamRequest(const GURL& url, |
| Helper* helper, |
| HttpStreamRequest::Delegate* delegate, |
| WebSocketHandshakeStreamBase::CreateHelper* |
| websocket_handshake_stream_create_helper, |
| const NetLogWithSource& net_log, |
| StreamType stream_type); |
| |
| ~HttpStreamRequest(); |
| |
| // When a HttpStream creation process is stalled due to necessity |
| // of Proxy authentication credentials, the delegate OnNeedsProxyAuth |
| // will have been called. It now becomes the delegate's responsibility |
| // to collect the necessary credentials, and then call this method to |
| // resume the HttpStream creation process. |
| int RestartTunnelWithProxyAuth(); |
| |
| // Called when the priority of the parent transaction changes. |
| void SetPriority(RequestPriority priority); |
| |
| // Marks completion of the request. Must be called before OnStreamReady(). |
| void Complete(bool was_alpn_negotiated, |
| NextProto negotiated_protocol, |
| bool using_spdy); |
| |
| // Called by |helper_| to record connection attempts made by the socket |
| // layer in an attached Job for this stream request. |
| void AddConnectionAttempts(const ConnectionAttempts& attempts); |
| |
| // Called when a stream becomes available on a connection that was not created |
| // by this request. |
| void OnStreamReadyOnPooledConnection(const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<HttpStream> stream); |
| void OnBidirectionalStreamImplReadyOnPooledConnection( |
| const SSLConfig& used_ssl_config, |
| const ProxyInfo& used_proxy_info, |
| std::unique_ptr<BidirectionalStreamImpl> stream); |
| |
| // Returns the LoadState for the request. |
| LoadState GetLoadState() const; |
| |
| // Returns true if TLS/ALPN was negotiated for this stream. |
| bool was_alpn_negotiated() const; |
| |
| // Protocol negotiated with the server. |
| NextProto negotiated_protocol() const; |
| |
| // Returns true if this stream is being fetched over SPDY. |
| bool using_spdy() const; |
| |
| // Returns socket-layer connection attempts made for this stream request. |
| const ConnectionAttempts& connection_attempts() const; |
| |
| // Returns the WebSocketHandshakeStreamBase::CreateHelper for this stream |
| // request. |
| WebSocketHandshakeStreamBase::CreateHelper* |
| websocket_handshake_stream_create_helper() const; |
| |
| // The GURL from the HttpRequestInfo the started the Request. |
| const GURL& url() const { return url_; } |
| |
| const NetLogWithSource& net_log() const { return net_log_; } |
| |
| // Called when the |helper_| determines the appropriate |spdy_session_key| |
| // for the Request. Note that this does not mean that SPDY is necessarily |
| // supported for this SpdySessionKey, since we may need to wait for NPN to |
| // complete before knowing if SPDY is available. |
| void SetSpdySessionKey(const SpdySessionKey& spdy_session_key) { |
| spdy_session_key_ = spdy_session_key; |
| } |
| bool HasSpdySessionKey() const { return spdy_session_key_.has_value(); } |
| const SpdySessionKey& GetSpdySessionKey() const { |
| DCHECK(HasSpdySessionKey()); |
| return spdy_session_key_.value(); |
| } |
| void ResetSpdySessionKey() { spdy_session_key_.reset(); } |
| |
| StreamType stream_type() const { return stream_type_; } |
| |
| bool completed() const { return completed_; } |
| |
| private: |
| const GURL url_; |
| |
| // Unowned. The helper must outlive this request. |
| Helper* helper_; |
| |
| WebSocketHandshakeStreamBase::CreateHelper* const |
| websocket_handshake_stream_create_helper_; |
| const NetLogWithSource net_log_; |
| |
| base::Optional<SpdySessionKey> spdy_session_key_; |
| |
| bool completed_; |
| bool was_alpn_negotiated_; |
| // Protocol negotiated with the server. |
| NextProto negotiated_protocol_; |
| bool using_spdy_; |
| ConnectionAttempts connection_attempts_; |
| const StreamType stream_type_; |
| |
| DISALLOW_COPY_AND_ASSIGN(HttpStreamRequest); |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_HTTP_HTTP_STREAM_REQUEST_H_ |