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_.
This commit is contained in:
klzgrad 2019-01-17 05:47:20 -05:00
parent bc84c9c6b9
commit 0b46fc1fd5
2 changed files with 35 additions and 0 deletions

View File

@ -38,6 +38,8 @@ QuicProxyClientSocket::QuicProxyClientSocket(
proxy_server_(proxy_server), proxy_server_(proxy_server),
proxy_delegate_(proxy_delegate), proxy_delegate_(proxy_delegate),
user_agent_(user_agent), user_agent_(user_agent),
use_fastopen_(false),
read_headers_pending_(false),
net_log_(net_log) { net_log_(net_log) {
DCHECK(stream_->IsOpen()); DCHECK(stream_->IsOpen());
@ -306,6 +308,16 @@ int QuicProxyClientSocket::DoLoop(int last_io_result) {
rv = DoReadReplyComplete(rv); rv = DoReadReplyComplete(rv);
net_log_.EndEventWithNetErrorCode( net_log_.EndEventWithNetErrorCode(
NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv); NetLogEventType::HTTP_TRANSACTION_TUNNEL_READ_HEADERS, rv);
if (use_fastopen_ && read_headers_pending_) {
read_headers_pending_ = false;
if (rv < 0) {
// read_callback_ will be called with this error and be reset.
// Further data after that will be ignored.
next_state_ = STATE_DISCONNECTED;
}
// Prevents calling connect_callback_.
rv = ERR_IO_PENDING;
}
break; break;
default: default:
NOTREACHED() << "bad state"; NOTREACHED() << "bad state";
@ -346,6 +358,11 @@ int QuicProxyClientSocket::DoSendRequest() {
HttpRequestHeaders proxy_delegate_headers; HttpRequestHeaders proxy_delegate_headers;
proxy_delegate_->OnBeforeTunnelRequest(proxy_server_, proxy_delegate_->OnBeforeTunnelRequest(proxy_server_,
&proxy_delegate_headers); &proxy_delegate_headers);
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); request_.extra_headers.MergeFrom(proxy_delegate_headers);
} }
@ -385,6 +402,11 @@ int QuicProxyClientSocket::DoReadReply() {
&response_header_block_, &response_header_block_,
base::BindOnce(&QuicProxyClientSocket::OnReadResponseHeadersComplete, base::BindOnce(&QuicProxyClientSocket::OnReadResponseHeadersComplete,
weak_factory_.GetWeakPtr())); 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) if (rv == ERR_IO_PENDING)
return ERR_IO_PENDING; return ERR_IO_PENDING;
if (rv < 0) if (rv < 0)
@ -433,6 +455,13 @@ int QuicProxyClientSocket::DoReadReplyComplete(int result) {
void QuicProxyClientSocket::OnReadResponseHeadersComplete(int result) { void QuicProxyClientSocket::OnReadResponseHeadersComplete(int result) {
// Convert the now-populated spdy::Http2HeaderBlock to HttpResponseInfo // Convert the now-populated spdy::Http2HeaderBlock to HttpResponseInfo
if (use_fastopen_ && read_headers_pending_) {
if (next_state_ == STATE_DISCONNECTED)
return;
if (next_state_ == STATE_CONNECT_COMPLETE)
next_state_ = STATE_READ_REPLY_COMPLETE;
}
if (result > 0) if (result > 0)
result = ProcessResponseHeaders(response_header_block_); result = ProcessResponseHeaders(response_header_block_);

View File

@ -144,6 +144,12 @@ class NET_EXPORT_PRIVATE QuicProxyClientSocket : public ProxyClientSocket {
std::string user_agent_; std::string user_agent_;
// Session connect timing info.
LoadTimingInfo::ConnectTiming connect_timing_;
bool use_fastopen_;
bool read_headers_pending_;
const NetLogWithSource net_log_; const NetLogWithSource net_log_;
// The default weak pointer factory. // The default weak pointer factory.