Chromium Code Reviews| 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" |
| 16 #include "base/time/default_tick_clock.h" | |
| 17 #include "base/time/tick_clock.h" | |
| 15 #include "base/time/time.h" | 18 #include "base/time/time.h" |
| 16 #include "base/timer/timer.h" | 19 #include "base/timer/timer.h" |
| 17 #include "base/values.h" | 20 #include "base/values.h" |
| 18 #include "net/base/load_flags.h" | 21 #include "net/base/load_flags.h" |
| 19 #include "net/base/net_errors.h" | 22 #include "net/base/net_errors.h" |
| 20 #include "net/http/bidirectional_stream_request_info.h" | 23 #include "net/http/bidirectional_stream_request_info.h" |
| 21 #include "net/http/http_log_util.h" | 24 #include "net/http/http_log_util.h" |
| 22 #include "net/http/http_network_session.h" | 25 #include "net/http/http_network_session.h" |
| 23 #include "net/http/http_response_headers.h" | 26 #include "net/http/http_response_headers.h" |
| 24 #include "net/http/http_stream.h" | 27 #include "net/http/http_stream.h" |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 79 Delegate* delegate, | 82 Delegate* delegate, |
| 80 std::unique_ptr<base::Timer> timer) | 83 std::unique_ptr<base::Timer> timer) |
| 81 : request_info_(std::move(request_info)), | 84 : request_info_(std::move(request_info)), |
| 82 net_log_(BoundNetLog::Make(session->net_log(), | 85 net_log_(BoundNetLog::Make(session->net_log(), |
| 83 NetLog::SOURCE_BIDIRECTIONAL_STREAM)), | 86 NetLog::SOURCE_BIDIRECTIONAL_STREAM)), |
| 84 session_(session), | 87 session_(session), |
| 85 send_request_headers_automatically_(send_request_headers_automatically), | 88 send_request_headers_automatically_(send_request_headers_automatically), |
| 86 request_headers_sent_(false), | 89 request_headers_sent_(false), |
| 87 delegate_(delegate), | 90 delegate_(delegate), |
| 88 timer_(std::move(timer)), | 91 timer_(std::move(timer)), |
| 92 tick_clock_(new base::DefaultTickClock()), | |
| 89 weak_factory_(this) { | 93 weak_factory_(this) { |
| 90 DCHECK(delegate_); | 94 DCHECK(delegate_); |
| 91 DCHECK(request_info_); | 95 DCHECK(request_info_); |
| 92 | 96 |
| 93 if (net_log_.IsCapturing()) { | 97 if (net_log_.IsCapturing()) { |
| 94 net_log_.BeginEvent( | 98 net_log_.BeginEvent( |
| 95 NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE, | 99 NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE, |
| 96 base::Bind(&NetLogCallback, &request_info_->url, &request_info_->method, | 100 base::Bind(&NetLogCallback, &request_info_->url, &request_info_->method, |
| 97 base::Unretained(&request_info_->extra_headers))); | 101 base::Unretained(&request_info_->extra_headers))); |
| 98 } | 102 } |
| (...skipping 20 matching lines...) Expand all Loading... | |
| 119 http_request_info, request_info_->priority, server_ssl_config, | 123 http_request_info, request_info_->priority, server_ssl_config, |
| 120 server_ssl_config, this, net_log_)); | 124 server_ssl_config, this, net_log_)); |
| 121 // Check that this call cannot fail to set a non-NULL |stream_request_|. | 125 // Check that this call cannot fail to set a non-NULL |stream_request_|. |
| 122 DCHECK(stream_request_); | 126 DCHECK(stream_request_); |
| 123 // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady | 127 // Check that HttpStreamFactory does not invoke OnBidirectionalStreamImplReady |
| 124 // synchronously. | 128 // synchronously. |
| 125 DCHECK(!stream_impl_); | 129 DCHECK(!stream_impl_); |
| 126 } | 130 } |
| 127 | 131 |
| 128 BidirectionalStream::~BidirectionalStream() { | 132 BidirectionalStream::~BidirectionalStream() { |
| 133 UpdateHistograms(); | |
| 129 Cancel(); | 134 Cancel(); |
| 130 if (net_log_.IsCapturing()) { | 135 if (net_log_.IsCapturing()) { |
| 131 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE); | 136 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_ALIVE); |
| 132 } | 137 } |
| 133 } | 138 } |
| 134 | 139 |
| 135 void BidirectionalStream::SendRequestHeaders() { | 140 void BidirectionalStream::SendRequestHeaders() { |
| 136 DCHECK(stream_impl_); | 141 DCHECK(stream_impl_); |
| 137 DCHECK(!request_headers_sent_); | 142 DCHECK(!request_headers_sent_); |
| 138 DCHECK(!send_request_headers_automatically_); | 143 DCHECK(!send_request_headers_automatically_); |
| (...skipping 98 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 237 HttpResponseInfo response_info; | 242 HttpResponseInfo response_info; |
| 238 if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) { | 243 if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) { |
| 239 DLOG(WARNING) << "Invalid headers"; | 244 DLOG(WARNING) << "Invalid headers"; |
| 240 NotifyFailed(ERR_FAILED); | 245 NotifyFailed(ERR_FAILED); |
| 241 return; | 246 return; |
| 242 } | 247 } |
| 243 if (net_log_.IsCapturing()) { | 248 if (net_log_.IsCapturing()) { |
| 244 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, | 249 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, |
| 245 base::Bind(&NetLogHeadersCallback, &response_headers)); | 250 base::Bind(&NetLogHeadersCallback, &response_headers)); |
| 246 } | 251 } |
| 252 recv_first_byte_time_ = tick_clock_->NowTicks(); | |
| 253 recv_last_byte_time_ = recv_first_byte_time_; | |
| 247 session_->http_stream_factory()->ProcessAlternativeServices( | 254 session_->http_stream_factory()->ProcessAlternativeServices( |
| 248 session_, response_info.headers.get(), | 255 session_, response_info.headers.get(), |
| 249 url::SchemeHostPort(request_info_->url)); | 256 url::SchemeHostPort(request_info_->url)); |
| 250 delegate_->OnHeadersReceived(response_headers); | 257 delegate_->OnHeadersReceived(response_headers); |
| 251 } | 258 } |
| 252 | 259 |
| 253 void BidirectionalStream::OnDataRead(int bytes_read) { | 260 void BidirectionalStream::OnDataRead(int bytes_read) { |
| 254 DCHECK(read_buffer_); | 261 DCHECK(read_buffer_); |
| 255 | 262 |
| 256 if (net_log_.IsCapturing()) { | 263 if (net_log_.IsCapturing()) { |
| 257 net_log_.AddByteTransferEvent( | 264 net_log_.AddByteTransferEvent( |
| 258 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, | 265 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, |
| 259 read_buffer_->data()); | 266 read_buffer_->data()); |
| 260 } | 267 } |
| 268 recv_last_byte_time_ = tick_clock_->NowTicks(); | |
| 261 read_buffer_ = nullptr; | 269 read_buffer_ = nullptr; |
| 262 delegate_->OnDataRead(bytes_read); | 270 delegate_->OnDataRead(bytes_read); |
| 263 } | 271 } |
| 264 | 272 |
| 265 void BidirectionalStream::OnDataSent() { | 273 void BidirectionalStream::OnDataSent() { |
| 266 DCHECK(!write_buffer_list_.empty()); | 274 DCHECK(!write_buffer_list_.empty()); |
| 267 DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size()); | 275 DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size()); |
| 268 | 276 |
| 269 if (net_log_.IsCapturing()) { | 277 if (net_log_.IsCapturing()) { |
| 270 if (write_buffer_list_.size() > 1) { | 278 if (write_buffer_list_.size() > 1) { |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 285 write_buffer_list_.clear(); | 293 write_buffer_list_.clear(); |
| 286 write_buffer_len_list_.clear(); | 294 write_buffer_len_list_.clear(); |
| 287 delegate_->OnDataSent(); | 295 delegate_->OnDataSent(); |
| 288 } | 296 } |
| 289 | 297 |
| 290 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) { | 298 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) { |
| 291 if (net_log_.IsCapturing()) { | 299 if (net_log_.IsCapturing()) { |
| 292 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, | 300 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, |
| 293 base::Bind(&NetLogHeadersCallback, &trailers)); | 301 base::Bind(&NetLogHeadersCallback, &trailers)); |
| 294 } | 302 } |
| 303 recv_last_byte_time_ = tick_clock_->NowTicks(); | |
| 295 delegate_->OnTrailersReceived(trailers); | 304 delegate_->OnTrailersReceived(trailers); |
| 296 } | 305 } |
| 297 | 306 |
| 298 void BidirectionalStream::OnFailed(int status) { | 307 void BidirectionalStream::OnFailed(int status) { |
| 299 if (net_log_.IsCapturing()) { | 308 if (net_log_.IsCapturing()) { |
| 300 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_FAILED, | 309 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_FAILED, |
| 301 NetLog::IntCallback("net_error", status)); | 310 NetLog::IntCallback("net_error", status)); |
| 302 } | 311 } |
| 303 NotifyFailed(status); | 312 NotifyFailed(status); |
| 304 } | 313 } |
| 305 | 314 |
| 306 void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config, | 315 void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config, |
| 307 const ProxyInfo& used_proxy_info, | 316 const ProxyInfo& used_proxy_info, |
| 308 HttpStream* stream) { | 317 HttpStream* stream) { |
| 309 NOTREACHED(); | 318 NOTREACHED(); |
| 310 } | 319 } |
| 311 | 320 |
| 312 void BidirectionalStream::OnBidirectionalStreamImplReady( | 321 void BidirectionalStream::OnBidirectionalStreamImplReady( |
| 313 const SSLConfig& used_ssl_config, | 322 const SSLConfig& used_ssl_config, |
| 314 const ProxyInfo& used_proxy_info, | 323 const ProxyInfo& used_proxy_info, |
| 315 BidirectionalStreamImpl* stream) { | 324 BidirectionalStreamImpl* stream) { |
| 316 DCHECK(!stream_impl_); | 325 DCHECK(!stream_impl_); |
| 317 | 326 |
| 327 start_time_ = tick_clock_->NowTicks(); | |
| 318 stream_request_.reset(); | 328 stream_request_.reset(); |
| 319 stream_impl_.reset(stream); | 329 stream_impl_.reset(stream); |
| 320 stream_impl_->Start(request_info_.get(), net_log_, | 330 stream_impl_->Start(request_info_.get(), net_log_, |
| 321 send_request_headers_automatically_, this, | 331 send_request_headers_automatically_, this, |
| 322 std::move(timer_)); | 332 std::move(timer_)); |
| 323 } | 333 } |
| 324 | 334 |
| 325 void BidirectionalStream::OnWebSocketHandshakeStreamReady( | 335 void BidirectionalStream::OnWebSocketHandshakeStreamReady( |
| 326 const SSLConfig& used_ssl_config, | 336 const SSLConfig& used_ssl_config, |
| 327 const ProxyInfo& used_proxy_info, | 337 const ProxyInfo& used_proxy_info, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 | 384 |
| 375 NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); | 385 NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); |
| 376 } | 386 } |
| 377 | 387 |
| 378 void BidirectionalStream::OnQuicBroken() {} | 388 void BidirectionalStream::OnQuicBroken() {} |
| 379 | 389 |
| 380 void BidirectionalStream::NotifyFailed(int error) { | 390 void BidirectionalStream::NotifyFailed(int error) { |
| 381 delegate_->OnFailed(error); | 391 delegate_->OnFailed(error); |
| 382 } | 392 } |
| 383 | 393 |
| 394 void BidirectionalStream::UpdateHistograms() { | |
| 395 // If the request failed before response is started, treat the metrics as | |
| 396 // bogus and skip logging. | |
| 397 if (start_time_.is_null() || recv_first_byte_time_.is_null() || | |
| 398 recv_last_byte_time_.is_null()) { | |
| 399 return; | |
| 400 } | |
| 401 if (GetProtocol() == kProtoHTTP2) { | |
| 402 UMA_HISTOGRAM_TIMES("BidirectionalStream.HTTP2.TimeToResponseStart", | |
|
Ilya Sherman
2016/08/08 22:26:37
Would it be appropriate to prefix these histogram
xunjieli
2016/08/09 20:31:28
Done.
| |
| 403 recv_first_byte_time_ - start_time_); | |
| 404 UMA_HISTOGRAM_TIMES("BidirectionalStream.HTTP2.TimeToResponseEnd", | |
| 405 recv_last_byte_time_ - start_time_); | |
| 406 UMA_HISTOGRAM_COUNTS("BidirectionalStream.HTTP2.ReceivedBytes", | |
|
Ilya Sherman
2016/08/08 22:26:37
Are the boundaries set by UMA_HISTOGRAM_COUNTS rea
xunjieli
2016/08/09 20:31:28
Yes, elsewhere in net/, the UMA for bytes is logge
| |
| 407 stream_impl_->GetTotalReceivedBytes()); | |
| 408 UMA_HISTOGRAM_COUNTS("BidirectionalStream.HTTP2.SentBytes", | |
| 409 stream_impl_->GetTotalSentBytes()); | |
| 410 } else if (GetProtocol() == kProtoQUIC1SPDY3) { | |
| 411 UMA_HISTOGRAM_TIMES("BidirectionalStream.QUIC.TimeToResponseStart", | |
| 412 recv_first_byte_time_ - start_time_); | |
| 413 UMA_HISTOGRAM_TIMES("BidirectionalStream.QUIC.TimeToResponseEnd", | |
| 414 recv_last_byte_time_ - start_time_); | |
| 415 UMA_HISTOGRAM_COUNTS("BidirectionalStream.QUIC.ReceivedBytes", | |
| 416 stream_impl_->GetTotalReceivedBytes()); | |
| 417 UMA_HISTOGRAM_COUNTS("BidirectionalStream.QUIC.SentBytes", | |
| 418 stream_impl_->GetTotalSentBytes()); | |
| 419 } | |
| 420 } | |
| 421 | |
| 384 } // namespace net | 422 } // namespace net |
| OLD | NEW |