From c8e823bc002aa883ec2220c1b6614851dcd337ee Mon Sep 17 00:00:00 2001 From: klzgrad Date: Thu, 17 Jan 2019 05:47:20 -0500 Subject: [PATCH] quic: Add support for HTTP/3 CONNECT Fast Open --- src/net/quic/quic_proxy_client_socket.cc | 28 ++++++++++++++++++++++++ src/net/quic/quic_proxy_client_socket.h | 3 +++ 2 files changed, 31 insertions(+) diff --git a/src/net/quic/quic_proxy_client_socket.cc b/src/net/quic/quic_proxy_client_socket.cc index ebcb314828..f81667d2fd 100644 --- a/src/net/quic/quic_proxy_client_socket.cc +++ b/src/net/quic/quic_proxy_client_socket.cc @@ -37,6 +37,10 @@ QuicProxyClientSocket::QuicProxyClientSocket( auth_(auth_controller), user_agent_(user_agent), redirect_has_load_timing_info_(false), + // This is a hack to avoid messing up higer APIs. + // Should be false by default officially. + use_fastopen_(true), + read_headers_pending_(false), net_log_(net_log), weak_factory_(this) { DCHECK(stream_->IsOpen()); @@ -304,6 +308,20 @@ int QuicProxyClientSocket::DoLoop(int last_io_result) { rv = DoReadReplyComplete(rv); net_log_.EndEventWithNetErrorCode( NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); + if (use_fastopen_ && read_headers_pending_) { + read_headers_pending_ = false; + if (rv < 0) { + // read_callback_ cannot be called. + if (!read_callback_) + rv = ERR_IO_PENDING; + // read_callback_ will be called with this error and be reset. + // Further data after that will be ignored. + next_state_ = STATE_DISCONNECTED; + } else { + // Does not call read_callback_ from here if headers are OK. + rv = ERR_IO_PENDING; + } + } break; default: NOTREACHED() << "bad state"; @@ -377,6 +395,11 @@ int QuicProxyClientSocket::DoReadReply() { &response_header_block_, base::Bind(&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) @@ -426,6 +449,11 @@ int QuicProxyClientSocket::DoReadReplyComplete(int result) { } void QuicProxyClientSocket::OnReadResponseHeadersComplete(int result) { + if (use_fastopen_ && read_headers_pending_ && + next_state_ == STATE_CONNECT_COMPLETE) { + next_state_ = STATE_READ_REPLY_COMPLETE; + } + // Convert the now-populated spdy::SpdyHeaderBlock to HttpResponseInfo if (result > 0) result = ProcessResponseHeaders(response_header_block_); diff --git a/src/net/quic/quic_proxy_client_socket.h b/src/net/quic/quic_proxy_client_socket.h index 45d15fcbf5..93acb01a48 100644 --- a/src/net/quic/quic_proxy_client_socket.h +++ b/src/net/quic/quic_proxy_client_socket.h @@ -146,6 +146,9 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket { // Session connect timing info. LoadTimingInfo::ConnectTiming connect_timing_; + bool use_fastopen_; + bool read_headers_pending_; + const NetLogWithSource net_log_; // The default weak pointer factory.