| // 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 <list> |
| #include <string> |
| #include <vector> |
| |
| #include "base/macros.h" |
| #include "base/memory/weak_ptr.h" |
| #include "net/base/completion_once_callback.h" |
| #include "net/base/io_buffer.h" |
| #include "net/base/load_timing_info.h" |
| #include "net/base/net_export.h" |
| #include "net/http/http_response_info.h" |
| #include "net/http/http_server_properties.h" |
| #include "net/log/net_log_with_source.h" |
| #include "net/quic/quic_chromium_client_session.h" |
| #include "net/quic/quic_chromium_client_stream.h" |
| #include "net/spdy/multiplexed_http_stream.h" |
| #include "net/third_party/quic/core/http/quic_client_push_promise_index.h" |
| #include "net/third_party/quic/core/quic_packets.h" |
| #include "starboard/types.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 MultiplexedHttpStream { |
| public: |
| explicit QuicHttpStream( |
| std::unique_ptr<QuicChromiumClientSession::Handle> session); |
| |
| ~QuicHttpStream() override; |
| |
| // HttpStream implementation. |
| int InitializeStream(const HttpRequestInfo* request_info, |
| bool can_send_early, |
| RequestPriority priority, |
| const NetLogWithSource& net_log, |
| CompletionOnceCallback callback) override; |
| int SendRequest(const HttpRequestHeaders& request_headers, |
| HttpResponseInfo* response, |
| CompletionOnceCallback callback) override; |
| int ReadResponseHeaders(CompletionOnceCallback callback) override; |
| int ReadResponseBody(IOBuffer* buf, |
| int buf_len, |
| CompletionOnceCallback callback) override; |
| void Close(bool not_reusable) override; |
| bool IsResponseBodyComplete() const override; |
| bool IsConnectionReused() const override; |
| int64_t GetTotalReceivedBytes() const override; |
| int64_t GetTotalSentBytes() const override; |
| bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; |
| bool GetAlternativeService( |
| AlternativeService* alternative_service) const override; |
| void PopulateNetErrorDetails(NetErrorDetails* details) override; |
| void SetPriority(RequestPriority priority) override; |
| |
| static HttpResponseInfo::ConnectionInfo ConnectionInfoFromQuicVersion( |
| quic::QuicTransportVersion quic_version); |
| |
| private: |
| friend class test::QuicHttpStreamPeer; |
| |
| enum State { |
| STATE_NONE, |
| STATE_HANDLE_PROMISE, |
| STATE_HANDLE_PROMISE_COMPLETE, |
| STATE_REQUEST_STREAM, |
| STATE_REQUEST_STREAM_COMPLETE, |
| 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 OnIOComplete(int rv); |
| void DoCallback(int rv); |
| |
| int DoLoop(int rv); |
| int DoHandlePromise(); |
| int DoHandlePromiseComplete(int rv); |
| int DoRequestStream(); |
| int DoRequestStreamComplete(int rv); |
| int DoSetRequestPriority(); |
| int DoSendHeaders(); |
| int DoSendHeadersComplete(int rv); |
| int DoReadRequestBody(); |
| int DoReadRequestBodyComplete(int rv); |
| int DoSendBody(); |
| int DoSendBodyComplete(int rv); |
| |
| void OnReadResponseHeadersComplete(int rv); |
| int ProcessResponseHeaders(const spdy::SpdyHeaderBlock& headers); |
| void ReadTrailingHeaders(); |
| void OnReadTrailingHeadersComplete(int rv); |
| |
| void OnReadBodyComplete(int rv); |
| int HandleReadComplete(int rv); |
| |
| void EnterStateSendHeaders(); |
| |
| void ResetStream(); |
| |
| // Returns ERR_QUIC_HANDSHAKE_FAILED, if |rv| is ERR_QUIC_PROTOCOL_ERROR and |
| // the handshake was never confirmed. Otherwise, returns |rv|. |
| int MapStreamError(int rv); |
| |
| // If |has_response_status_| is false, sets |response_status| to the result |
| // of ComputeResponseStatus(). Returns |response_status_|. |
| int GetResponseStatus(); |
| // Sets the result of |ComputeResponseStatus()| as the |response_status_|. |
| void SaveResponseStatus(); |
| // Sets |response_status_| to |response_status| and sets |
| // |has_response_status_| to true. |
| void SetResponseStatus(int response_status); |
| // Computes the correct response status based on the status of the handshake, |
| // |session_error|, |connection_error| and |stream_error|. |
| int ComputeResponseStatus() const; |
| |
| QuicChromiumClientSession::Handle* quic_session() { |
| return static_cast<QuicChromiumClientSession::Handle*>(session()); |
| } |
| |
| const QuicChromiumClientSession::Handle* quic_session() const { |
| return static_cast<const QuicChromiumClientSession::Handle*>(session()); |
| } |
| |
| State next_state_; |
| |
| std::unique_ptr<QuicChromiumClientStream::Handle> stream_; |
| |
| // The following three fields are all owned by the caller and must |
| // outlive this object, according to the HttpStream contract. |
| |
| // The request to send. |
| // Only valid before the response body is read. |
| const HttpRequestInfo* request_info_; |
| |
| // Whether this request can be sent without confirmation. |
| bool can_send_early_; |
| |
| // 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_; |
| bool has_response_status_; // true if response_status_ as been set. |
| // 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. |
| spdy::SpdyHeaderBlock request_headers_; |
| |
| spdy::SpdyHeaderBlock response_header_block_; |
| bool response_headers_received_; |
| |
| spdy::SpdyHeaderBlock trailing_header_block_; |
| bool trailing_headers_received_; |
| |
| // 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_; |
| // True if the stream is the first stream negotiated on the session. Set when |
| // the stream was closed. If |stream_| is failed to be created, this takes on |
| // the default value of false. |
| bool closed_is_first_stream_; |
| |
| // The caller's callback to be used for asynchronous operations. |
| CompletionOnceCallback callback_; |
| |
| // Caller provided buffer for the ReadResponseBody() response. |
| scoped_refptr<IOBuffer> user_buffer_; |
| int user_buffer_len_; |
| |
| // Temporary buffer used to read the request body from UploadDataStream. |
| scoped_refptr<IOBufferWithSize> raw_request_body_buf_; |
| // Wraps raw_request_body_buf_ to read the remaining data progressively. |
| scoped_refptr<DrainableIOBuffer> request_body_buf_; |
| |
| NetLogWithSource stream_net_log_; |
| |
| int session_error_; // Error code from the connection shutdown. |
| |
| bool found_promise_; |
| |
| // Set to true when DoLoop() is being executed, false otherwise. |
| bool in_loop_; |
| |
| // Session connect timing info. |
| LoadTimingInfo::ConnectTiming connect_timing_; |
| |
| base::WeakPtrFactory<QuicHttpStream> weak_factory_; |
| |
| DISALLOW_COPY_AND_ASSIGN(QuicHttpStream); |
| }; |
| |
| } // namespace net |
| |
| #endif // NET_QUIC_QUIC_HTTP_STREAM_H_ |