net/quic: Add support for HTTP/3 CONNECT Fast Open
SpdyProxyClientSocket uses read_callback_ for both Connect() and Read(), and its OnIOComplete() calls read_callback_, thus its fast connect code checks read_callback_. The code was ported to QuicProxyClientSocket without much change. But QuicProxyClientSocket uses a separate connect_callback_ apart from read_callback_, and its OnIOComplete() calls connect_callback_, thus when headers are received after Connect() it doesn't need to check read_callback_ and should always avoid calling connect_callback_.master
parent
41179267cf
commit
225893da02
|
|
@ -874,6 +874,11 @@ int QuicChromiumClientStream::DeliverInitialHeaders(
|
|||
return ERR_INVALID_RESPONSE;
|
||||
}
|
||||
|
||||
// During proxy Fast Open, DeliverInitialHeaders() queued from
|
||||
// OnInitialHeadersComplete() can be delayed after OnBodyAvailable(),
|
||||
// which then does nothing and stalls ReadBody(). Resumes it here.
|
||||
OnBodyAvailable();
|
||||
|
||||
net_log_.AddEvent(
|
||||
NetLogEventType::QUIC_CHROMIUM_CLIENT_STREAM_READ_RESPONSE_HEADERS,
|
||||
[&](NetLogCaptureMode capture_mode) {
|
||||
|
|
|
|||
|
|
@ -270,6 +270,13 @@ void QuicProxyClientSocket::OnIOComplete(int result) {
|
|||
DCHECK_NE(STATE_DISCONNECTED, next_state_);
|
||||
int rv = DoLoop(result);
|
||||
if (rv != ERR_IO_PENDING) {
|
||||
if (use_fastopen_ && read_headers_pending_ == false) {
|
||||
if (rv != OK)
|
||||
next_state_ = STATE_DISCONNECTED;
|
||||
if (read_callback_ && rv != OK)
|
||||
std::move(read_callback_).Run(rv);
|
||||
return;
|
||||
}
|
||||
// Connect() finished (successfully or unsuccessfully).
|
||||
DCHECK(!connect_callback_.is_null());
|
||||
std::move(connect_callback_).Run(rv);
|
||||
|
|
@ -387,6 +394,11 @@ int QuicProxyClientSocket::DoCalculateHeadersComplete(int result) {
|
|||
return result;
|
||||
}
|
||||
next_state_ = STATE_SEND_REQUEST;
|
||||
if (proxy_delegate_headers_.HasHeader("fastopen")) {
|
||||
proxy_delegate_headers_.RemoveHeader("fastopen");
|
||||
// TODO(klzgrad): look into why Fast Open does not work.
|
||||
use_fastopen_ = true;
|
||||
}
|
||||
request_.extra_headers.MergeFrom(proxy_delegate_headers_);
|
||||
return result;
|
||||
}
|
||||
|
|
@ -431,6 +443,11 @@ int QuicProxyClientSocket::DoReadReply() {
|
|||
&response_header_block_,
|
||||
base::BindOnce(&QuicProxyClientSocket::OnReadResponseHeadersComplete,
|
||||
weak_factory_.GetWeakPtr()));
|
||||
if (use_fastopen_ && rv == ERR_IO_PENDING) {
|
||||
read_headers_pending_ = true;
|
||||
next_state_ = STATE_CONNECT_COMPLETE;
|
||||
return OK;
|
||||
}
|
||||
if (rv == ERR_IO_PENDING)
|
||||
return ERR_IO_PENDING;
|
||||
if (rv < 0)
|
||||
|
|
@ -499,6 +516,14 @@ int QuicProxyClientSocket::DoProcessResponseCode() {
|
|||
|
||||
void QuicProxyClientSocket::OnReadResponseHeadersComplete(int result) {
|
||||
// Convert the now-populated quiche::HttpHeaderBlock to HttpResponseInfo
|
||||
if (use_fastopen_ && read_headers_pending_) {
|
||||
read_headers_pending_ = false;
|
||||
if (next_state_ == STATE_DISCONNECTED)
|
||||
return;
|
||||
if (next_state_ == STATE_CONNECT_COMPLETE)
|
||||
next_state_ = STATE_READ_REPLY_COMPLETE;
|
||||
}
|
||||
|
||||
if (result > 0)
|
||||
result = ProcessResponseHeaders(response_header_block_);
|
||||
|
||||
|
|
|
|||
|
|
@ -164,6 +164,9 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
|
|||
|
||||
std::string user_agent_;
|
||||
|
||||
bool use_fastopen_ = false;
|
||||
std::optional<bool> read_headers_pending_;
|
||||
|
||||
const NetLogWithSource net_log_;
|
||||
|
||||
// The default weak pointer factory.
|
||||
|
|
|
|||
Loading…
Reference in New Issue