xref: /aosp_15_r20/external/cronet/net/http/bidirectional_stream.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2015 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/http/bidirectional_stream.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <string>
8*6777b538SAndroid Build Coastguard Worker #include <utility>
9*6777b538SAndroid Build Coastguard Worker #include <vector>
10*6777b538SAndroid Build Coastguard Worker 
11*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/location.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/logging.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/metrics/histogram_macros.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/timer/timer.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/values.h"
18*6777b538SAndroid Build Coastguard Worker #include "net/base/load_flags.h"
19*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
20*6777b538SAndroid Build Coastguard Worker #include "net/http/bidirectional_stream_request_info.h"
21*6777b538SAndroid Build Coastguard Worker #include "net/http/http_network_session.h"
22*6777b538SAndroid Build Coastguard Worker #include "net/http/http_response_headers.h"
23*6777b538SAndroid Build Coastguard Worker #include "net/http/http_stream.h"
24*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_capture_mode.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_event_type.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_source_type.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/log/net_log_values.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_http_utils.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/spdy/spdy_log_util.h"
31*6777b538SAndroid Build Coastguard Worker #include "net/ssl/ssl_cert_request_info.h"
32*6777b538SAndroid Build Coastguard Worker #include "net/third_party/quiche/src/quiche/spdy/core/http2_header_block.h"
33*6777b538SAndroid Build Coastguard Worker #include "net/traffic_annotation/network_traffic_annotation.h"
34*6777b538SAndroid Build Coastguard Worker #include "url/gurl.h"
35*6777b538SAndroid Build Coastguard Worker 
36*6777b538SAndroid Build Coastguard Worker namespace net {
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker namespace {
39*6777b538SAndroid Build Coastguard Worker 
NetLogHeadersParams(const spdy::Http2HeaderBlock * headers,NetLogCaptureMode capture_mode)40*6777b538SAndroid Build Coastguard Worker base::Value::Dict NetLogHeadersParams(const spdy::Http2HeaderBlock* headers,
41*6777b538SAndroid Build Coastguard Worker                                       NetLogCaptureMode capture_mode) {
42*6777b538SAndroid Build Coastguard Worker   base::Value::Dict dict;
43*6777b538SAndroid Build Coastguard Worker   dict.Set("headers", ElideHttp2HeaderBlockForNetLog(*headers, capture_mode));
44*6777b538SAndroid Build Coastguard Worker   return dict;
45*6777b538SAndroid Build Coastguard Worker }
46*6777b538SAndroid Build Coastguard Worker 
NetLogParams(const GURL & url,const std::string & method,const HttpRequestHeaders * headers,NetLogCaptureMode capture_mode)47*6777b538SAndroid Build Coastguard Worker base::Value::Dict NetLogParams(const GURL& url,
48*6777b538SAndroid Build Coastguard Worker                                const std::string& method,
49*6777b538SAndroid Build Coastguard Worker                                const HttpRequestHeaders* headers,
50*6777b538SAndroid Build Coastguard Worker                                NetLogCaptureMode capture_mode) {
51*6777b538SAndroid Build Coastguard Worker   base::Value::Dict dict;
52*6777b538SAndroid Build Coastguard Worker   dict.Set("url", url.possibly_invalid_spec());
53*6777b538SAndroid Build Coastguard Worker   dict.Set("method", method);
54*6777b538SAndroid Build Coastguard Worker   base::Value headers_param(
55*6777b538SAndroid Build Coastguard Worker       headers->NetLogParams(/*request_line=*/std::string(), capture_mode));
56*6777b538SAndroid Build Coastguard Worker   dict.Set("headers", std::move(headers_param));
57*6777b538SAndroid Build Coastguard Worker   return dict;
58*6777b538SAndroid Build Coastguard Worker }
59*6777b538SAndroid Build Coastguard Worker 
60*6777b538SAndroid Build Coastguard Worker }  // namespace
61*6777b538SAndroid Build Coastguard Worker 
62*6777b538SAndroid Build Coastguard Worker BidirectionalStream::Delegate::Delegate() = default;
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker BidirectionalStream::Delegate::~Delegate() = default;
65*6777b538SAndroid Build Coastguard Worker 
BidirectionalStream(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,HttpNetworkSession * session,bool send_request_headers_automatically,Delegate * delegate)66*6777b538SAndroid Build Coastguard Worker BidirectionalStream::BidirectionalStream(
67*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
68*6777b538SAndroid Build Coastguard Worker     HttpNetworkSession* session,
69*6777b538SAndroid Build Coastguard Worker     bool send_request_headers_automatically,
70*6777b538SAndroid Build Coastguard Worker     Delegate* delegate)
71*6777b538SAndroid Build Coastguard Worker     : BidirectionalStream(std::move(request_info),
72*6777b538SAndroid Build Coastguard Worker                           session,
73*6777b538SAndroid Build Coastguard Worker                           send_request_headers_automatically,
74*6777b538SAndroid Build Coastguard Worker                           delegate,
75*6777b538SAndroid Build Coastguard Worker                           std::make_unique<base::OneShotTimer>()) {}
76*6777b538SAndroid Build Coastguard Worker 
BidirectionalStream(std::unique_ptr<BidirectionalStreamRequestInfo> request_info,HttpNetworkSession * session,bool send_request_headers_automatically,Delegate * delegate,std::unique_ptr<base::OneShotTimer> timer)77*6777b538SAndroid Build Coastguard Worker BidirectionalStream::BidirectionalStream(
78*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<BidirectionalStreamRequestInfo> request_info,
79*6777b538SAndroid Build Coastguard Worker     HttpNetworkSession* session,
80*6777b538SAndroid Build Coastguard Worker     bool send_request_headers_automatically,
81*6777b538SAndroid Build Coastguard Worker     Delegate* delegate,
82*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<base::OneShotTimer> timer)
83*6777b538SAndroid Build Coastguard Worker     : request_info_(std::move(request_info)),
84*6777b538SAndroid Build Coastguard Worker       net_log_(NetLogWithSource::Make(session->net_log(),
85*6777b538SAndroid Build Coastguard Worker                                       NetLogSourceType::BIDIRECTIONAL_STREAM)),
86*6777b538SAndroid Build Coastguard Worker       session_(session),
87*6777b538SAndroid Build Coastguard Worker       send_request_headers_automatically_(send_request_headers_automatically),
88*6777b538SAndroid Build Coastguard Worker       delegate_(delegate),
89*6777b538SAndroid Build Coastguard Worker       timer_(std::move(timer)) {
90*6777b538SAndroid Build Coastguard Worker   DCHECK(delegate_);
91*6777b538SAndroid Build Coastguard Worker   DCHECK(request_info_);
92*6777b538SAndroid Build Coastguard Worker 
93*6777b538SAndroid Build Coastguard Worker   // Start time should be measured before connect.
94*6777b538SAndroid Build Coastguard Worker   load_timing_info_.request_start_time = base::Time::Now();
95*6777b538SAndroid Build Coastguard Worker   load_timing_info_.request_start = base::TimeTicks::Now();
96*6777b538SAndroid Build Coastguard Worker 
97*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
98*6777b538SAndroid Build Coastguard Worker     net_log_.BeginEvent(NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE,
99*6777b538SAndroid Build Coastguard Worker                         [&](NetLogCaptureMode capture_mode) {
100*6777b538SAndroid Build Coastguard Worker                           return NetLogParams(
101*6777b538SAndroid Build Coastguard Worker                               request_info_->url, request_info_->method,
102*6777b538SAndroid Build Coastguard Worker                               &request_info_->extra_headers, capture_mode);
103*6777b538SAndroid Build Coastguard Worker                         });
104*6777b538SAndroid Build Coastguard Worker   }
105*6777b538SAndroid Build Coastguard Worker 
106*6777b538SAndroid Build Coastguard Worker   if (!request_info_->url.SchemeIs(url::kHttpsScheme)) {
107*6777b538SAndroid Build Coastguard Worker     base::SingleThreadTaskRunner::GetCurrentDefault()->PostTask(
108*6777b538SAndroid Build Coastguard Worker         FROM_HERE,
109*6777b538SAndroid Build Coastguard Worker         base::BindOnce(&BidirectionalStream::NotifyFailed,
110*6777b538SAndroid Build Coastguard Worker                        weak_factory_.GetWeakPtr(), ERR_DISALLOWED_URL_SCHEME));
111*6777b538SAndroid Build Coastguard Worker     return;
112*6777b538SAndroid Build Coastguard Worker   }
113*6777b538SAndroid Build Coastguard Worker 
114*6777b538SAndroid Build Coastguard Worker   StartRequest();
115*6777b538SAndroid Build Coastguard Worker }
116*6777b538SAndroid Build Coastguard Worker 
~BidirectionalStream()117*6777b538SAndroid Build Coastguard Worker BidirectionalStream::~BidirectionalStream() {
118*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
119*6777b538SAndroid Build Coastguard Worker     net_log_.EndEvent(NetLogEventType::BIDIRECTIONAL_STREAM_ALIVE);
120*6777b538SAndroid Build Coastguard Worker   }
121*6777b538SAndroid Build Coastguard Worker }
122*6777b538SAndroid Build Coastguard Worker 
SendRequestHeaders()123*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::SendRequestHeaders() {
124*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_impl_);
125*6777b538SAndroid Build Coastguard Worker   DCHECK(!request_headers_sent_);
126*6777b538SAndroid Build Coastguard Worker   DCHECK(!send_request_headers_automatically_);
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   stream_impl_->SendRequestHeaders();
129*6777b538SAndroid Build Coastguard Worker }
130*6777b538SAndroid Build Coastguard Worker 
ReadData(IOBuffer * buf,int buf_len)131*6777b538SAndroid Build Coastguard Worker int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) {
132*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_impl_);
133*6777b538SAndroid Build Coastguard Worker 
134*6777b538SAndroid Build Coastguard Worker   int rv = stream_impl_->ReadData(buf, buf_len);
135*6777b538SAndroid Build Coastguard Worker   if (rv > 0) {
136*6777b538SAndroid Build Coastguard Worker     read_end_time_ = base::TimeTicks::Now();
137*6777b538SAndroid Build Coastguard Worker     net_log_.AddByteTransferEvent(
138*6777b538SAndroid Build Coastguard Worker         NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_RECEIVED, rv, buf->data());
139*6777b538SAndroid Build Coastguard Worker   } else if (rv == ERR_IO_PENDING) {
140*6777b538SAndroid Build Coastguard Worker     read_buffer_ = buf;
141*6777b538SAndroid Build Coastguard Worker     // Bytes will be logged in OnDataRead().
142*6777b538SAndroid Build Coastguard Worker   }
143*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
144*6777b538SAndroid Build Coastguard Worker     net_log_.AddEventWithIntParams(
145*6777b538SAndroid Build Coastguard Worker         NetLogEventType::BIDIRECTIONAL_STREAM_READ_DATA, "rv", rv);
146*6777b538SAndroid Build Coastguard Worker   }
147*6777b538SAndroid Build Coastguard Worker   return rv;
148*6777b538SAndroid Build Coastguard Worker }
149*6777b538SAndroid Build Coastguard Worker 
SendvData(const std::vector<scoped_refptr<IOBuffer>> & buffers,const std::vector<int> & lengths,bool end_stream)150*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::SendvData(
151*6777b538SAndroid Build Coastguard Worker     const std::vector<scoped_refptr<IOBuffer>>& buffers,
152*6777b538SAndroid Build Coastguard Worker     const std::vector<int>& lengths,
153*6777b538SAndroid Build Coastguard Worker     bool end_stream) {
154*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_impl_);
155*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(buffers.size(), lengths.size());
156*6777b538SAndroid Build Coastguard Worker   DCHECK(write_buffer_list_.empty());
157*6777b538SAndroid Build Coastguard Worker   DCHECK(write_buffer_len_list_.empty());
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
160*6777b538SAndroid Build Coastguard Worker     net_log_.AddEventWithIntParams(
161*6777b538SAndroid Build Coastguard Worker         NetLogEventType::BIDIRECTIONAL_STREAM_SENDV_DATA, "num_buffers",
162*6777b538SAndroid Build Coastguard Worker         buffers.size());
163*6777b538SAndroid Build Coastguard Worker   }
164*6777b538SAndroid Build Coastguard Worker   stream_impl_->SendvData(buffers, lengths, end_stream);
165*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < buffers.size(); ++i) {
166*6777b538SAndroid Build Coastguard Worker     write_buffer_list_.push_back(buffers[i]);
167*6777b538SAndroid Build Coastguard Worker     write_buffer_len_list_.push_back(lengths[i]);
168*6777b538SAndroid Build Coastguard Worker   }
169*6777b538SAndroid Build Coastguard Worker }
170*6777b538SAndroid Build Coastguard Worker 
GetProtocol() const171*6777b538SAndroid Build Coastguard Worker NextProto BidirectionalStream::GetProtocol() const {
172*6777b538SAndroid Build Coastguard Worker   if (!stream_impl_)
173*6777b538SAndroid Build Coastguard Worker     return kProtoUnknown;
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   return stream_impl_->GetProtocol();
176*6777b538SAndroid Build Coastguard Worker }
177*6777b538SAndroid Build Coastguard Worker 
GetTotalReceivedBytes() const178*6777b538SAndroid Build Coastguard Worker int64_t BidirectionalStream::GetTotalReceivedBytes() const {
179*6777b538SAndroid Build Coastguard Worker   if (!stream_impl_)
180*6777b538SAndroid Build Coastguard Worker     return 0;
181*6777b538SAndroid Build Coastguard Worker 
182*6777b538SAndroid Build Coastguard Worker   return stream_impl_->GetTotalReceivedBytes();
183*6777b538SAndroid Build Coastguard Worker }
184*6777b538SAndroid Build Coastguard Worker 
GetTotalSentBytes() const185*6777b538SAndroid Build Coastguard Worker int64_t BidirectionalStream::GetTotalSentBytes() const {
186*6777b538SAndroid Build Coastguard Worker   if (!stream_impl_)
187*6777b538SAndroid Build Coastguard Worker     return 0;
188*6777b538SAndroid Build Coastguard Worker 
189*6777b538SAndroid Build Coastguard Worker   return stream_impl_->GetTotalSentBytes();
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker 
GetLoadTimingInfo(LoadTimingInfo * load_timing_info) const192*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::GetLoadTimingInfo(
193*6777b538SAndroid Build Coastguard Worker     LoadTimingInfo* load_timing_info) const {
194*6777b538SAndroid Build Coastguard Worker   *load_timing_info = load_timing_info_;
195*6777b538SAndroid Build Coastguard Worker }
196*6777b538SAndroid Build Coastguard Worker 
PopulateNetErrorDetails(NetErrorDetails * details)197*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::PopulateNetErrorDetails(NetErrorDetails* details) {
198*6777b538SAndroid Build Coastguard Worker   DCHECK(details);
199*6777b538SAndroid Build Coastguard Worker   if (stream_impl_)
200*6777b538SAndroid Build Coastguard Worker     stream_impl_->PopulateNetErrorDetails(details);
201*6777b538SAndroid Build Coastguard Worker }
202*6777b538SAndroid Build Coastguard Worker 
StartRequest()203*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::StartRequest() {
204*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_request_);
205*6777b538SAndroid Build Coastguard Worker   HttpRequestInfo http_request_info;
206*6777b538SAndroid Build Coastguard Worker   http_request_info.url = request_info_->url;
207*6777b538SAndroid Build Coastguard Worker   http_request_info.method = request_info_->method;
208*6777b538SAndroid Build Coastguard Worker   http_request_info.extra_headers = request_info_->extra_headers;
209*6777b538SAndroid Build Coastguard Worker   http_request_info.socket_tag = request_info_->socket_tag;
210*6777b538SAndroid Build Coastguard Worker   stream_request_ =
211*6777b538SAndroid Build Coastguard Worker       session_->http_stream_factory()->RequestBidirectionalStreamImpl(
212*6777b538SAndroid Build Coastguard Worker           http_request_info, request_info_->priority, /*allowed_bad_certs=*/{},
213*6777b538SAndroid Build Coastguard Worker           this, /* enable_ip_based_pooling = */ true,
214*6777b538SAndroid Build Coastguard Worker           /* enable_alternative_services = */ true, net_log_);
215*6777b538SAndroid Build Coastguard Worker   // Check that this call does not fail.
216*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_request_);
217*6777b538SAndroid Build Coastguard Worker   // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady
218*6777b538SAndroid Build Coastguard Worker   // synchronously.
219*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_impl_);
220*6777b538SAndroid Build Coastguard Worker }
221*6777b538SAndroid Build Coastguard Worker 
OnStreamReady(bool request_headers_sent)222*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnStreamReady(bool request_headers_sent) {
223*6777b538SAndroid Build Coastguard Worker   request_headers_sent_ = request_headers_sent;
224*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
225*6777b538SAndroid Build Coastguard Worker     net_log_.AddEntryWithBoolParams(
226*6777b538SAndroid Build Coastguard Worker         NetLogEventType::BIDIRECTIONAL_STREAM_READY, NetLogEventPhase::NONE,
227*6777b538SAndroid Build Coastguard Worker         "request_headers_sent", request_headers_sent);
228*6777b538SAndroid Build Coastguard Worker   }
229*6777b538SAndroid Build Coastguard Worker   load_timing_info_.send_start = base::TimeTicks::Now();
230*6777b538SAndroid Build Coastguard Worker   load_timing_info_.send_end = load_timing_info_.send_start;
231*6777b538SAndroid Build Coastguard Worker   delegate_->OnStreamReady(request_headers_sent);
232*6777b538SAndroid Build Coastguard Worker }
233*6777b538SAndroid Build Coastguard Worker 
OnHeadersReceived(const spdy::Http2HeaderBlock & response_headers)234*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnHeadersReceived(
235*6777b538SAndroid Build Coastguard Worker     const spdy::Http2HeaderBlock& response_headers) {
236*6777b538SAndroid Build Coastguard Worker   HttpResponseInfo response_info;
237*6777b538SAndroid Build Coastguard Worker   if (SpdyHeadersToHttpResponse(response_headers, &response_info) != OK) {
238*6777b538SAndroid Build Coastguard Worker     DLOG(WARNING) << "Invalid headers";
239*6777b538SAndroid Build Coastguard Worker     NotifyFailed(ERR_FAILED);
240*6777b538SAndroid Build Coastguard Worker     return;
241*6777b538SAndroid Build Coastguard Worker   }
242*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
243*6777b538SAndroid Build Coastguard Worker     net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_RECV_HEADERS,
244*6777b538SAndroid Build Coastguard Worker                       [&](NetLogCaptureMode capture_mode) {
245*6777b538SAndroid Build Coastguard Worker                         return NetLogHeadersParams(&response_headers,
246*6777b538SAndroid Build Coastguard Worker                                                    capture_mode);
247*6777b538SAndroid Build Coastguard Worker                       });
248*6777b538SAndroid Build Coastguard Worker   }
249*6777b538SAndroid Build Coastguard Worker   // Impl should only provide |connect_timing| and |socket_reused| info,
250*6777b538SAndroid Build Coastguard Worker   // so use a copy to get these information only.
251*6777b538SAndroid Build Coastguard Worker   LoadTimingInfo impl_load_timing_info;
252*6777b538SAndroid Build Coastguard Worker   bool has_load_timing =
253*6777b538SAndroid Build Coastguard Worker       stream_impl_->GetLoadTimingInfo(&impl_load_timing_info);
254*6777b538SAndroid Build Coastguard Worker   if (has_load_timing) {
255*6777b538SAndroid Build Coastguard Worker     load_timing_info_.connect_timing = impl_load_timing_info.connect_timing;
256*6777b538SAndroid Build Coastguard Worker     load_timing_info_.socket_reused = impl_load_timing_info.socket_reused;
257*6777b538SAndroid Build Coastguard Worker   }
258*6777b538SAndroid Build Coastguard Worker   load_timing_info_.receive_headers_end = base::TimeTicks::Now();
259*6777b538SAndroid Build Coastguard Worker   read_end_time_ = load_timing_info_.receive_headers_end;
260*6777b538SAndroid Build Coastguard Worker   session_->http_stream_factory()->ProcessAlternativeServices(
261*6777b538SAndroid Build Coastguard Worker       session_, net::NetworkAnonymizationKey(), response_info.headers.get(),
262*6777b538SAndroid Build Coastguard Worker       url::SchemeHostPort(request_info_->url));
263*6777b538SAndroid Build Coastguard Worker   delegate_->OnHeadersReceived(response_headers);
264*6777b538SAndroid Build Coastguard Worker }
265*6777b538SAndroid Build Coastguard Worker 
OnDataRead(int bytes_read)266*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnDataRead(int bytes_read) {
267*6777b538SAndroid Build Coastguard Worker   DCHECK(read_buffer_);
268*6777b538SAndroid Build Coastguard Worker 
269*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
270*6777b538SAndroid Build Coastguard Worker     net_log_.AddByteTransferEvent(
271*6777b538SAndroid Build Coastguard Worker         NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read,
272*6777b538SAndroid Build Coastguard Worker         read_buffer_->data());
273*6777b538SAndroid Build Coastguard Worker   }
274*6777b538SAndroid Build Coastguard Worker   read_end_time_ = base::TimeTicks::Now();
275*6777b538SAndroid Build Coastguard Worker   read_buffer_ = nullptr;
276*6777b538SAndroid Build Coastguard Worker   delegate_->OnDataRead(bytes_read);
277*6777b538SAndroid Build Coastguard Worker }
278*6777b538SAndroid Build Coastguard Worker 
OnDataSent()279*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnDataSent() {
280*6777b538SAndroid Build Coastguard Worker   DCHECK(!write_buffer_list_.empty());
281*6777b538SAndroid Build Coastguard Worker   DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size());
282*6777b538SAndroid Build Coastguard Worker 
283*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
284*6777b538SAndroid Build Coastguard Worker     if (write_buffer_list_.size() > 1) {
285*6777b538SAndroid Build Coastguard Worker       net_log_.BeginEvent(
286*6777b538SAndroid Build Coastguard Worker           NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED, [&] {
287*6777b538SAndroid Build Coastguard Worker             return NetLogParamsWithInt("num_buffers_coalesced",
288*6777b538SAndroid Build Coastguard Worker                                        write_buffer_list_.size());
289*6777b538SAndroid Build Coastguard Worker           });
290*6777b538SAndroid Build Coastguard Worker     }
291*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < write_buffer_list_.size(); ++i) {
292*6777b538SAndroid Build Coastguard Worker       net_log_.AddByteTransferEvent(
293*6777b538SAndroid Build Coastguard Worker           NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT,
294*6777b538SAndroid Build Coastguard Worker           write_buffer_len_list_[i], write_buffer_list_[i]->data());
295*6777b538SAndroid Build Coastguard Worker     }
296*6777b538SAndroid Build Coastguard Worker     if (write_buffer_list_.size() > 1) {
297*6777b538SAndroid Build Coastguard Worker       net_log_.EndEvent(
298*6777b538SAndroid Build Coastguard Worker           NetLogEventType::BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED);
299*6777b538SAndroid Build Coastguard Worker     }
300*6777b538SAndroid Build Coastguard Worker   }
301*6777b538SAndroid Build Coastguard Worker   load_timing_info_.send_end = base::TimeTicks::Now();
302*6777b538SAndroid Build Coastguard Worker   write_buffer_list_.clear();
303*6777b538SAndroid Build Coastguard Worker   write_buffer_len_list_.clear();
304*6777b538SAndroid Build Coastguard Worker   delegate_->OnDataSent();
305*6777b538SAndroid Build Coastguard Worker }
306*6777b538SAndroid Build Coastguard Worker 
OnTrailersReceived(const spdy::Http2HeaderBlock & trailers)307*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnTrailersReceived(
308*6777b538SAndroid Build Coastguard Worker     const spdy::Http2HeaderBlock& trailers) {
309*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
310*6777b538SAndroid Build Coastguard Worker     net_log_.AddEvent(NetLogEventType::BIDIRECTIONAL_STREAM_RECV_TRAILERS,
311*6777b538SAndroid Build Coastguard Worker                       [&](NetLogCaptureMode capture_mode) {
312*6777b538SAndroid Build Coastguard Worker                         return NetLogHeadersParams(&trailers, capture_mode);
313*6777b538SAndroid Build Coastguard Worker                       });
314*6777b538SAndroid Build Coastguard Worker   }
315*6777b538SAndroid Build Coastguard Worker   read_end_time_ = base::TimeTicks::Now();
316*6777b538SAndroid Build Coastguard Worker   delegate_->OnTrailersReceived(trailers);
317*6777b538SAndroid Build Coastguard Worker }
318*6777b538SAndroid Build Coastguard Worker 
OnFailed(int status)319*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnFailed(int status) {
320*6777b538SAndroid Build Coastguard Worker   if (net_log_.IsCapturing()) {
321*6777b538SAndroid Build Coastguard Worker     net_log_.AddEventWithIntParams(NetLogEventType::BIDIRECTIONAL_STREAM_FAILED,
322*6777b538SAndroid Build Coastguard Worker                                    "net_error", status);
323*6777b538SAndroid Build Coastguard Worker   }
324*6777b538SAndroid Build Coastguard Worker   NotifyFailed(status);
325*6777b538SAndroid Build Coastguard Worker }
326*6777b538SAndroid Build Coastguard Worker 
OnStreamReady(const ProxyInfo & used_proxy_info,std::unique_ptr<HttpStream> stream)327*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnStreamReady(const ProxyInfo& used_proxy_info,
328*6777b538SAndroid Build Coastguard Worker                                         std::unique_ptr<HttpStream> stream) {
329*6777b538SAndroid Build Coastguard Worker   NOTREACHED();
330*6777b538SAndroid Build Coastguard Worker }
331*6777b538SAndroid Build Coastguard Worker 
OnBidirectionalStreamImplReady(const ProxyInfo & used_proxy_info,std::unique_ptr<BidirectionalStreamImpl> stream)332*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnBidirectionalStreamImplReady(
333*6777b538SAndroid Build Coastguard Worker     const ProxyInfo& used_proxy_info,
334*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<BidirectionalStreamImpl> stream) {
335*6777b538SAndroid Build Coastguard Worker   DCHECK(!stream_impl_);
336*6777b538SAndroid Build Coastguard Worker 
337*6777b538SAndroid Build Coastguard Worker   net::NetworkTrafficAnnotationTag traffic_annotation =
338*6777b538SAndroid Build Coastguard Worker       net::DefineNetworkTrafficAnnotation("bidirectional_stream", R"(
339*6777b538SAndroid Build Coastguard Worker         semantics {
340*6777b538SAndroid Build Coastguard Worker           sender: "Bidirectional Stream"
341*6777b538SAndroid Build Coastguard Worker           description:
342*6777b538SAndroid Build Coastguard Worker             "Bidirectional stream is used to exchange data with a server on "
343*6777b538SAndroid Build Coastguard Worker             "behalf of an RPC API."
344*6777b538SAndroid Build Coastguard Worker           trigger:
345*6777b538SAndroid Build Coastguard Worker             "When an application makes an RPC to the server."
346*6777b538SAndroid Build Coastguard Worker           data:
347*6777b538SAndroid Build Coastguard Worker             "Any arbitrary data."
348*6777b538SAndroid Build Coastguard Worker           destination: OTHER
349*6777b538SAndroid Build Coastguard Worker           destination_other:
350*6777b538SAndroid Build Coastguard Worker             "Any destination that the application chooses."
351*6777b538SAndroid Build Coastguard Worker         }
352*6777b538SAndroid Build Coastguard Worker         policy {
353*6777b538SAndroid Build Coastguard Worker           cookies_allowed: NO
354*6777b538SAndroid Build Coastguard Worker           setting: "This feature is not used in Chrome."
355*6777b538SAndroid Build Coastguard Worker           policy_exception_justification:
356*6777b538SAndroid Build Coastguard Worker             "This feature is not used in Chrome."
357*6777b538SAndroid Build Coastguard Worker         }
358*6777b538SAndroid Build Coastguard Worker     )");
359*6777b538SAndroid Build Coastguard Worker 
360*6777b538SAndroid Build Coastguard Worker   stream_request_.reset();
361*6777b538SAndroid Build Coastguard Worker   stream_impl_ = std::move(stream);
362*6777b538SAndroid Build Coastguard Worker   stream_impl_->Start(request_info_.get(), net_log_,
363*6777b538SAndroid Build Coastguard Worker                       send_request_headers_automatically_, this,
364*6777b538SAndroid Build Coastguard Worker                       std::move(timer_), traffic_annotation);
365*6777b538SAndroid Build Coastguard Worker }
366*6777b538SAndroid Build Coastguard Worker 
OnWebSocketHandshakeStreamReady(const ProxyInfo & used_proxy_info,std::unique_ptr<WebSocketHandshakeStreamBase> stream)367*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnWebSocketHandshakeStreamReady(
368*6777b538SAndroid Build Coastguard Worker     const ProxyInfo& used_proxy_info,
369*6777b538SAndroid Build Coastguard Worker     std::unique_ptr<WebSocketHandshakeStreamBase> stream) {
370*6777b538SAndroid Build Coastguard Worker   NOTREACHED();
371*6777b538SAndroid Build Coastguard Worker }
372*6777b538SAndroid Build Coastguard Worker 
OnStreamFailed(int result,const NetErrorDetails & net_error_details,const ProxyInfo & used_proxy_info,ResolveErrorInfo resolve_error_info)373*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnStreamFailed(
374*6777b538SAndroid Build Coastguard Worker     int result,
375*6777b538SAndroid Build Coastguard Worker     const NetErrorDetails& net_error_details,
376*6777b538SAndroid Build Coastguard Worker     const ProxyInfo& used_proxy_info,
377*6777b538SAndroid Build Coastguard Worker     ResolveErrorInfo resolve_error_info) {
378*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(result, 0);
379*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(result, ERR_IO_PENDING);
380*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_request_);
381*6777b538SAndroid Build Coastguard Worker 
382*6777b538SAndroid Build Coastguard Worker   NotifyFailed(result);
383*6777b538SAndroid Build Coastguard Worker }
384*6777b538SAndroid Build Coastguard Worker 
OnCertificateError(int result,const SSLInfo & ssl_info)385*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnCertificateError(int result,
386*6777b538SAndroid Build Coastguard Worker                                              const SSLInfo& ssl_info) {
387*6777b538SAndroid Build Coastguard Worker   DCHECK_LT(result, 0);
388*6777b538SAndroid Build Coastguard Worker   DCHECK_NE(result, ERR_IO_PENDING);
389*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_request_);
390*6777b538SAndroid Build Coastguard Worker 
391*6777b538SAndroid Build Coastguard Worker   NotifyFailed(result);
392*6777b538SAndroid Build Coastguard Worker }
393*6777b538SAndroid Build Coastguard Worker 
OnNeedsProxyAuth(const HttpResponseInfo & proxy_response,const ProxyInfo & used_proxy_info,HttpAuthController * auth_controller)394*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnNeedsProxyAuth(
395*6777b538SAndroid Build Coastguard Worker     const HttpResponseInfo& proxy_response,
396*6777b538SAndroid Build Coastguard Worker     const ProxyInfo& used_proxy_info,
397*6777b538SAndroid Build Coastguard Worker     HttpAuthController* auth_controller) {
398*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_request_);
399*6777b538SAndroid Build Coastguard Worker 
400*6777b538SAndroid Build Coastguard Worker   NotifyFailed(ERR_PROXY_AUTH_REQUESTED);
401*6777b538SAndroid Build Coastguard Worker }
402*6777b538SAndroid Build Coastguard Worker 
OnNeedsClientAuth(SSLCertRequestInfo * cert_info)403*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnNeedsClientAuth(SSLCertRequestInfo* cert_info) {
404*6777b538SAndroid Build Coastguard Worker   DCHECK(stream_request_);
405*6777b538SAndroid Build Coastguard Worker 
406*6777b538SAndroid Build Coastguard Worker   // BidirectionalStream doesn't support client auth. It ignores client auth
407*6777b538SAndroid Build Coastguard Worker   // requests with null client cert and key.
408*6777b538SAndroid Build Coastguard Worker   session_->ssl_client_context()->SetClientCertificate(cert_info->host_and_port,
409*6777b538SAndroid Build Coastguard Worker                                                        nullptr, nullptr);
410*6777b538SAndroid Build Coastguard Worker   stream_request_ = nullptr;
411*6777b538SAndroid Build Coastguard Worker   StartRequest();
412*6777b538SAndroid Build Coastguard Worker }
413*6777b538SAndroid Build Coastguard Worker 
OnQuicBroken()414*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::OnQuicBroken() {}
415*6777b538SAndroid Build Coastguard Worker 
NotifyFailed(int error)416*6777b538SAndroid Build Coastguard Worker void BidirectionalStream::NotifyFailed(int error) {
417*6777b538SAndroid Build Coastguard Worker   delegate_->OnFailed(error);
418*6777b538SAndroid Build Coastguard Worker }
419*6777b538SAndroid Build Coastguard Worker 
420*6777b538SAndroid Build Coastguard Worker }  // namespace net
421