1 // Copyright 2016 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_QUIC_BIDIRECTIONAL_STREAM_QUIC_IMPL_H_ 6 #define NET_QUIC_BIDIRECTIONAL_STREAM_QUIC_IMPL_H_ 7 8 #include <stdint.h> 9 10 #include <memory> 11 #include <vector> 12 13 #include "base/memory/raw_ptr.h" 14 #include "base/memory/weak_ptr.h" 15 #include "net/base/load_timing_info.h" 16 #include "net/base/net_export.h" 17 #include "net/http/bidirectional_stream_impl.h" 18 #include "net/quic/quic_chromium_client_session.h" 19 #include "net/quic/quic_chromium_client_stream.h" 20 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" 21 22 namespace base { 23 class OneShotTimer; 24 } // namespace base 25 26 namespace net { 27 28 struct BidirectionalStreamRequestInfo; 29 class IOBuffer; 30 31 class NET_EXPORT_PRIVATE BidirectionalStreamQuicImpl 32 : public BidirectionalStreamImpl { 33 public: 34 explicit BidirectionalStreamQuicImpl( 35 std::unique_ptr<QuicChromiumClientSession::Handle> session); 36 37 BidirectionalStreamQuicImpl(const BidirectionalStreamQuicImpl&) = delete; 38 BidirectionalStreamQuicImpl& operator=(const BidirectionalStreamQuicImpl&) = 39 delete; 40 41 ~BidirectionalStreamQuicImpl() override; 42 43 // BidirectionalStreamImpl implementation: 44 void Start(const BidirectionalStreamRequestInfo* request_info, 45 const NetLogWithSource& net_log, 46 bool send_request_headers_automatically, 47 BidirectionalStreamImpl::Delegate* delegate, 48 std::unique_ptr<base::OneShotTimer> timer, 49 const NetworkTrafficAnnotationTag& traffic_annotation) override; 50 void SendRequestHeaders() override; 51 int ReadData(IOBuffer* buffer, int buffer_len) override; 52 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers, 53 const std::vector<int>& lengths, 54 bool end_stream) override; 55 NextProto GetProtocol() const override; 56 int64_t GetTotalReceivedBytes() const override; 57 int64_t GetTotalSentBytes() const override; 58 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 59 void PopulateNetErrorDetails(NetErrorDetails* details) override; 60 61 private: 62 int WriteHeaders(); 63 void OnStreamReady(int rv); 64 void OnSendDataComplete(int rv); 65 void ReadInitialHeaders(); 66 void OnReadInitialHeadersComplete(int rv); 67 void ReadTrailingHeaders(); 68 void OnReadTrailingHeadersComplete(int rv); 69 void OnReadDataComplete(int rv); 70 71 // Notifies the delegate of an error, clears |stream_| and |delegate_|, 72 // and cancels any pending callbacks. 73 void NotifyError(int error); 74 // Notifies the delegate of an error, clears |stream_| and |delegate_|, 75 // and cancels any pending callbacks. If |notify_delegate_later| is true 76 // then the delegate will be notified asynchronously via a posted task, 77 // otherwise the notification will be synchronous. 78 void NotifyErrorImpl(int error, bool notify_delegate_later); 79 // Notifies the delegate that the stream is ready. 80 void NotifyStreamReady(); 81 // Resets the stream and ensures that |delegate_| won't be called back. 82 void ResetStream(); 83 // Invokes OnFailure(error) on |delegate|. 84 void NotifyFailure(BidirectionalStreamImpl::Delegate* delegate, int error); 85 86 const std::unique_ptr<QuicChromiumClientSession::Handle> session_; 87 std::unique_ptr<QuicChromiumClientStream::Handle> stream_; 88 89 raw_ptr<const BidirectionalStreamRequestInfo> request_info_ = nullptr; 90 raw_ptr<BidirectionalStreamImpl::Delegate> delegate_ = nullptr; 91 // Saves the response status if the stream is explicitly closed via OnError 92 // or OnClose with an error. Once all buffered data has been returned, this 93 // will be used as the final response. 94 int response_status_ = OK; 95 96 // The protocol that is negotiated. 97 NextProto negotiated_protocol_ = kProtoUnknown; 98 // Connect timing information for this stream. Populated when headers are 99 // received. 100 LoadTimingInfo::ConnectTiming connect_timing_; 101 102 spdy::Http2HeaderBlock initial_headers_; 103 spdy::Http2HeaderBlock trailing_headers_; 104 105 // User provided read buffer for ReadData() response. 106 scoped_refptr<IOBuffer> read_buffer_; 107 int read_buffer_len_ = 0; 108 109 // Number of bytes received by the headers stream on behalf of this stream. 110 int64_t headers_bytes_received_ = 0; 111 // Number of bytes sent by the headers stream on behalf of this stream. 112 int64_t headers_bytes_sent_ = 0; 113 // After |stream_| has been closed, this keeps track of the total number of 114 // bytes received over the network for |stream_| while it was open. 115 int64_t closed_stream_received_bytes_ = 0; 116 // After |stream_| has been closed, this keeps track of the total number of 117 // bytes sent over the network for |stream_| while it was open. 118 int64_t closed_stream_sent_bytes_ = 0; 119 // True if the stream is the first stream negotiated on the session. Set when 120 // the stream was closed. If |stream_| is failed to be created, this takes on 121 // the default value of false. 122 bool closed_is_first_stream_ = false; 123 // Indicates whether initial headers have been sent. 124 bool has_sent_headers_ = false; 125 126 // Whether to automatically send request headers when stream is negotiated. 127 // If false, headers will not be sent until SendRequestHeaders() is called or 128 // until next SendData/SendvData, during which QUIC will try to combine header 129 // frame with data frame in the same packet if possible. 130 bool send_request_headers_automatically_ = true; 131 132 // True when callbacks to the delegate may be invoked synchronously. 133 bool may_invoke_callbacks_ = true; 134 135 base::WeakPtrFactory<BidirectionalStreamQuicImpl> weak_factory_{this}; 136 }; 137 138 } // namespace net 139 140 #endif // NET_QUIC_BIDIRECTIONAL_STREAM_QUIC_IMPL_H_ 141