| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/http/bidirectional_stream.h" | 5 #include "net/http/bidirectional_stream.h" |
| 6 | 6 |
| 7 #include <memory> | 7 #include <memory> |
| 8 #include <string> | 8 #include <string> |
| 9 | 9 |
| 10 #include "base/bind.h" | 10 #include "base/bind.h" |
| 11 #include "base/location.h" | 11 #include "base/location.h" |
| 12 #include "base/logging.h" | 12 #include "base/logging.h" |
| 13 #include "base/memory/ptr_util.h" | 13 #include "base/memory/ptr_util.h" |
| 14 #include "base/metrics/histogram_macros.h" |
| 14 #include "base/threading/thread_task_runner_handle.h" | 15 #include "base/threading/thread_task_runner_handle.h" |
| 15 #include "base/time/time.h" | |
| 16 #include "base/timer/timer.h" | 16 #include "base/timer/timer.h" |
| 17 #include "base/values.h" | 17 #include "base/values.h" |
| 18 #include "net/base/load_flags.h" | 18 #include "net/base/load_flags.h" |
| 19 #include "net/base/net_errors.h" | 19 #include "net/base/net_errors.h" |
| 20 #include "net/http/bidirectional_stream_request_info.h" | 20 #include "net/http/bidirectional_stream_request_info.h" |
| 21 #include "net/http/http_log_util.h" | 21 #include "net/http/http_log_util.h" |
| 22 #include "net/http/http_network_session.h" | 22 #include "net/http/http_network_session.h" |
| 23 #include "net/http/http_response_headers.h" | 23 #include "net/http/http_response_headers.h" |
| 24 #include "net/http/http_stream.h" | 24 #include "net/http/http_stream.h" |
| 25 #include "net/log/net_log_capture_mode.h" | 25 #include "net/log/net_log_capture_mode.h" |
| (...skipping 93 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 119 http_request_info, request_info_->priority, server_ssl_config, | 119 http_request_info, request_info_->priority, server_ssl_config, |
| 120 server_ssl_config, this, net_log_)); | 120 server_ssl_config, this, net_log_)); |
| 121 // Check that this call cannot fail to set a non-NULL |stream_request_|. | 121 // Check that this call cannot fail to set a non-NULL |stream_request_|. |
| 122 DCHECK(stream_request_); | 122 DCHECK(stream_request_); |
| 123 // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady | 123 // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady |
| 124 // synchronously. | 124 // synchronously. |
| 125 DCHECK(!stream_impl_); | 125 DCHECK(!stream_impl_); |
| 126 } | 126 } |
| 127 | 127 |
| 128 BidirectionalStream::~BidirectionalStream() { | 128 BidirectionalStream::~BidirectionalStream() { |
| 129 UpdateHistograms(); |
| 129 if (net_log_.IsCapturing()) { | 130 if (net_log_.IsCapturing()) { |
| 130 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE); | 131 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE); |
| 131 } | 132 } |
| 132 } | 133 } |
| 133 | 134 |
| 134 void BidirectionalStream::SendRequestHeaders() { | 135 void BidirectionalStream::SendRequestHeaders() { |
| 135 DCHECK(stream_impl_); | 136 DCHECK(stream_impl_); |
| 136 DCHECK(!request_headers_sent_); | 137 DCHECK(!request_headers_sent_); |
| 137 DCHECK(!send_request_headers_automatically_); | 138 DCHECK(!send_request_headers_automatically_); |
| 138 | 139 |
| 139 stream_impl_->SendRequestHeaders(); | 140 stream_impl_->SendRequestHeaders(); |
| 140 } | 141 } |
| 141 | 142 |
| 142 int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) { | 143 int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) { |
| 143 DCHECK(stream_impl_); | 144 DCHECK(stream_impl_); |
| 144 | 145 |
| 145 int rv = stream_impl_->ReadData(buf, buf_len); | 146 int rv = stream_impl_->ReadData(buf, buf_len); |
| 146 if (rv > 0) { | 147 if (rv > 0) { |
| 148 read_end_time_ = base::TimeTicks::Now(); |
| 147 net_log_.AddByteTransferEvent( | 149 net_log_.AddByteTransferEvent( |
| 148 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, rv, buf->data()); | 150 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, rv, buf->data()); |
| 149 } else if (rv == ERR_IO_PENDING) { | 151 } else if (rv == ERR_IO_PENDING) { |
| 150 read_buffer_ = buf; | 152 read_buffer_ = buf; |
| 151 // Bytes will be logged in OnDataRead(). | 153 // Bytes will be logged in OnDataRead(). |
| 152 } | 154 } |
| 153 if (net_log_.IsCapturing()) { | 155 if (net_log_.IsCapturing()) { |
| 154 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_READ_DATA, | 156 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_READ_DATA, |
| 155 NetLog::IntCallback("rv", rv)); | 157 NetLog::IntCallback("rv", rv)); |
| 156 } | 158 } |
| (...skipping 56 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 213 return stream_impl_->GetTotalSentBytes(); | 215 return stream_impl_->GetTotalSentBytes(); |
| 214 } | 216 } |
| 215 | 217 |
| 216 void BidirectionalStream::OnStreamReady(bool request_headers_sent) { | 218 void BidirectionalStream::OnStreamReady(bool request_headers_sent) { |
| 217 request_headers_sent_ = request_headers_sent; | 219 request_headers_sent_ = request_headers_sent; |
| 218 if (net_log_.IsCapturing()) { | 220 if (net_log_.IsCapturing()) { |
| 219 net_log_.AddEvent( | 221 net_log_.AddEvent( |
| 220 NetLog::TYPE_BIDIRECTIONAL_STREAM_READY, | 222 NetLog::TYPE_BIDIRECTIONAL_STREAM_READY, |
| 221 NetLog::BoolCallback("request_headers_sent", request_headers_sent)); | 223 NetLog::BoolCallback("request_headers_sent", request_headers_sent)); |
| 222 } | 224 } |
| 225 send_start_time_ = base::TimeTicks::Now(); |
| 226 send_end_time_ = send_start_time_; |
| 223 delegate_->OnStreamReady(request_headers_sent); | 227 delegate_->OnStreamReady(request_headers_sent); |
| 224 } | 228 } |
| 225 | 229 |
| 226 void BidirectionalStream::OnHeadersReceived( | 230 void BidirectionalStream::OnHeadersReceived( |
| 227 const SpdyHeaderBlock& response_headers) { | 231 const SpdyHeaderBlock& response_headers) { |
| 228 HttpResponseInfo response_info; | 232 HttpResponseInfo response_info; |
| 229 if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) { | 233 if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) { |
| 230 DLOG(WARNING) << "Invalid headers"; | 234 DLOG(WARNING) << "Invalid headers"; |
| 231 NotifyFailed(ERR_FAILED); | 235 NotifyFailed(ERR_FAILED); |
| 232 return; | 236 return; |
| 233 } | 237 } |
| 234 if (net_log_.IsCapturing()) { | 238 if (net_log_.IsCapturing()) { |
| 235 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, | 239 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, |
| 236 base::Bind(&NetLogHeadersCallback, &response_headers)); | 240 base::Bind(&NetLogHeadersCallback, &response_headers)); |
| 237 } | 241 } |
| 242 read_start_time_ = base::TimeTicks::Now(); |
| 243 read_end_time_ = read_start_time_; |
| 238 session_->http_stream_factory()->ProcessAlternativeServices( | 244 session_->http_stream_factory()->ProcessAlternativeServices( |
| 239 session_, response_info.headers.get(), | 245 session_, response_info.headers.get(), |
| 240 url::SchemeHostPort(request_info_->url)); | 246 url::SchemeHostPort(request_info_->url)); |
| 241 delegate_->OnHeadersReceived(response_headers); | 247 delegate_->OnHeadersReceived(response_headers); |
| 242 } | 248 } |
| 243 | 249 |
| 244 void BidirectionalStream::OnDataRead(int bytes_read) { | 250 void BidirectionalStream::OnDataRead(int bytes_read) { |
| 245 DCHECK(read_buffer_); | 251 DCHECK(read_buffer_); |
| 246 | 252 |
| 247 if (net_log_.IsCapturing()) { | 253 if (net_log_.IsCapturing()) { |
| 248 net_log_.AddByteTransferEvent( | 254 net_log_.AddByteTransferEvent( |
| 249 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, | 255 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, |
| 250 read_buffer_->data()); | 256 read_buffer_->data()); |
| 251 } | 257 } |
| 258 read_end_time_ = base::TimeTicks::Now(); |
| 252 read_buffer_ = nullptr; | 259 read_buffer_ = nullptr; |
| 253 delegate_->OnDataRead(bytes_read); | 260 delegate_->OnDataRead(bytes_read); |
| 254 } | 261 } |
| 255 | 262 |
| 256 void BidirectionalStream::OnDataSent() { | 263 void BidirectionalStream::OnDataSent() { |
| 257 DCHECK(!write_buffer_list_.empty()); | 264 DCHECK(!write_buffer_list_.empty()); |
| 258 DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size()); | 265 DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size()); |
| 259 | 266 |
| 260 if (net_log_.IsCapturing()) { | 267 if (net_log_.IsCapturing()) { |
| 261 if (write_buffer_list_.size() > 1) { | 268 if (write_buffer_list_.size() > 1) { |
| 262 net_log_.BeginEvent( | 269 net_log_.BeginEvent( |
| 263 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED, | 270 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED, |
| 264 NetLog::IntCallback("num_buffers_coalesced", | 271 NetLog::IntCallback("num_buffers_coalesced", |
| 265 write_buffer_list_.size())); | 272 write_buffer_list_.size())); |
| 266 } | 273 } |
| 267 for (size_t i = 0; i < write_buffer_list_.size(); ++i) { | 274 for (size_t i = 0; i < write_buffer_list_.size(); ++i) { |
| 268 net_log_.AddByteTransferEvent( | 275 net_log_.AddByteTransferEvent( |
| 269 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT, | 276 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT, |
| 270 write_buffer_len_list_[i], write_buffer_list_[i]->data()); | 277 write_buffer_len_list_[i], write_buffer_list_[i]->data()); |
| 271 } | 278 } |
| 272 if (write_buffer_list_.size() > 1) { | 279 if (write_buffer_list_.size() > 1) { |
| 273 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED); | 280 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED); |
| 274 } | 281 } |
| 275 } | 282 } |
| 283 send_end_time_ = base::TimeTicks::Now(); |
| 276 write_buffer_list_.clear(); | 284 write_buffer_list_.clear(); |
| 277 write_buffer_len_list_.clear(); | 285 write_buffer_len_list_.clear(); |
| 278 delegate_->OnDataSent(); | 286 delegate_->OnDataSent(); |
| 279 } | 287 } |
| 280 | 288 |
| 281 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) { | 289 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) { |
| 282 if (net_log_.IsCapturing()) { | 290 if (net_log_.IsCapturing()) { |
| 283 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, | 291 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, |
| 284 base::Bind(&NetLogHeadersCallback, &trailers)); | 292 base::Bind(&NetLogHeadersCallback, &trailers)); |
| 285 } | 293 } |
| 294 read_end_time_ = base::TimeTicks::Now(); |
| 286 delegate_->OnTrailersReceived(trailers); | 295 delegate_->OnTrailersReceived(trailers); |
| 287 } | 296 } |
| 288 | 297 |
| 289 void BidirectionalStream::OnFailed(int status) { | 298 void BidirectionalStream::OnFailed(int status) { |
| 290 if (net_log_.IsCapturing()) { | 299 if (net_log_.IsCapturing()) { |
| 291 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_FAILED, | 300 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_FAILED, |
| 292 NetLog::IntCallback("net_error", status)); | 301 NetLog::IntCallback("net_error", status)); |
| 293 } | 302 } |
| 294 NotifyFailed(status); | 303 NotifyFailed(status); |
| 295 } | 304 } |
| 296 | 305 |
| 297 void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config, | 306 void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config, |
| 298 const ProxyInfo& used_proxy_info, | 307 const ProxyInfo& used_proxy_info, |
| 299 HttpStream* stream) { | 308 HttpStream* stream) { |
| 300 NOTREACHED(); | 309 NOTREACHED(); |
| 301 } | 310 } |
| 302 | 311 |
| 303 void BidirectionalStream::OnBidirectionalStreamImplReady( | 312 void BidirectionalStream::OnBidirectionalStreamImplReady( |
| 304 const SSLConfig& used_ssl_config, | 313 const SSLConfig& used_ssl_config, |
| 305 const ProxyInfo& used_proxy_info, | 314 const ProxyInfo& used_proxy_info, |
| 306 BidirectionalStreamImpl* stream) { | 315 BidirectionalStreamImpl* stream) { |
| 307 DCHECK(!stream_impl_); | 316 DCHECK(!stream_impl_); |
| 308 | 317 |
| 318 start_time_ = base::TimeTicks::Now(); |
| 309 stream_request_.reset(); | 319 stream_request_.reset(); |
| 310 stream_impl_.reset(stream); | 320 stream_impl_.reset(stream); |
| 311 stream_impl_->Start(request_info_.get(), net_log_, | 321 stream_impl_->Start(request_info_.get(), net_log_, |
| 312 send_request_headers_automatically_, this, | 322 send_request_headers_automatically_, this, |
| 313 std::move(timer_)); | 323 std::move(timer_)); |
| 314 } | 324 } |
| 315 | 325 |
| 316 void BidirectionalStream::OnWebSocketHandshakeStreamReady( | 326 void BidirectionalStream::OnWebSocketHandshakeStreamReady( |
| 317 const SSLConfig& used_ssl_config, | 327 const SSLConfig& used_ssl_config, |
| 318 const ProxyInfo& used_proxy_info, | 328 const ProxyInfo& used_proxy_info, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 365 | 375 |
| 366 NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); | 376 NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); |
| 367 } | 377 } |
| 368 | 378 |
| 369 void BidirectionalStream::OnQuicBroken() {} | 379 void BidirectionalStream::OnQuicBroken() {} |
| 370 | 380 |
| 371 void BidirectionalStream::NotifyFailed(int error) { | 381 void BidirectionalStream::NotifyFailed(int error) { |
| 372 delegate_->OnFailed(error); | 382 delegate_->OnFailed(error); |
| 373 } | 383 } |
| 374 | 384 |
| 385 void BidirectionalStream::UpdateHistograms() { |
| 386 // If the request failed before response is started, treat the metrics as |
| 387 // bogus and skip logging. |
| 388 if (start_time_.is_null() || read_start_time_.is_null() || |
| 389 read_end_time_.is_null() || send_start_time_.is_null() || |
| 390 send_end_time_.is_null()) { |
| 391 return; |
| 392 } |
| 393 if (GetProtocol() == kProtoHTTP2) { |
| 394 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToReadStart", |
| 395 read_start_time_ - start_time_); |
| 396 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToReadEnd", |
| 397 read_end_time_ - start_time_); |
| 398 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToSendStart", |
| 399 send_start_time_ - start_time_); |
| 400 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToSendEnd", |
| 401 send_end_time_ - start_time_); |
| 402 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.HTTP2.ReceivedBytes", |
| 403 stream_impl_->GetTotalReceivedBytes()); |
| 404 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.HTTP2.SentBytes", |
| 405 stream_impl_->GetTotalSentBytes()); |
| 406 } else if (GetProtocol() == kProtoQUIC1SPDY3) { |
| 407 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToReadStart", |
| 408 read_start_time_ - start_time_); |
| 409 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToReadEnd", |
| 410 read_end_time_ - start_time_); |
| 411 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToSendStart", |
| 412 send_start_time_ - start_time_); |
| 413 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToSendEnd", |
| 414 send_end_time_ - start_time_); |
| 415 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.QUIC.ReceivedBytes", |
| 416 stream_impl_->GetTotalReceivedBytes()); |
| 417 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.QUIC.SentBytes", |
| 418 stream_impl_->GetTotalSentBytes()); |
| 419 } |
| 420 } |
| 421 |
| 375 } // namespace net | 422 } // namespace net |
| OLD | NEW |