Moves the connected callback invocation to before stream initialization
As suggested in crrev.com/c/3545253, moving the `connected_callback_`
invocation in HttpNetworkTransaction can happen *before* DoInitStream()
is called, enabling the URLLoader::OnConnected() behavior to execute
without having to wait for stream initialization.
This CL moves the `connected_callback_` invocation to
DoCreateStreamComplete(). In order to do this, the HttpRequestInfo
object needs to be available to get the ACCEPT_CH frame payload (if
any), and currently it was only available when
HttpStream::InitializeStream() is called. To solve this problem, we
introduce a new method to the HttpStream interface: RegisterRequest.
This separates request registration from stream initialization so we can
move the `connected_callback_` invocation to before DoInitStream().
In addition to a (perhaps slight) performance improvement, the
advantages of this are:
- If the HTTP/2 or HTTP/3 session has hit its max stream limit, you no
longer wait on a slot to be available (only to not use it!) first.
- If there's a matching HTTP/2 push stream, you don't consume and discard
it.
- If 0-RTT over TCP is enabled (not launched) and this is a POST request,
you no longer wait for handshake confirmation and can resolve ACCEPT_CH
a hair sooner.
Bug: 1313781
Change-Id: I30ccf9473ce0798a409364b2ddad5e8fee2cfa74
Fixed: 1313781
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/3573185
Reviewed-by: Titouan Rigoudy <[email protected]>
Reviewed-by: Matt Menke <[email protected]>
Commit-Queue: Ali Beyad <[email protected]>
Cr-Commit-Position: refs/heads/main@{#990556}
diff --git a/net/http/http_network_transaction.cc b/net/http/http_network_transaction.cc
index 72fafbd..d1494b8 100644
--- a/net/http/http_network_transaction.cc
+++ b/net/http/http_network_transaction.cc
@@ -378,7 +378,7 @@
// Renewed streams shouldn't carry over sent or received bytes.
DCHECK_EQ(0, new_stream->GetTotalReceivedBytes());
DCHECK_EQ(0, new_stream->GetTotalSentBytes());
- next_state_ = STATE_INIT_STREAM;
+ next_state_ = STATE_CONNECTED_CALLBACK;
}
stream_.reset(new_stream);
}
@@ -738,6 +738,9 @@
case STATE_INIT_STREAM_COMPLETE:
rv = DoInitStreamComplete(rv);
break;
+ case STATE_CONNECTED_CALLBACK:
+ rv = DoConnectedCallback();
+ break;
case STATE_CONNECTED_CALLBACK_COMPLETE:
rv = DoConnectedCallbackComplete(rv);
break;
@@ -857,7 +860,7 @@
int HttpNetworkTransaction::DoCreateStreamComplete(int result) {
CopyConnectionAttemptsFromStreamRequest();
if (result == OK) {
- next_state_ = STATE_INIT_STREAM;
+ next_state_ = STATE_CONNECTED_CALLBACK;
DCHECK(stream_.get());
} else if (result == ERR_HTTP_1_1_REQUIRED ||
result == ERR_PROXY_HTTP_1_1_REQUIRED) {
@@ -877,10 +880,8 @@
DCHECK(stream_.get());
next_state_ = STATE_INIT_STREAM_COMPLETE;
- stream_->GetRemoteEndpoint(&remote_endpoint_);
-
- return stream_->InitializeStream(request_, can_send_early_data_, priority_,
- net_log_, io_callback_);
+ return stream_->InitializeStream(can_send_early_data_, priority_, net_log_,
+ io_callback_);
}
int HttpNetworkTransaction::DoInitStreamComplete(int result) {
@@ -898,22 +899,33 @@
return result;
}
+ next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
+ return result;
+}
+
+int HttpNetworkTransaction::DoConnectedCallback() {
+ // Register the HttpRequestInfo object on the stream here so that it's
+ // available when invoking the `connected_callback_`, as
+ // HttpStream::GetAcceptChViaAlps() needs the HttpRequestInfo to retrieve
+ // the ACCEPT_CH frame payload.
+ stream_->RegisterRequest(request_);
+ stream_->GetRemoteEndpoint(&remote_endpoint_);
next_state_ = STATE_CONNECTED_CALLBACK_COMPLETE;
- // Fire off notification that we have successfully connected.
- if (!connected_callback_.is_null()) {
- TransportType type = TransportType::kDirect;
- if (!proxy_info_.is_direct()) {
- type = TransportType::kProxied;
- }
- result = connected_callback_.Run(
- TransportInfo(type, remote_endpoint_,
- std::string(stream_->GetAcceptChViaAlps())),
- base::BindOnce(&HttpNetworkTransaction::ResumeAfterConnected,
- base::Unretained(this)));
+ if (connected_callback_.is_null()) {
+ return OK;
}
- return result;
+ // Fire off notification that we have successfully connected.
+ TransportType type = TransportType::kDirect;
+ if (!proxy_info_.is_direct()) {
+ type = TransportType::kProxied;
+ }
+ return connected_callback_.Run(
+ TransportInfo(type, remote_endpoint_,
+ std::string{stream_->GetAcceptChViaAlps()}),
+ base::BindOnce(&HttpNetworkTransaction::ResumeAfterConnected,
+ base::Unretained(this)));
}
int HttpNetworkTransaction::DoConnectedCallbackComplete(int result) {
@@ -926,7 +938,7 @@
return result;
}
- next_state_ = STATE_GENERATE_PROXY_AUTH_TOKEN;
+ next_state_ = STATE_INIT_STREAM;
return OK;
}