1 // Copyright 2015 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_SPDY_BIDIRECTIONAL_STREAM_SPDY_IMPL_H_ 6 #define NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_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/scoped_refptr.h" 15 #include "base/memory/weak_ptr.h" 16 #include "net/base/load_timing_info.h" 17 #include "net/base/net_export.h" 18 #include "net/http/bidirectional_stream_impl.h" 19 #include "net/http/bidirectional_stream_request_info.h" 20 #include "net/http/http_request_info.h" 21 #include "net/log/net_log_source.h" 22 #include "net/spdy/spdy_read_queue.h" 23 #include "net/spdy/spdy_session.h" 24 #include "net/spdy/spdy_stream.h" 25 #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h" 26 27 namespace base { 28 class OneShotTimer; 29 } // namespace base 30 31 namespace net { 32 33 class IOBuffer; 34 class NetLogWithSource; 35 36 class NET_EXPORT_PRIVATE BidirectionalStreamSpdyImpl 37 : public BidirectionalStreamImpl, 38 public SpdyStream::Delegate { 39 public: 40 BidirectionalStreamSpdyImpl(const base::WeakPtr<SpdySession>& spdy_session, 41 NetLogSource source_dependency); 42 43 BidirectionalStreamSpdyImpl(const BidirectionalStreamSpdyImpl&) = delete; 44 BidirectionalStreamSpdyImpl& operator=(const BidirectionalStreamSpdyImpl&) = 45 delete; 46 47 ~BidirectionalStreamSpdyImpl() override; 48 49 // BidirectionalStreamImpl implementation: 50 void Start(const BidirectionalStreamRequestInfo* request_info, 51 const NetLogWithSource& net_log, 52 bool send_request_headers_automatically, 53 BidirectionalStreamImpl::Delegate* delegate, 54 std::unique_ptr<base::OneShotTimer> timer, 55 const NetworkTrafficAnnotationTag& traffic_annotation) override; 56 void SendRequestHeaders() override; 57 int ReadData(IOBuffer* buf, int buf_len) override; 58 void SendvData(const std::vector<scoped_refptr<IOBuffer>>& buffers, 59 const std::vector<int>& lengths, 60 bool end_stream) override; 61 NextProto GetProtocol() const override; 62 int64_t GetTotalReceivedBytes() const override; 63 int64_t GetTotalSentBytes() const override; 64 bool GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const override; 65 void PopulateNetErrorDetails(NetErrorDetails* details) override; 66 67 // SpdyStream::Delegate implementation: 68 void OnHeadersSent() override; 69 void OnEarlyHintsReceived(const spdy::Http2HeaderBlock& headers) override; 70 void OnHeadersReceived( 71 const spdy::Http2HeaderBlock& response_headers, 72 const spdy::Http2HeaderBlock* pushed_request_headers) override; 73 void OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) override; 74 void OnDataSent() override; 75 void OnTrailers(const spdy::Http2HeaderBlock& trailers) override; 76 void OnClose(int status) override; 77 bool CanGreaseFrameType() const override; 78 NetLogSource source_dependency() const override; 79 80 private: 81 int SendRequestHeadersHelper(); 82 void OnStreamInitialized(int rv); 83 // Notifies delegate of an error. 84 void NotifyError(int rv); 85 void ResetStream(); 86 void ScheduleBufferedRead(); 87 void DoBufferedRead(); 88 bool ShouldWaitForMoreBufferedData() const; 89 // Handles the case where stream is closed when SendData()/SendvData() is 90 // called. Return true if stream is closed. 91 bool MaybeHandleStreamClosedInSendData(); 92 93 const base::WeakPtr<SpdySession> spdy_session_; 94 raw_ptr<const BidirectionalStreamRequestInfo> request_info_ = nullptr; 95 raw_ptr<BidirectionalStreamImpl::Delegate> delegate_ = nullptr; 96 std::unique_ptr<base::OneShotTimer> timer_; 97 SpdyStreamRequest stream_request_; 98 base::WeakPtr<SpdyStream> stream_; 99 const NetLogSource source_dependency_; 100 101 NextProto negotiated_protocol_ = kProtoUnknown; 102 103 // Buffers the data as it arrives asynchronously from the stream. 104 SpdyReadQueue read_data_queue_; 105 // Whether received more data has arrived since started waiting. 106 bool more_read_data_pending_ = false; 107 // User provided read buffer for ReadData() response. 108 scoped_refptr<IOBuffer> read_buffer_; 109 int read_buffer_len_ = 0; 110 111 // Whether client has written the end of stream flag in request headers or 112 // in SendData()/SendvData(). 113 bool written_end_of_stream_ = false; 114 // Whether a SendData() or SendvData() is pending. 115 bool write_pending_ = false; 116 117 // Whether OnClose has been invoked. 118 bool stream_closed_ = false; 119 // Status reported in OnClose. 120 int closed_stream_status_ = ERR_FAILED; 121 // After |stream_| has been closed, this keeps track of the total number of 122 // bytes received over the network for |stream_| while it was open. 123 int64_t closed_stream_received_bytes_ = 0; 124 // After |stream_| has been closed, this keeps track of the total number of 125 // bytes sent over the network for |stream_| while it was open. 126 int64_t closed_stream_sent_bytes_ = 0; 127 // True if |stream_| has LoadTimingInfo when it is closed. 128 bool closed_has_load_timing_info_ = false; 129 // LoadTimingInfo populated when |stream_| is closed. 130 LoadTimingInfo closed_load_timing_info_; 131 132 // This is the combined buffer of buffers passed in through SendvData. 133 // Keep a reference here so it is alive until OnDataSent is invoked. 134 scoped_refptr<IOBuffer> pending_combined_buffer_; 135 136 base::WeakPtrFactory<BidirectionalStreamSpdyImpl> weak_factory_{this}; 137 }; 138 139 } // namespace net 140 141 #endif // NET_SPDY_BIDIRECTIONAL_STREAM_SPDY_IMPL_H_ 142