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