// 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_QUIC_QUIC_HTTP_STREAM_H_ #define NET_QUIC_QUIC_HTTP_STREAM_H_ #include #include #include #include #include #include "base/macros.h" #include "base/memory/weak_ptr.h" #include "net/base/io_buffer.h" #include "net/http/http_stream.h" #include "net/quic/quic_chromium_client_session.h" #include "net/quic/quic_chromium_client_stream.h" #include "net/quic/quic_client_push_promise_index.h" namespace net { namespace test { class QuicHttpStreamPeer; } // namespace test // The QuicHttpStream is a QUIC-specific HttpStream subclass. It holds a // non-owning pointer to a QuicChromiumClientStream which it uses to // send and receive data. class NET_EXPORT_PRIVATE QuicHttpStream : public QuicChromiumClientSession::Observer, public QuicChromiumClientStream::Delegate, public QuicClientPushPromiseIndex::Delegate, public HttpStream { public: explicit QuicHttpStream( const base::WeakPtr& session); ~QuicHttpStream() override; // HttpStream implementation. int InitializeStream(const HttpRequestInfo* request_info, RequestPriority priority, const BoundNetLog& net_log, const CompletionCallback& callback) override; int SendRequest(const HttpRequestHeaders& request_headers, HttpResponseInfo* response, const CompletionCallback& callback) override; UploadProgress GetUploadProgress() const override; int ReadResponseHeaders(const CompletionCallback& callback) override; int ReadResponseBody(IOBuffer* buf, int buf_len, const CompletionCallback& callback) override; void Close(bool not_reusable) override; HttpStream* RenewStreamForAuth() override; bool IsResponseBodyComplete() const override; bool IsConnectionReused() const override; void SetConnectionReused() override; bool CanReuseConnection() const override; int64_t GetTotalReceivedBytes() const override; int64_t GetTotalSentBytes() const override; bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; void GetSSLInfo(SSLInfo* ssl_info) override; void GetSSLCertRequestInfo(SSLCertRequestInfo* cert_request_info) override; bool GetRemoteEndpoint(IPEndPoint* endpoint) override; Error GetSignedEKMForTokenBinding(crypto::ECPrivateKey* key, std::vector* out) override; void Drain(HttpNetworkSession* session) override; void PopulateNetErrorDetails(NetErrorDetails* details) override; void SetPriority(RequestPriority priority) override; // QuicChromiumClientStream::Delegate implementation void OnHeadersAvailable(const SpdyHeaderBlock& headers, size_t frame_len) override; void OnDataAvailable() override; void OnClose(QuicErrorCode error) override; void OnError(int error) override; bool HasSendHeadersComplete() override; // QuicChromiumClientSession::Observer implementation void OnCryptoHandshakeConfirmed() override; void OnSessionClosed(int error, bool port_migration_detected) override; // QuicClientPushPromiseIndex::Delegate implementation bool CheckVary(const SpdyHeaderBlock& client_request, const SpdyHeaderBlock& promise_request, const SpdyHeaderBlock& promise_response) override; void OnRendezvousResult(QuicSpdyStream* stream) override; private: friend class test::QuicHttpStreamPeer; enum State { STATE_NONE, STATE_REQUEST_STREAM, STATE_SET_REQUEST_PRIORITY, STATE_SEND_HEADERS, STATE_SEND_HEADERS_COMPLETE, STATE_READ_REQUEST_BODY, STATE_READ_REQUEST_BODY_COMPLETE, STATE_SEND_BODY, STATE_SEND_BODY_COMPLETE, STATE_OPEN, }; void OnStreamReady(int rv); void OnIOComplete(int rv); void DoCallback(int rv); int DoLoop(int rv); int DoStreamRequest(); int DoSetRequestPriority(); int DoSendHeaders(); int DoSendHeadersComplete(int rv); int DoReadRequestBody(); int DoReadRequestBodyComplete(int rv); int DoSendBody(); int DoSendBodyComplete(int rv); int DoReadResponseHeaders(); int DoReadResponseHeadersComplete(int rv); int ProcessResponseHeaders(const SpdyHeaderBlock& headers); int ReadAvailableData(IOBuffer* buf, int buf_len); void EnterStateSendHeaders(); int HandlePromise(); void ResetStream(); bool CancelPromiseIfHasBody(); State next_state_; base::WeakPtr session_; int session_error_; // Error code from the connection shutdown. bool was_handshake_confirmed_; // True if the crypto handshake succeeded. QuicChromiumClientSession::StreamRequest stream_request_; QuicChromiumClientStream* stream_; // Non-owning. // The following three fields are all owned by the caller and must // outlive this object, according to the HttpStream contract. // The request to send. const HttpRequestInfo* request_info_; // The request body to send, if any, owned by the caller. UploadDataStream* request_body_stream_; // Time the request was issued. base::Time request_time_; // The priority of the request. RequestPriority priority_; // |response_info_| is the HTTP response data object which is filled in // when a the response headers are read. It is not owned by this stream. HttpResponseInfo* response_info_; // Because response data is buffered, also buffer the response status if the // stream is explicitly closed via OnError or OnClose with an error. // Once all buffered data has been returned, this will be used as the final // response. int response_status_; // Serialized request headers. SpdyHeaderBlock request_headers_; bool response_headers_received_; // Serialized HTTP request. std::string request_; // Number of bytes received by the headers stream on behalf of this stream. int64_t headers_bytes_received_; // Number of bytes sent by the headers stream on behalf of this stream. int64_t headers_bytes_sent_; // Number of bytes received when the stream was closed. int64_t closed_stream_received_bytes_; // Number of bytes sent when the stream was closed. int64_t closed_stream_sent_bytes_; // The caller's callback to be used for asynchronous operations. CompletionCallback callback_; // Caller provided buffer for the ReadResponseBody() response. scoped_refptr user_buffer_; int user_buffer_len_; // Temporary buffer used to read the request body from UploadDataStream. scoped_refptr raw_request_body_buf_; // Wraps raw_request_body_buf_ to read the remaining data progressively. scoped_refptr request_body_buf_; BoundNetLog stream_net_log_; QuicErrorCode quic_connection_error_; // SSLInfo from the underlying QuicSession. SSLInfo ssl_info_; // True when this stream receives a go away from server due to port migration. bool port_migration_detected_; bool found_promise_; // |QuicClientPromisedInfo| owns this. It will be set when |Try()| // is asynchronous, i.e. it returned QUIC_PENDING, and remains valid // until |OnRendezvouResult()| fires or |push_handle_->Cancel()| is // invoked. QuicClientPushPromiseIndex::TryHandle* push_handle_; base::WeakPtrFactory weak_factory_; DISALLOW_COPY_AND_ASSIGN(QuicHttpStream); }; } // namespace net #endif // NET_QUIC_QUIC_HTTP_STREAM_H_