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_); |
| 139 | 144 |
| 140 stream_impl_->SendRequestHeaders(); | 145 stream_impl_->SendRequestHeaders(); |
| 141 } | 146 } |
| 142 | 147 |
| 143 int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) { | 148 int BidirectionalStream::ReadData(IOBuffer* buf, int buf_len) { |
| 144 DCHECK(stream_impl_); | 149 DCHECK(stream_impl_); |
| 145 | 150 |
| 146 int rv = stream_impl_->ReadData(buf, buf_len); | 151 int rv = stream_impl_->ReadData(buf, buf_len); |
| 147 if (rv > 0) { | 152 if (rv > 0) { |
| 153 read_end_time_ = tick_clock_->NowTicks(); | |
|
mef
2016/08/10 01:05:20
Can we use TimeTicks::Now() here and elsewhere? Th
xunjieli
2016/08/11 12:50:40
Done.
| |
| 148 net_log_.AddByteTransferEvent( | 154 net_log_.AddByteTransferEvent( |
| 149 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, rv, buf->data()); | 155 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, rv, buf->data()); |
| 150 } else if (rv == ERR_IO_PENDING) { | 156 } else if (rv == ERR_IO_PENDING) { |
| 151 read_buffer_ = buf; | 157 read_buffer_ = buf; |
| 152 // Bytes will be logged in OnDataRead(). | 158 // Bytes will be logged in OnDataRead(). |
| 153 } | 159 } |
| 154 if (net_log_.IsCapturing()) { | 160 if (net_log_.IsCapturing()) { |
| 155 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_READ_DATA, | 161 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_READ_DATA, |
| 156 NetLog::IntCallback("rv", rv)); | 162 NetLog::IntCallback("rv", rv)); |
| 157 } | 163 } |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 222 return stream_impl_->GetTotalSentBytes(); | 228 return stream_impl_->GetTotalSentBytes(); |
| 223 } | 229 } |
| 224 | 230 |
| 225 void BidirectionalStream::OnStreamReady(bool request_headers_sent) { | 231 void BidirectionalStream::OnStreamReady(bool request_headers_sent) { |
| 226 request_headers_sent_ = request_headers_sent; | 232 request_headers_sent_ = request_headers_sent; |
| 227 if (net_log_.IsCapturing()) { | 233 if (net_log_.IsCapturing()) { |
| 228 net_log_.AddEvent( | 234 net_log_.AddEvent( |
| 229 NetLog::TYPE_BIDIRECTIONAL_STREAM_READY, | 235 NetLog::TYPE_BIDIRECTIONAL_STREAM_READY, |
| 230 NetLog::BoolCallback("request_headers_sent", request_headers_sent)); | 236 NetLog::BoolCallback("request_headers_sent", request_headers_sent)); |
| 231 } | 237 } |
| 238 send_start_time_ = tick_clock_->NowTicks(); | |
| 239 send_end_time_ = send_start_time_; | |
| 232 delegate_->OnStreamReady(request_headers_sent); | 240 delegate_->OnStreamReady(request_headers_sent); |
| 233 } | 241 } |
| 234 | 242 |
| 235 void BidirectionalStream::OnHeadersReceived( | 243 void BidirectionalStream::OnHeadersReceived( |
| 236 const SpdyHeaderBlock& response_headers) { | 244 const SpdyHeaderBlock& response_headers) { |
| 237 HttpResponseInfo response_info; | 245 HttpResponseInfo response_info; |
| 238 if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) { | 246 if (!SpdyHeadersToHttpResponse(response_headers, &response_info)) { |
| 239 DLOG(WARNING) << "Invalid headers"; | 247 DLOG(WARNING) << "Invalid headers"; |
| 240 NotifyFailed(ERR_FAILED); | 248 NotifyFailed(ERR_FAILED); |
| 241 return; | 249 return; |
| 242 } | 250 } |
| 243 if (net_log_.IsCapturing()) { | 251 if (net_log_.IsCapturing()) { |
| 244 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, | 252 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_HEADERS, |
| 245 base::Bind(&NetLogHeadersCallback, &response_headers)); | 253 base::Bind(&NetLogHeadersCallback, &response_headers)); |
| 246 } | 254 } |
| 255 read_start_time_ = tick_clock_->NowTicks(); | |
| 256 read_end_time_ = read_start_time_; | |
| 247 session_->http_stream_factory()->ProcessAlternativeServices( | 257 session_->http_stream_factory()->ProcessAlternativeServices( |
| 248 session_, response_info.headers.get(), | 258 session_, response_info.headers.get(), |
| 249 url::SchemeHostPort(request_info_->url)); | 259 url::SchemeHostPort(request_info_->url)); |
| 250 delegate_->OnHeadersReceived(response_headers); | 260 delegate_->OnHeadersReceived(response_headers); |
| 251 } | 261 } |
| 252 | 262 |
| 253 void BidirectionalStream::OnDataRead(int bytes_read) { | 263 void BidirectionalStream::OnDataRead(int bytes_read) { |
| 254 DCHECK(read_buffer_); | 264 DCHECK(read_buffer_); |
| 255 | 265 |
| 256 if (net_log_.IsCapturing()) { | 266 if (net_log_.IsCapturing()) { |
| 257 net_log_.AddByteTransferEvent( | 267 net_log_.AddByteTransferEvent( |
| 258 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, | 268 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_RECEIVED, bytes_read, |
| 259 read_buffer_->data()); | 269 read_buffer_->data()); |
| 260 } | 270 } |
| 271 read_end_time_ = tick_clock_->NowTicks(); | |
| 261 read_buffer_ = nullptr; | 272 read_buffer_ = nullptr; |
| 262 delegate_->OnDataRead(bytes_read); | 273 delegate_->OnDataRead(bytes_read); |
| 263 } | 274 } |
| 264 | 275 |
| 265 void BidirectionalStream::OnDataSent() { | 276 void BidirectionalStream::OnDataSent() { |
| 266 DCHECK(!write_buffer_list_.empty()); | 277 DCHECK(!write_buffer_list_.empty()); |
| 267 DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size()); | 278 DCHECK_EQ(write_buffer_list_.size(), write_buffer_len_list_.size()); |
| 268 | 279 |
| 269 if (net_log_.IsCapturing()) { | 280 if (net_log_.IsCapturing()) { |
| 270 if (write_buffer_list_.size() > 1) { | 281 if (write_buffer_list_.size() > 1) { |
| 271 net_log_.BeginEvent( | 282 net_log_.BeginEvent( |
| 272 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED, | 283 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED, |
| 273 NetLog::IntCallback("num_buffers_coalesced", | 284 NetLog::IntCallback("num_buffers_coalesced", |
| 274 write_buffer_list_.size())); | 285 write_buffer_list_.size())); |
| 275 } | 286 } |
| 276 for (size_t i = 0; i < write_buffer_list_.size(); ++i) { | 287 for (size_t i = 0; i < write_buffer_list_.size(); ++i) { |
| 277 net_log_.AddByteTransferEvent( | 288 net_log_.AddByteTransferEvent( |
| 278 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT, | 289 NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT, |
| 279 write_buffer_len_list_[i], write_buffer_list_[i]->data()); | 290 write_buffer_len_list_[i], write_buffer_list_[i]->data()); |
| 280 } | 291 } |
| 281 if (write_buffer_list_.size() > 1) { | 292 if (write_buffer_list_.size() > 1) { |
| 282 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED); | 293 net_log_.EndEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_BYTES_SENT_COALESCED); |
| 283 } | 294 } |
| 284 } | 295 } |
| 296 send_end_time_ = tick_clock_->NowTicks(); | |
| 285 write_buffer_list_.clear(); | 297 write_buffer_list_.clear(); |
| 286 write_buffer_len_list_.clear(); | 298 write_buffer_len_list_.clear(); |
| 287 delegate_->OnDataSent(); | 299 delegate_->OnDataSent(); |
| 288 } | 300 } |
| 289 | 301 |
| 290 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) { | 302 void BidirectionalStream::OnTrailersReceived(const SpdyHeaderBlock& trailers) { |
| 291 if (net_log_.IsCapturing()) { | 303 if (net_log_.IsCapturing()) { |
| 292 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, | 304 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_RECV_TRAILERS, |
| 293 base::Bind(&NetLogHeadersCallback, &trailers)); | 305 base::Bind(&NetLogHeadersCallback, &trailers)); |
| 294 } | 306 } |
| 307 read_end_time_ = tick_clock_->NowTicks(); | |
| 295 delegate_->OnTrailersReceived(trailers); | 308 delegate_->OnTrailersReceived(trailers); |
| 296 } | 309 } |
| 297 | 310 |
| 298 void BidirectionalStream::OnFailed(int status) { | 311 void BidirectionalStream::OnFailed(int status) { |
| 299 if (net_log_.IsCapturing()) { | 312 if (net_log_.IsCapturing()) { |
| 300 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_FAILED, | 313 net_log_.AddEvent(NetLog::TYPE_BIDIRECTIONAL_STREAM_FAILED, |
| 301 NetLog::IntCallback("net_error", status)); | 314 NetLog::IntCallback("net_error", status)); |
| 302 } | 315 } |
| 303 NotifyFailed(status); | 316 NotifyFailed(status); |
| 304 } | 317 } |
| 305 | 318 |
| 306 void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config, | 319 void BidirectionalStream::OnStreamReady(const SSLConfig& used_ssl_config, |
| 307 const ProxyInfo& used_proxy_info, | 320 const ProxyInfo& used_proxy_info, |
| 308 HttpStream* stream) { | 321 HttpStream* stream) { |
| 309 NOTREACHED(); | 322 NOTREACHED(); |
| 310 } | 323 } |
| 311 | 324 |
| 312 void BidirectionalStream::OnBidirectionalStreamImplReady( | 325 void BidirectionalStream::OnBidirectionalStreamImplReady( |
| 313 const SSLConfig& used_ssl_config, | 326 const SSLConfig& used_ssl_config, |
| 314 const ProxyInfo& used_proxy_info, | 327 const ProxyInfo& used_proxy_info, |
| 315 BidirectionalStreamImpl* stream) { | 328 BidirectionalStreamImpl* stream) { |
| 316 DCHECK(!stream_impl_); | 329 DCHECK(!stream_impl_); |
| 317 | 330 |
| 331 start_time_ = tick_clock_->NowTicks(); | |
| 318 stream_request_.reset(); | 332 stream_request_.reset(); |
| 319 stream_impl_.reset(stream); | 333 stream_impl_.reset(stream); |
| 320 stream_impl_->Start(request_info_.get(), net_log_, | 334 stream_impl_->Start(request_info_.get(), net_log_, |
| 321 send_request_headers_automatically_, this, | 335 send_request_headers_automatically_, this, |
| 322 std::move(timer_)); | 336 std::move(timer_)); |
| 323 } | 337 } |
| 324 | 338 |
| 325 void BidirectionalStream::OnWebSocketHandshakeStreamReady( | 339 void BidirectionalStream::OnWebSocketHandshakeStreamReady( |
| 326 const SSLConfig& used_ssl_config, | 340 const SSLConfig& used_ssl_config, |
| 327 const ProxyInfo& used_proxy_info, | 341 const ProxyInfo& used_proxy_info, |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 374 | 388 |
| 375 NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); | 389 NotifyFailed(ERR_HTTPS_PROXY_TUNNEL_RESPONSE); |
| 376 } | 390 } |
| 377 | 391 |
| 378 void BidirectionalStream::OnQuicBroken() {} | 392 void BidirectionalStream::OnQuicBroken() {} |
| 379 | 393 |
| 380 void BidirectionalStream::NotifyFailed(int error) { | 394 void BidirectionalStream::NotifyFailed(int error) { |
| 381 delegate_->OnFailed(error); | 395 delegate_->OnFailed(error); |
| 382 } | 396 } |
| 383 | 397 |
| 398 void BidirectionalStream::UpdateHistograms() { | |
| 399 // If the request failed before response is started, treat the metrics as | |
| 400 // bogus and skip logging. | |
| 401 if (start_time_.is_null() || read_start_time_.is_null() || | |
| 402 read_end_time_.is_null() || send_start_time_.is_null() || | |
| 403 send_end_time_.is_null()) { | |
| 404 return; | |
| 405 } | |
| 406 if (GetProtocol() == kProtoHTTP2) { | |
| 407 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToReadStart", | |
|
mef
2016/08/10 01:05:20
Should these names match those in histograms.xml?
xunjieli
2016/08/11 12:50:40
I don't understand. They do match right? I added t
mef
2016/08/11 15:42:19
I would've thought that suffix goes at the end of
Ilya Sherman
2016/08/11 18:48:46
ordering=prefix should indeed put the "suffix" in
xunjieli
2016/08/11 19:37:09
I talked to csharrison@ who added a similar histog
| |
| 408 read_start_time_ - start_time_); | |
| 409 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToReadEnd", | |
| 410 read_end_time_ - start_time_); | |
| 411 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToSendStart", | |
| 412 send_start_time_ - start_time_); | |
| 413 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.HTTP2.TimeToSendEnd", | |
| 414 send_end_time_ - start_time_); | |
| 415 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.HTTP2.ReceivedBytes", | |
| 416 stream_impl_->GetTotalReceivedBytes()); | |
| 417 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.HTTP2.SentBytes", | |
| 418 stream_impl_->GetTotalSentBytes()); | |
| 419 } else if (GetProtocol() == kProtoQUIC1SPDY3) { | |
| 420 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToReadStart", | |
| 421 read_start_time_ - start_time_); | |
| 422 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToReadEnd", | |
| 423 read_end_time_ - start_time_); | |
| 424 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToSendStart", | |
| 425 send_start_time_ - start_time_); | |
| 426 UMA_HISTOGRAM_TIMES("Net.BidirectionalStream.QUIC.TimeToSendEnd", | |
| 427 send_end_time_ - start_time_); | |
| 428 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.QUIC.ReceivedBytes", | |
| 429 stream_impl_->GetTotalReceivedBytes()); | |
| 430 UMA_HISTOGRAM_COUNTS("Net.BidirectionalStream.QUIC.SentBytes", | |
| 431 stream_impl_->GetTotalSentBytes()); | |
| 432 } | |
| 433 } | |
| 434 | |
| 384 } // namespace net | 435 } // namespace net |
| OLD | NEW |