xref: /aosp_15_r20/external/cronet/net/spdy/spdy_http_stream.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_http_stream.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <algorithm>
8*6777b538SAndroid Build Coastguard Worker #include <list>
9*6777b538SAndroid Build Coastguard Worker #include <set>
10*6777b538SAndroid Build Coastguard Worker #include <string>
11*6777b538SAndroid Build Coastguard Worker #include <string_view>
12*6777b538SAndroid Build Coastguard Worker #include <utility>
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker #include "base/check_op.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/base/ip_endpoint.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/base/upload_data_stream.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_headers.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/http/http_request_info.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_info.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_with_source.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/socket/next_proto.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_http_utils.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_session.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/spdy_protocol.h"
32*6777b538SAndroid Build Coastguard Worker #include "url/scheme_host_port.h"
33*6777b538SAndroid Build Coastguard Worker 
34*6777b538SAndroid Build Coastguard Worker namespace net {
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker // Align our request body with |kMaxSpdyFrameChunkSize| to prevent unexpected
37*6777b538SAndroid Build Coastguard Worker // buffer chunking. This is 16KB - frame header size.
38*6777b538SAndroid Build Coastguard Worker const size_t SpdyHttpStream::kRequestBodyBufferSize = kMaxSpdyFrameChunkSize;
39*6777b538SAndroid Build Coastguard Worker 
SpdyHttpStream(const base::WeakPtr<SpdySession> & spdy_session,NetLogSource source_dependency,std::set<std::string> dns_aliases)40*6777b538SAndroid Build Coastguard Worker SpdyHttpStream::SpdyHttpStream(const base::WeakPtr<SpdySession>& spdy_session,
41*6777b538SAndroid Build Coastguard Worker                                NetLogSource source_dependency,
42*6777b538SAndroid Build Coastguard Worker                                std::set<std::string> dns_aliases)
43*6777b538SAndroid Build Coastguard Worker     : MultiplexedHttpStream(
44*6777b538SAndroid Build Coastguard Worker           std::make_unique<MultiplexedSessionHandle>(spdy_session)),
45*6777b538SAndroid Build Coastguard Worker       spdy_session_(spdy_session),
46*6777b538SAndroid Build Coastguard Worker       is_reused_(spdy_session_->IsReused()),
47*6777b538SAndroid Build Coastguard Worker       source_dependency_(source_dependency),
48*6777b538SAndroid Build Coastguard Worker       dns_aliases_(std::move(dns_aliases)) {
49*6777b538SAndroid Build Coastguard Worker   DCHECK(spdy_session_.get());
50*6777b538SAndroid Build Coastguard Worker }
51*6777b538SAndroid Build Coastguard Worker 
~SpdyHttpStream()52*6777b538SAndroid Build Coastguard Worker SpdyHttpStream::~SpdyHttpStream() {
53*6777b538SAndroid Build Coastguard Worker   if (stream_) {
54*6777b538SAndroid Build Coastguard Worker     stream_->DetachDelegate();
55*6777b538SAndroid Build Coastguard Worker     DCHECK(!stream_);
56*6777b538SAndroid Build Coastguard Worker   }
57*6777b538SAndroid Build Coastguard Worker }
58*6777b538SAndroid Build Coastguard Worker 
RegisterRequest(const HttpRequestInfo * request_info)59*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::RegisterRequest(const HttpRequestInfo* request_info) {
60*6777b538SAndroid Build Coastguard Worker   DCHECK(request_info);
61*6777b538SAndroid Build Coastguard Worker   request_info_ = request_info;
62*6777b538SAndroid Build Coastguard Worker }
63*6777b538SAndroid Build Coastguard Worker 
InitializeStream(bool can_send_early,RequestPriority priority,const NetLogWithSource & stream_net_log,CompletionOnceCallback callback)64*6777b538SAndroid Build Coastguard Worker int SpdyHttpStream::InitializeStream(bool can_send_early,
65*6777b538SAndroid Build Coastguard Worker                                      RequestPriority priority,
66*6777b538SAndroid Build Coastguard Worker                                      const NetLogWithSource& stream_net_log,
67*6777b538SAndroid Build Coastguard Worker                                      CompletionOnceCallback callback) {
68*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_);
69*6777b538SAndroid Build Coastguard Worker   DCHECK(request_info_);
70*6777b538SAndroid Build Coastguard Worker   if (!spdy_session_)
71*6777b538SAndroid Build Coastguard Worker     return ERR_CONNECTION_CLOSED;
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker   priority_ = priority;
74*6777b538SAndroid Build Coastguard Worker   int rv = stream_request_.StartRequest(
75*6777b538SAndroid Build Coastguard Worker       SPDY_REQUEST_RESPONSE_STREAM, spdy_session_, request_info_->url,
76*6777b538SAndroid Build Coastguard Worker       can_send_early, priority, request_info_->socket_tag, stream_net_log,
77*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&SpdyHttpStream::OnStreamCreated,
78*6777b538SAndroid Build Coastguard Worker                      weak_factory_.GetWeakPtr(), std::move(callback)),
79*6777b538SAndroid Build Coastguard Worker       NetworkTrafficAnnotationTag{request_info_->traffic_annotation});
80*6777b538SAndroid Build Coastguard Worker 
81*6777b538SAndroid Build Coastguard Worker   if (rv == OK) {
82*6777b538SAndroid Build Coastguard Worker     stream_ = stream_request_.ReleaseStream().get();
83*6777b538SAndroid Build Coastguard Worker     InitializeStreamHelper();
84*6777b538SAndroid Build Coastguard Worker   }
85*6777b538SAndroid Build Coastguard Worker 
86*6777b538SAndroid Build Coastguard Worker   return rv;
87*6777b538SAndroid Build Coastguard Worker }
88*6777b538SAndroid Build Coastguard Worker 
ReadResponseHeaders(CompletionOnceCallback callback)89*6777b538SAndroid Build Coastguard Worker int SpdyHttpStream::ReadResponseHeaders(CompletionOnceCallback callback) {
90*6777b538SAndroid Build Coastguard Worker   CHECK(!callback.is_null());
91*6777b538SAndroid Build Coastguard Worker   if (stream_closed_)
92*6777b538SAndroid Build Coastguard Worker     return closed_stream_status_;
93*6777b538SAndroid Build Coastguard Worker 
94*6777b538SAndroid Build Coastguard Worker   CHECK(stream_);
95*6777b538SAndroid Build Coastguard Worker 
96*6777b538SAndroid Build Coastguard Worker   // Check if we already have the response headers. If so, return synchronously.
97*6777b538SAndroid Build Coastguard Worker   if (response_headers_complete_) {
98*6777b538SAndroid Build Coastguard Worker     CHECK(!stream_->IsIdle());
99*6777b538SAndroid Build Coastguard Worker     return OK;
100*6777b538SAndroid Build Coastguard Worker   }
101*6777b538SAndroid Build Coastguard Worker 
102*6777b538SAndroid Build Coastguard Worker   // Still waiting for the response, return IO_PENDING.
103*6777b538SAndroid Build Coastguard Worker   CHECK(response_callback_.is_null());
104*6777b538SAndroid Build Coastguard Worker   response_callback_ = std::move(callback);
105*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
106*6777b538SAndroid Build Coastguard Worker }
107*6777b538SAndroid Build Coastguard Worker 
ReadResponseBody(IOBuffer * buf,int buf_len,CompletionOnceCallback callback)108*6777b538SAndroid Build Coastguard Worker int SpdyHttpStream::ReadResponseBody(IOBuffer* buf,
109*6777b538SAndroid Build Coastguard Worker                                      int buf_len,
110*6777b538SAndroid Build Coastguard Worker                                      CompletionOnceCallback callback) {
111*6777b538SAndroid Build Coastguard Worker   if (stream_)
112*6777b538SAndroid Build Coastguard Worker     CHECK(!stream_->IsIdle());
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   CHECK(buf);
115*6777b538SAndroid Build Coastguard Worker   CHECK(buf_len);
116*6777b538SAndroid Build Coastguard Worker   CHECK(!callback.is_null());
117*6777b538SAndroid Build Coastguard Worker 
118*6777b538SAndroid Build Coastguard Worker   // If we have data buffered, complete the IO immediately.
119*6777b538SAndroid Build Coastguard Worker   if (!response_body_queue_.IsEmpty()) {
120*6777b538SAndroid Build Coastguard Worker     return response_body_queue_.Dequeue(buf->data(), buf_len);
121*6777b538SAndroid Build Coastguard Worker   } else if (stream_closed_) {
122*6777b538SAndroid Build Coastguard Worker     return closed_stream_status_;
123*6777b538SAndroid Build Coastguard Worker   }
124*6777b538SAndroid Build Coastguard Worker 
125*6777b538SAndroid Build Coastguard Worker   CHECK(response_callback_.is_null());
126*6777b538SAndroid Build Coastguard Worker   CHECK(!user_buffer_.get());
127*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(0, user_buffer_len_);
128*6777b538SAndroid Build Coastguard Worker 
129*6777b538SAndroid Build Coastguard Worker   response_callback_ = std::move(callback);
130*6777b538SAndroid Build Coastguard Worker   user_buffer_ = buf;
131*6777b538SAndroid Build Coastguard Worker   user_buffer_len_ = buf_len;
132*6777b538SAndroid Build Coastguard Worker   return ERR_IO_PENDING;
133*6777b538SAndroid Build Coastguard Worker }
134*6777b538SAndroid Build Coastguard Worker 
Close(bool not_reusable)135*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::Close(bool not_reusable) {
136*6777b538SAndroid Build Coastguard Worker   // Note: the not_reusable flag has no meaning for SPDY streams.
137*6777b538SAndroid Build Coastguard Worker 
138*6777b538SAndroid Build Coastguard Worker   Cancel();
139*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_);
140*6777b538SAndroid Build Coastguard Worker }
141*6777b538SAndroid Build Coastguard Worker 
IsResponseBodyComplete() const142*6777b538SAndroid Build Coastguard Worker bool SpdyHttpStream::IsResponseBodyComplete() const {
143*6777b538SAndroid Build Coastguard Worker   return stream_closed_;
144*6777b538SAndroid Build Coastguard Worker }
145*6777b538SAndroid Build Coastguard Worker 
IsConnectionReused() const146*6777b538SAndroid Build Coastguard Worker bool SpdyHttpStream::IsConnectionReused() const {
147*6777b538SAndroid Build Coastguard Worker   return is_reused_;
148*6777b538SAndroid Build Coastguard Worker }
149*6777b538SAndroid Build Coastguard Worker 
GetTotalReceivedBytes() const150*6777b538SAndroid Build Coastguard Worker int64_t SpdyHttpStream::GetTotalReceivedBytes() const {
151*6777b538SAndroid Build Coastguard Worker   if (stream_closed_)
152*6777b538SAndroid Build Coastguard Worker     return closed_stream_received_bytes_;
153*6777b538SAndroid Build Coastguard Worker 
154*6777b538SAndroid Build Coastguard Worker   if (!stream_)
155*6777b538SAndroid Build Coastguard Worker     return 0;
156*6777b538SAndroid Build Coastguard Worker 
157*6777b538SAndroid Build Coastguard Worker   return stream_->raw_received_bytes();
158*6777b538SAndroid Build Coastguard Worker }
159*6777b538SAndroid Build Coastguard Worker 
GetTotalSentBytes() const160*6777b538SAndroid Build Coastguard Worker int64_t SpdyHttpStream::GetTotalSentBytes() const {
161*6777b538SAndroid Build Coastguard Worker   if (stream_closed_)
162*6777b538SAndroid Build Coastguard Worker     return closed_stream_sent_bytes_;
163*6777b538SAndroid Build Coastguard Worker 
164*6777b538SAndroid Build Coastguard Worker   if (!stream_)
165*6777b538SAndroid Build Coastguard Worker     return 0;
166*6777b538SAndroid Build Coastguard Worker 
167*6777b538SAndroid Build Coastguard Worker   return stream_->raw_sent_bytes();
168*6777b538SAndroid Build Coastguard Worker }
169*6777b538SAndroid Build Coastguard Worker 
GetAlternativeService(AlternativeService * alternative_service) const170*6777b538SAndroid Build Coastguard Worker bool SpdyHttpStream::GetAlternativeService(
171*6777b538SAndroid Build Coastguard Worker     AlternativeService* alternative_service) const {
172*6777b538SAndroid Build Coastguard Worker   return false;
173*6777b538SAndroid Build Coastguard Worker }
174*6777b538SAndroid Build Coastguard Worker 
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const175*6777b538SAndroid Build Coastguard Worker bool SpdyHttpStream::GetLoadTimingInfo(LoadTimingInfo* load_timing_info) const {
176*6777b538SAndroid Build Coastguard Worker   if (stream_closed_) {
177*6777b538SAndroid Build Coastguard Worker     if (!closed_stream_has_load_timing_info_)
178*6777b538SAndroid Build Coastguard Worker       return false;
179*6777b538SAndroid Build Coastguard Worker     *load_timing_info = closed_stream_load_timing_info_;
180*6777b538SAndroid Build Coastguard Worker   } else {
181*6777b538SAndroid Build Coastguard Worker     // If |stream_| has yet to be created, or does not yet have an ID, fail.
182*6777b538SAndroid Build Coastguard Worker     // The reused flag can only be correctly set once a stream has an ID.
183*6777b538SAndroid Build Coastguard Worker     // Streams get their IDs once the request has been successfully sent, so
184*6777b538SAndroid Build Coastguard Worker     // this does not behave that differently from other stream types.
185*6777b538SAndroid Build Coastguard Worker     if (!stream_ || stream_->stream_id() == 0)
186*6777b538SAndroid Build Coastguard Worker       return false;
187*6777b538SAndroid Build Coastguard Worker 
188*6777b538SAndroid Build Coastguard Worker     if (!stream_->GetLoadTimingInfo(load_timing_info))
189*6777b538SAndroid Build Coastguard Worker       return false;
190*6777b538SAndroid Build Coastguard Worker   }
191*6777b538SAndroid Build Coastguard Worker 
192*6777b538SAndroid Build Coastguard Worker   // If the request waited for handshake confirmation, shift |ssl_end| to
193*6777b538SAndroid Build Coastguard Worker   // include that time.
194*6777b538SAndroid Build Coastguard Worker   if (!load_timing_info->connect_timing.ssl_end.is_null() &&
195*6777b538SAndroid Build Coastguard Worker       !stream_request_.confirm_handshake_end().is_null()) {
196*6777b538SAndroid Build Coastguard Worker     load_timing_info->connect_timing.ssl_end =
197*6777b538SAndroid Build Coastguard Worker         stream_request_.confirm_handshake_end();
198*6777b538SAndroid Build Coastguard Worker     load_timing_info->connect_timing.connect_end =
199*6777b538SAndroid Build Coastguard Worker         stream_request_.confirm_handshake_end();
200*6777b538SAndroid Build Coastguard Worker   }
201*6777b538SAndroid Build Coastguard Worker 
202*6777b538SAndroid Build Coastguard Worker   return true;
203*6777b538SAndroid Build Coastguard Worker }
204*6777b538SAndroid Build Coastguard Worker 
SendRequest(const HttpRequestHeaders & request_headers,HttpResponseInfo * response,CompletionOnceCallback callback)205*6777b538SAndroid Build Coastguard Worker int SpdyHttpStream::SendRequest(const HttpRequestHeaders& request_headers,
206*6777b538SAndroid Build Coastguard Worker                                 HttpResponseInfo* response,
207*6777b538SAndroid Build Coastguard Worker                                 CompletionOnceCallback callback) {
208*6777b538SAndroid Build Coastguard Worker   if (stream_closed_) {
209*6777b538SAndroid Build Coastguard Worker     return closed_stream_status_;
210*6777b538SAndroid Build Coastguard Worker   }
211*6777b538SAndroid Build Coastguard Worker 
212*6777b538SAndroid Build Coastguard Worker   base::Time request_time = base::Time::Now();
213*6777b538SAndroid Build Coastguard Worker   CHECK(stream_);
214*6777b538SAndroid Build Coastguard Worker 
215*6777b538SAndroid Build Coastguard Worker   stream_->SetRequestTime(request_time);
216*6777b538SAndroid Build Coastguard Worker   // This should only get called in the case of a request occurring
217*6777b538SAndroid Build Coastguard Worker   // during server push that has already begun but hasn't finished,
218*6777b538SAndroid Build Coastguard Worker   // so we set the response's request time to be the actual one
219*6777b538SAndroid Build Coastguard Worker   if (response_info_)
220*6777b538SAndroid Build Coastguard Worker     response_info_->request_time = request_time;
221*6777b538SAndroid Build Coastguard Worker 
222*6777b538SAndroid Build Coastguard Worker   CHECK(!request_body_buf_.get());
223*6777b538SAndroid Build Coastguard Worker   if (HasUploadData()) {
224*6777b538SAndroid Build Coastguard Worker     request_body_buf_ =
225*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(kRequestBodyBufferSize);
226*6777b538SAndroid Build Coastguard Worker     // The request body buffer is empty at first.
227*6777b538SAndroid Build Coastguard Worker     request_body_buf_size_ = 0;
228*6777b538SAndroid Build Coastguard Worker   }
229*6777b538SAndroid Build Coastguard Worker 
230*6777b538SAndroid Build Coastguard Worker   CHECK(!callback.is_null());
231*6777b538SAndroid Build Coastguard Worker   CHECK(response);
232*6777b538SAndroid Build Coastguard Worker   DCHECK(!response_info_);
233*6777b538SAndroid Build Coastguard Worker 
234*6777b538SAndroid Build Coastguard Worker   response_info_ = response;
235*6777b538SAndroid Build Coastguard Worker 
236*6777b538SAndroid Build Coastguard Worker   // Put the peer's IP address and port into the response.
237*6777b538SAndroid Build Coastguard Worker   IPEndPoint address;
238*6777b538SAndroid Build Coastguard Worker   int result = stream_->GetPeerAddress(&address);
239*6777b538SAndroid Build Coastguard Worker   if (result != OK)
240*6777b538SAndroid Build Coastguard Worker     return result;
241*6777b538SAndroid Build Coastguard Worker   response_info_->remote_endpoint = address;
242*6777b538SAndroid Build Coastguard Worker 
243*6777b538SAndroid Build Coastguard Worker   spdy::Http2HeaderBlock headers;
244*6777b538SAndroid Build Coastguard Worker   CreateSpdyHeadersFromHttpRequest(*request_info_, priority_, request_headers,
245*6777b538SAndroid Build Coastguard Worker                                    &headers);
246*6777b538SAndroid Build Coastguard Worker   DispatchRequestHeadersCallback(headers);
247*6777b538SAndroid Build Coastguard Worker 
248*6777b538SAndroid Build Coastguard Worker   bool will_send_data =
249*6777b538SAndroid Build Coastguard Worker       HasUploadData() || spdy_session_->EndStreamWithDataFrame();
250*6777b538SAndroid Build Coastguard Worker   result = stream_->SendRequestHeaders(
251*6777b538SAndroid Build Coastguard Worker       std::move(headers),
252*6777b538SAndroid Build Coastguard Worker       will_send_data ? MORE_DATA_TO_SEND : NO_MORE_DATA_TO_SEND);
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker   if (result == ERR_IO_PENDING) {
255*6777b538SAndroid Build Coastguard Worker     CHECK(request_callback_.is_null());
256*6777b538SAndroid Build Coastguard Worker     request_callback_ = std::move(callback);
257*6777b538SAndroid Build Coastguard Worker   }
258*6777b538SAndroid Build Coastguard Worker   return result;
259*6777b538SAndroid Build Coastguard Worker }
260*6777b538SAndroid Build Coastguard Worker 
Cancel()261*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::Cancel() {
262*6777b538SAndroid Build Coastguard Worker   request_callback_.Reset();
263*6777b538SAndroid Build Coastguard Worker   response_callback_.Reset();
264*6777b538SAndroid Build Coastguard Worker   if (stream_) {
265*6777b538SAndroid Build Coastguard Worker     stream_->Cancel(ERR_ABORTED);
266*6777b538SAndroid Build Coastguard Worker     DCHECK(!stream_);
267*6777b538SAndroid Build Coastguard Worker   }
268*6777b538SAndroid Build Coastguard Worker }
269*6777b538SAndroid Build Coastguard Worker 
OnHeadersSent()270*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnHeadersSent() {
271*6777b538SAndroid Build Coastguard Worker   if (HasUploadData()) {
272*6777b538SAndroid Build Coastguard Worker     ReadAndSendRequestBodyData();
273*6777b538SAndroid Build Coastguard Worker   } else if (spdy_session_->EndStreamWithDataFrame()) {
274*6777b538SAndroid Build Coastguard Worker     SendEmptyBody();
275*6777b538SAndroid Build Coastguard Worker   } else {
276*6777b538SAndroid Build Coastguard Worker     MaybePostRequestCallback(OK);
277*6777b538SAndroid Build Coastguard Worker   }
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker 
OnEarlyHintsReceived(const spdy::Http2HeaderBlock & headers)280*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnEarlyHintsReceived(
281*6777b538SAndroid Build Coastguard Worker     const spdy::Http2HeaderBlock& headers) {
282*6777b538SAndroid Build Coastguard Worker   DCHECK(!response_headers_complete_);
283*6777b538SAndroid Build Coastguard Worker   DCHECK(response_info_);
284*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(stream_->type(), SPDY_REQUEST_RESPONSE_STREAM);
285*6777b538SAndroid Build Coastguard Worker 
286*6777b538SAndroid Build Coastguard Worker   const int rv = SpdyHeadersToHttpResponse(headers, response_info_);
287*6777b538SAndroid Build Coastguard Worker   CHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
288*6777b538SAndroid Build Coastguard Worker 
289*6777b538SAndroid Build Coastguard Worker   if (!response_callback_.is_null()) {
290*6777b538SAndroid Build Coastguard Worker     DoResponseCallback(OK);
291*6777b538SAndroid Build Coastguard Worker   }
292*6777b538SAndroid Build Coastguard Worker }
293*6777b538SAndroid Build Coastguard Worker 
OnHeadersReceived(const spdy::Http2HeaderBlock & response_headers)294*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnHeadersReceived(
295*6777b538SAndroid Build Coastguard Worker     const spdy::Http2HeaderBlock& response_headers) {
296*6777b538SAndroid Build Coastguard Worker   DCHECK(!response_headers_complete_);
297*6777b538SAndroid Build Coastguard Worker   DCHECK(response_info_);
298*6777b538SAndroid Build Coastguard Worker   response_headers_complete_ = true;
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker   const int rv = SpdyHeadersToHttpResponse(response_headers, response_info_);
301*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
302*6777b538SAndroid Build Coastguard Worker 
303*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_RESPONSE_HEADERS_MULTIPLE_LOCATION) {
304*6777b538SAndroid Build Coastguard Worker     // Cancel will call OnClose, which might call callbacks and might destroy
305*6777b538SAndroid Build Coastguard Worker     // `this`.
306*6777b538SAndroid Build Coastguard Worker     stream_->Cancel(rv);
307*6777b538SAndroid Build Coastguard Worker     return;
308*6777b538SAndroid Build Coastguard Worker   }
309*6777b538SAndroid Build Coastguard Worker 
310*6777b538SAndroid Build Coastguard Worker   response_info_->response_time = stream_->response_time();
311*6777b538SAndroid Build Coastguard Worker   // Don't store the SSLInfo in the response here, HttpNetworkTransaction
312*6777b538SAndroid Build Coastguard Worker   // will take care of that part.
313*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(stream_->GetNegotiatedProtocol(), kProtoHTTP2);
314*6777b538SAndroid Build Coastguard Worker   response_info_->was_alpn_negotiated = true;
315*6777b538SAndroid Build Coastguard Worker   response_info_->request_time = stream_->GetRequestTime();
316*6777b538SAndroid Build Coastguard Worker   response_info_->connection_info = HttpConnectionInfo::kHTTP2;
317*6777b538SAndroid Build Coastguard Worker   response_info_->alpn_negotiated_protocol =
318*6777b538SAndroid Build Coastguard Worker       HttpConnectionInfoToString(response_info_->connection_info);
319*6777b538SAndroid Build Coastguard Worker 
320*6777b538SAndroid Build Coastguard Worker   // Invalidate HttpRequestInfo pointer. This is to allow |this| to be
321*6777b538SAndroid Build Coastguard Worker   // shared across multiple consumers at the cache layer which might require
322*6777b538SAndroid Build Coastguard Worker   // this stream to outlive the request_info_'s owner.
323*6777b538SAndroid Build Coastguard Worker   if (!upload_stream_in_progress_)
324*6777b538SAndroid Build Coastguard Worker     request_info_ = nullptr;
325*6777b538SAndroid Build Coastguard Worker 
326*6777b538SAndroid Build Coastguard Worker   if (!response_callback_.is_null()) {
327*6777b538SAndroid Build Coastguard Worker     DoResponseCallback(OK);
328*6777b538SAndroid Build Coastguard Worker   }
329*6777b538SAndroid Build Coastguard Worker }
330*6777b538SAndroid Build Coastguard Worker 
OnDataReceived(std::unique_ptr<SpdyBuffer> buffer)331*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnDataReceived(std::unique_ptr<SpdyBuffer> buffer) {
332*6777b538SAndroid Build Coastguard Worker   DCHECK(response_headers_complete_);
333*6777b538SAndroid Build Coastguard Worker 
334*6777b538SAndroid Build Coastguard Worker   // Note that data may be received for a SpdyStream prior to the user calling
335*6777b538SAndroid Build Coastguard Worker   // ReadResponseBody(), therefore user_buffer_ may be NULL.  This may often
336*6777b538SAndroid Build Coastguard Worker   // happen for server initiated streams.
337*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_);
338*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_->IsClosed());
339*6777b538SAndroid Build Coastguard Worker   if (buffer) {
340*6777b538SAndroid Build Coastguard Worker     response_body_queue_.Enqueue(std::move(buffer));
341*6777b538SAndroid Build Coastguard Worker     MaybeScheduleBufferedReadCallback();
342*6777b538SAndroid Build Coastguard Worker   }
343*6777b538SAndroid Build Coastguard Worker }
344*6777b538SAndroid Build Coastguard Worker 
OnDataSent()345*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnDataSent() {
346*6777b538SAndroid Build Coastguard Worker   if (request_info_ && HasUploadData()) {
347*6777b538SAndroid Build Coastguard Worker     request_body_buf_size_ = 0;
348*6777b538SAndroid Build Coastguard Worker     ReadAndSendRequestBodyData();
349*6777b538SAndroid Build Coastguard Worker   } else {
350*6777b538SAndroid Build Coastguard Worker     CHECK(spdy_session_->EndStreamWithDataFrame());
351*6777b538SAndroid Build Coastguard Worker     MaybePostRequestCallback(OK);
352*6777b538SAndroid Build Coastguard Worker   }
353*6777b538SAndroid Build Coastguard Worker }
354*6777b538SAndroid Build Coastguard Worker 
355*6777b538SAndroid Build Coastguard Worker // TODO(xunjieli): Maybe do something with the trailers. crbug.com/422958.
OnTrailers(const spdy::Http2HeaderBlock & trailers)356*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnTrailers(const spdy::Http2HeaderBlock& trailers) {}
357*6777b538SAndroid Build Coastguard Worker 
OnClose(int status)358*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnClose(int status) {
359*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_);
360*6777b538SAndroid Build Coastguard Worker 
361*6777b538SAndroid Build Coastguard Worker   // Cancel any pending reads from the upload data stream.
362*6777b538SAndroid Build Coastguard Worker   if (request_info_ && request_info_->upload_data_stream)
363*6777b538SAndroid Build Coastguard Worker     request_info_->upload_data_stream->Reset();
364*6777b538SAndroid Build Coastguard Worker 
365*6777b538SAndroid Build Coastguard Worker   stream_closed_ = true;
366*6777b538SAndroid Build Coastguard Worker   closed_stream_status_ = status;
367*6777b538SAndroid Build Coastguard Worker   closed_stream_id_ = stream_->stream_id();
368*6777b538SAndroid Build Coastguard Worker   closed_stream_has_load_timing_info_ =
369*6777b538SAndroid Build Coastguard Worker       stream_->GetLoadTimingInfo(&closed_stream_load_timing_info_);
370*6777b538SAndroid Build Coastguard Worker   closed_stream_received_bytes_ = stream_->raw_received_bytes();
371*6777b538SAndroid Build Coastguard Worker   closed_stream_sent_bytes_ = stream_->raw_sent_bytes();
372*6777b538SAndroid Build Coastguard Worker   stream_ = nullptr;
373*6777b538SAndroid Build Coastguard Worker 
374*6777b538SAndroid Build Coastguard Worker   // Callbacks might destroy |this|.
375*6777b538SAndroid Build Coastguard Worker   base::WeakPtr<SpdyHttpStream> self = weak_factory_.GetWeakPtr();
376*6777b538SAndroid Build Coastguard Worker 
377*6777b538SAndroid Build Coastguard Worker   if (!request_callback_.is_null()) {
378*6777b538SAndroid Build Coastguard Worker     DoRequestCallback(status);
379*6777b538SAndroid Build Coastguard Worker     if (!self)
380*6777b538SAndroid Build Coastguard Worker       return;
381*6777b538SAndroid Build Coastguard Worker   }
382*6777b538SAndroid Build Coastguard Worker 
383*6777b538SAndroid Build Coastguard Worker   if (status == OK) {
384*6777b538SAndroid Build Coastguard Worker     // We need to complete any pending buffered read now.
385*6777b538SAndroid Build Coastguard Worker     DoBufferedReadCallback();
386*6777b538SAndroid Build Coastguard Worker     if (!self)
387*6777b538SAndroid Build Coastguard Worker       return;
388*6777b538SAndroid Build Coastguard Worker   }
389*6777b538SAndroid Build Coastguard Worker 
390*6777b538SAndroid Build Coastguard Worker   if (!response_callback_.is_null()) {
391*6777b538SAndroid Build Coastguard Worker     DoResponseCallback(status);
392*6777b538SAndroid Build Coastguard Worker   }
393*6777b538SAndroid Build Coastguard Worker }
394*6777b538SAndroid Build Coastguard Worker 
CanGreaseFrameType() const395*6777b538SAndroid Build Coastguard Worker bool SpdyHttpStream::CanGreaseFrameType() const {
396*6777b538SAndroid Build Coastguard Worker   return true;
397*6777b538SAndroid Build Coastguard Worker }
398*6777b538SAndroid Build Coastguard Worker 
source_dependency() const399*6777b538SAndroid Build Coastguard Worker NetLogSource SpdyHttpStream::source_dependency() const {
400*6777b538SAndroid Build Coastguard Worker   return source_dependency_;
401*6777b538SAndroid Build Coastguard Worker }
402*6777b538SAndroid Build Coastguard Worker 
HasUploadData() const403*6777b538SAndroid Build Coastguard Worker bool SpdyHttpStream::HasUploadData() const {
404*6777b538SAndroid Build Coastguard Worker   CHECK(request_info_);
405*6777b538SAndroid Build Coastguard Worker   return
406*6777b538SAndroid Build Coastguard Worker       request_info_->upload_data_stream &&
407*6777b538SAndroid Build Coastguard Worker       ((request_info_->upload_data_stream->size() > 0) ||
408*6777b538SAndroid Build Coastguard Worker        request_info_->upload_data_stream->is_chunked());
409*6777b538SAndroid Build Coastguard Worker }
410*6777b538SAndroid Build Coastguard Worker 
OnStreamCreated(CompletionOnceCallback callback,int rv)411*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnStreamCreated(CompletionOnceCallback callback, int rv) {
412*6777b538SAndroid Build Coastguard Worker   if (rv == OK) {
413*6777b538SAndroid Build Coastguard Worker     stream_ = stream_request_.ReleaseStream().get();
414*6777b538SAndroid Build Coastguard Worker     InitializeStreamHelper();
415*6777b538SAndroid Build Coastguard Worker   }
416*6777b538SAndroid Build Coastguard Worker   std::move(callback).Run(rv);
417*6777b538SAndroid Build Coastguard Worker }
418*6777b538SAndroid Build Coastguard Worker 
ReadAndSendRequestBodyData()419*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::ReadAndSendRequestBodyData() {
420*6777b538SAndroid Build Coastguard Worker   CHECK(HasUploadData());
421*6777b538SAndroid Build Coastguard Worker   upload_stream_in_progress_ = true;
422*6777b538SAndroid Build Coastguard Worker 
423*6777b538SAndroid Build Coastguard Worker   CHECK_EQ(request_body_buf_size_, 0);
424*6777b538SAndroid Build Coastguard Worker   if (request_info_->upload_data_stream->IsEOF()) {
425*6777b538SAndroid Build Coastguard Worker     MaybePostRequestCallback(OK);
426*6777b538SAndroid Build Coastguard Worker 
427*6777b538SAndroid Build Coastguard Worker     // Invalidate HttpRequestInfo pointer. This is to allow |this| to be
428*6777b538SAndroid Build Coastguard Worker     // shared across multiple consumers at the cache layer which might require
429*6777b538SAndroid Build Coastguard Worker     // this stream to outlive the request_info_'s owner.
430*6777b538SAndroid Build Coastguard Worker     upload_stream_in_progress_ = false;
431*6777b538SAndroid Build Coastguard Worker     if (response_headers_complete_)
432*6777b538SAndroid Build Coastguard Worker       request_info_ = nullptr;
433*6777b538SAndroid Build Coastguard Worker     return;
434*6777b538SAndroid Build Coastguard Worker   }
435*6777b538SAndroid Build Coastguard Worker 
436*6777b538SAndroid Build Coastguard Worker   // Read the data from the request body stream.
437*6777b538SAndroid Build Coastguard Worker   const int rv = request_info_->upload_data_stream->Read(
438*6777b538SAndroid Build Coastguard Worker       request_body_buf_.get(), request_body_buf_->size(),
439*6777b538SAndroid Build Coastguard Worker       base::BindOnce(&SpdyHttpStream::OnRequestBodyReadCompleted,
440*6777b538SAndroid Build Coastguard Worker                      weak_factory_.GetWeakPtr()));
441*6777b538SAndroid Build Coastguard Worker 
442*6777b538SAndroid Build Coastguard Worker   if (rv != ERR_IO_PENDING)
443*6777b538SAndroid Build Coastguard Worker     OnRequestBodyReadCompleted(rv);
444*6777b538SAndroid Build Coastguard Worker }
445*6777b538SAndroid Build Coastguard Worker 
SendEmptyBody()446*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::SendEmptyBody() {
447*6777b538SAndroid Build Coastguard Worker   CHECK(!HasUploadData());
448*6777b538SAndroid Build Coastguard Worker   CHECK(spdy_session_->EndStreamWithDataFrame());
449*6777b538SAndroid Build Coastguard Worker 
450*6777b538SAndroid Build Coastguard Worker   auto buffer = base::MakeRefCounted<IOBufferWithSize>(/* buffer_size = */ 0);
451*6777b538SAndroid Build Coastguard Worker   stream_->SendData(buffer.get(), /* length = */ 0, NO_MORE_DATA_TO_SEND);
452*6777b538SAndroid Build Coastguard Worker }
453*6777b538SAndroid Build Coastguard Worker 
InitializeStreamHelper()454*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::InitializeStreamHelper() {
455*6777b538SAndroid Build Coastguard Worker   stream_->SetDelegate(this);
456*6777b538SAndroid Build Coastguard Worker }
457*6777b538SAndroid Build Coastguard Worker 
ResetStream(int error)458*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::ResetStream(int error) {
459*6777b538SAndroid Build Coastguard Worker   spdy_session_->ResetStream(stream()->stream_id(), error, std::string());
460*6777b538SAndroid Build Coastguard Worker }
461*6777b538SAndroid Build Coastguard Worker 
OnRequestBodyReadCompleted(int status)462*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::OnRequestBodyReadCompleted(int status) {
463*6777b538SAndroid Build Coastguard Worker   if (status < 0) {
464*6777b538SAndroid Build Coastguard Worker     DCHECK_NE(ERR_IO_PENDING, status);
465*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
466*6777b538SAndroid Build Coastguard Worker         FROM_HERE, base::BindOnce(&SpdyHttpStream::ResetStream,
467*6777b538SAndroid Build Coastguard Worker                                   weak_factory_.GetWeakPtr(), status));
468*6777b538SAndroid Build Coastguard Worker 
469*6777b538SAndroid Build Coastguard Worker     return;
470*6777b538SAndroid Build Coastguard Worker   }
471*6777b538SAndroid Build Coastguard Worker 
472*6777b538SAndroid Build Coastguard Worker   CHECK_GE(status, 0);
473*6777b538SAndroid Build Coastguard Worker   request_body_buf_size_ = status;
474*6777b538SAndroid Build Coastguard Worker   const bool eof = request_info_->upload_data_stream->IsEOF();
475*6777b538SAndroid Build Coastguard Worker   // Only the final frame may have a length of 0.
476*6777b538SAndroid Build Coastguard Worker   if (eof) {
477*6777b538SAndroid Build Coastguard Worker     CHECK_GE(request_body_buf_size_, 0);
478*6777b538SAndroid Build Coastguard Worker   } else {
479*6777b538SAndroid Build Coastguard Worker     CHECK_GT(request_body_buf_size_, 0);
480*6777b538SAndroid Build Coastguard Worker   }
481*6777b538SAndroid Build Coastguard Worker   stream_->SendData(request_body_buf_.get(),
482*6777b538SAndroid Build Coastguard Worker                     request_body_buf_size_,
483*6777b538SAndroid Build Coastguard Worker                     eof ? NO_MORE_DATA_TO_SEND : MORE_DATA_TO_SEND);
484*6777b538SAndroid Build Coastguard Worker }
485*6777b538SAndroid Build Coastguard Worker 
MaybeScheduleBufferedReadCallback()486*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::MaybeScheduleBufferedReadCallback() {
487*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_closed_);
488*6777b538SAndroid Build Coastguard Worker 
489*6777b538SAndroid Build Coastguard Worker   if (!user_buffer_.get())
490*6777b538SAndroid Build Coastguard Worker     return;
491*6777b538SAndroid Build Coastguard Worker 
492*6777b538SAndroid Build Coastguard Worker   // If enough data was received to fill the user buffer, invoke
493*6777b538SAndroid Build Coastguard Worker   // DoBufferedReadCallback() with no delay.
494*6777b538SAndroid Build Coastguard Worker   //
495*6777b538SAndroid Build Coastguard Worker   // Note: DoBufferedReadCallback() is invoked asynchronously to preserve
496*6777b538SAndroid Build Coastguard Worker   // historical behavior. It would be interesting to evaluate whether it can be
497*6777b538SAndroid Build Coastguard Worker   // invoked synchronously to avoid the overhead of posting a task. A long time
498*6777b538SAndroid Build Coastguard Worker   // ago, the callback was invoked synchronously
499*6777b538SAndroid Build Coastguard Worker   // https://codereview.chromium.org/652209/diff/2018/net/spdy/spdy_stream.cc.
500*6777b538SAndroid Build Coastguard Worker   if (response_body_queue_.GetTotalSize() >=
501*6777b538SAndroid Build Coastguard Worker       static_cast<size_t>(user_buffer_len_)) {
502*6777b538SAndroid Build Coastguard Worker     buffered_read_timer_.Start(FROM_HERE, base::TimeDelta() /* no delay */,
503*6777b538SAndroid Build Coastguard Worker                                this, &SpdyHttpStream::DoBufferedReadCallback);
504*6777b538SAndroid Build Coastguard Worker     return;
505*6777b538SAndroid Build Coastguard Worker   }
506*6777b538SAndroid Build Coastguard Worker 
507*6777b538SAndroid Build Coastguard Worker   // Handing small chunks of data to the caller creates measurable overhead.
508*6777b538SAndroid Build Coastguard Worker   // Wait 1ms to allow handing off multiple chunks of data received within a
509*6777b538SAndroid Build Coastguard Worker   // short time span at once.
510*6777b538SAndroid Build Coastguard Worker   buffered_read_timer_.Start(FROM_HERE, base::Milliseconds(1), this,
511*6777b538SAndroid Build Coastguard Worker                              &SpdyHttpStream::DoBufferedReadCallback);
512*6777b538SAndroid Build Coastguard Worker }
513*6777b538SAndroid Build Coastguard Worker 
DoBufferedReadCallback()514*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::DoBufferedReadCallback() {
515*6777b538SAndroid Build Coastguard Worker   buffered_read_timer_.Stop();
516*6777b538SAndroid Build Coastguard Worker 
517*6777b538SAndroid Build Coastguard Worker   // If the transaction is cancelled or errored out, we don't need to complete
518*6777b538SAndroid Build Coastguard Worker   // the read.
519*6777b538SAndroid Build Coastguard Worker   if (stream_closed_ && closed_stream_status_ != OK) {
520*6777b538SAndroid Build Coastguard Worker     if (response_callback_)
521*6777b538SAndroid Build Coastguard Worker       DoResponseCallback(closed_stream_status_);
522*6777b538SAndroid Build Coastguard Worker     return;
523*6777b538SAndroid Build Coastguard Worker   }
524*6777b538SAndroid Build Coastguard Worker 
525*6777b538SAndroid Build Coastguard Worker   if (!user_buffer_.get())
526*6777b538SAndroid Build Coastguard Worker     return;
527*6777b538SAndroid Build Coastguard Worker 
528*6777b538SAndroid Build Coastguard Worker   if (!response_body_queue_.IsEmpty()) {
529*6777b538SAndroid Build Coastguard Worker     int rv =
530*6777b538SAndroid Build Coastguard Worker         response_body_queue_.Dequeue(user_buffer_->data(), user_buffer_len_);
531*6777b538SAndroid Build Coastguard Worker     user_buffer_ = nullptr;
532*6777b538SAndroid Build Coastguard Worker     user_buffer_len_ = 0;
533*6777b538SAndroid Build Coastguard Worker     DoResponseCallback(rv);
534*6777b538SAndroid Build Coastguard Worker     return;
535*6777b538SAndroid Build Coastguard Worker   }
536*6777b538SAndroid Build Coastguard Worker 
537*6777b538SAndroid Build Coastguard Worker   if (stream_closed_ && response_callback_)
538*6777b538SAndroid Build Coastguard Worker     DoResponseCallback(closed_stream_status_);
539*6777b538SAndroid Build Coastguard Worker }
540*6777b538SAndroid Build Coastguard Worker 
DoRequestCallback(int rv)541*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::DoRequestCallback(int rv) {
542*6777b538SAndroid Build Coastguard Worker   CHECK_NE(rv, ERR_IO_PENDING);
543*6777b538SAndroid Build Coastguard Worker   CHECK(!request_callback_.is_null());
544*6777b538SAndroid Build Coastguard Worker   // Since Run may result in being called back, reset request_callback_ in
545*6777b538SAndroid Build Coastguard Worker   // advance.
546*6777b538SAndroid Build Coastguard Worker   std::move(request_callback_).Run(rv);
547*6777b538SAndroid Build Coastguard Worker }
548*6777b538SAndroid Build Coastguard Worker 
MaybeDoRequestCallback(int rv)549*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::MaybeDoRequestCallback(int rv) {
550*6777b538SAndroid Build Coastguard Worker   CHECK_NE(ERR_IO_PENDING, rv);
551*6777b538SAndroid Build Coastguard Worker   if (request_callback_)
552*6777b538SAndroid Build Coastguard Worker     std::move(request_callback_).Run(rv);
553*6777b538SAndroid Build Coastguard Worker }
554*6777b538SAndroid Build Coastguard Worker 
MaybePostRequestCallback(int rv)555*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::MaybePostRequestCallback(int rv) {
556*6777b538SAndroid Build Coastguard Worker   CHECK_NE(ERR_IO_PENDING, rv);
557*6777b538SAndroid Build Coastguard Worker   if (request_callback_)
558*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
559*6777b538SAndroid Build Coastguard Worker         FROM_HERE, base::BindOnce(&SpdyHttpStream::MaybeDoRequestCallback,
560*6777b538SAndroid Build Coastguard Worker                                   weak_factory_.GetWeakPtr(), rv));
561*6777b538SAndroid Build Coastguard Worker }
562*6777b538SAndroid Build Coastguard Worker 
DoResponseCallback(int rv)563*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::DoResponseCallback(int rv) {
564*6777b538SAndroid Build Coastguard Worker   CHECK_NE(rv, ERR_IO_PENDING);
565*6777b538SAndroid Build Coastguard Worker   CHECK(!response_callback_.is_null());
566*6777b538SAndroid Build Coastguard Worker 
567*6777b538SAndroid Build Coastguard Worker   // Since Run may result in being called back, reset response_callback_ in
568*6777b538SAndroid Build Coastguard Worker   // advance.
569*6777b538SAndroid Build Coastguard Worker   std::move(response_callback_).Run(rv);
570*6777b538SAndroid Build Coastguard Worker }
571*6777b538SAndroid Build Coastguard Worker 
GetRemoteEndpoint(IPEndPoint * endpoint)572*6777b538SAndroid Build Coastguard Worker int SpdyHttpStream::GetRemoteEndpoint(IPEndPoint* endpoint) {
573*6777b538SAndroid Build Coastguard Worker   if (!spdy_session_)
574*6777b538SAndroid Build Coastguard Worker     return ERR_SOCKET_NOT_CONNECTED;
575*6777b538SAndroid Build Coastguard Worker 
576*6777b538SAndroid Build Coastguard Worker   return spdy_session_->GetPeerAddress(endpoint);
577*6777b538SAndroid Build Coastguard Worker }
578*6777b538SAndroid Build Coastguard Worker 
PopulateNetErrorDetails(NetErrorDetails * details)579*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::PopulateNetErrorDetails(NetErrorDetails* details) {
580*6777b538SAndroid Build Coastguard Worker   details->connection_info = HttpConnectionInfo::kHTTP2;
581*6777b538SAndroid Build Coastguard Worker   return;
582*6777b538SAndroid Build Coastguard Worker }
583*6777b538SAndroid Build Coastguard Worker 
SetPriority(RequestPriority priority)584*6777b538SAndroid Build Coastguard Worker void SpdyHttpStream::SetPriority(RequestPriority priority) {
585*6777b538SAndroid Build Coastguard Worker   priority_ = priority;
586*6777b538SAndroid Build Coastguard Worker   if (stream_) {
587*6777b538SAndroid Build Coastguard Worker     stream_->SetPriority(priority);
588*6777b538SAndroid Build Coastguard Worker   }
589*6777b538SAndroid Build Coastguard Worker }
590*6777b538SAndroid Build Coastguard Worker 
GetDnsAliases() const591*6777b538SAndroid Build Coastguard Worker const std::set<std::string>& SpdyHttpStream::GetDnsAliases() const {
592*6777b538SAndroid Build Coastguard Worker   return dns_aliases_;
593*6777b538SAndroid Build Coastguard Worker }
594*6777b538SAndroid Build Coastguard Worker 
GetAcceptChViaAlps() const595*6777b538SAndroid Build Coastguard Worker std::string_view SpdyHttpStream::GetAcceptChViaAlps() const {
596*6777b538SAndroid Build Coastguard Worker   if (!request_info_) {
597*6777b538SAndroid Build Coastguard Worker     return {};
598*6777b538SAndroid Build Coastguard Worker   }
599*6777b538SAndroid Build Coastguard Worker 
600*6777b538SAndroid Build Coastguard Worker   return session()->GetAcceptChViaAlps(url::SchemeHostPort(request_info_->url));
601*6777b538SAndroid Build Coastguard Worker }
602*6777b538SAndroid Build Coastguard Worker 
603*6777b538SAndroid Build Coastguard Worker }  // namespace net
604