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
klzgrad 2019-01-17 05:47:20 -05:00
parent 41179267cf
commit 225893da02
3 changed files with 33 additions and 0 deletions

View File

@ -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) {

View File

@ -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_);

View File

@ -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.