net/spdy: propagate CONNECT response header conversion result
OnHeadersReceived() discarded the SpdyHeadersToHttpResponse() result, so a conversion failure (e.g. multiple distinct location headers) left response_.headers unassigned for DoReadReplyComplete() to dereference. Propagate the result to OnIOComplete() so the existing "result < 0" short-circuit in DoReadReplyComplete() handles the failure with the actual error code. For proxy Fast Open, where Connect() has already completed early, only complete a pending application read and transition to STATE_DISCONNECTED on failure.pull/827/head
parent
a5fe135a76
commit
f318b76a4c
|
|
@ -321,6 +321,11 @@ void SpdyProxyClientSocket::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 < 0)
|
||||
next_state_ = STATE_DISCONNECTED;
|
||||
if (!read_callback_ || rv == OK) return;
|
||||
}
|
||||
std::move(read_callback_).Run(rv);
|
||||
}
|
||||
}
|
||||
|
|
@ -394,20 +399,6 @@ int SpdyProxyClientSocket::DoLoop(int last_io_result) {
|
|||
case STATE_PROCESS_RESPONSE_CODE:
|
||||
DCHECK_EQ(OK, rv);
|
||||
rv = DoProcessResponseCode();
|
||||
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";
|
||||
|
|
@ -554,12 +545,6 @@ int SpdyProxyClientSocket::DoReadReplyComplete(int result) {
|
|||
if (result < 0)
|
||||
return result;
|
||||
|
||||
// SpdyHeadersToHttpResponse() may have failed to convert the response
|
||||
// headers (e.g. duplicate location values), in which case
|
||||
// response_.headers is null and must not be dereferenced.
|
||||
if (!response_.headers)
|
||||
return ERR_TUNNEL_CONNECTION_FAILED;
|
||||
|
||||
// Require the "HTTP/1.x" status line for SSL CONNECT.
|
||||
if (response_.headers->GetHttpVersion() < HttpVersion(1, 0))
|
||||
return ERR_TUNNEL_CONNECTION_FAILED;
|
||||
|
|
@ -639,6 +624,7 @@ void SpdyProxyClientSocket::OnEarlyHintsReceived(
|
|||
void SpdyProxyClientSocket::OnHeadersReceived(
|
||||
const quiche::HttpHeaderBlock& response_headers) {
|
||||
if (use_fastopen_ && read_headers_pending_ && next_state_ == STATE_OPEN) {
|
||||
read_headers_pending_ = false;
|
||||
next_state_ = STATE_READ_REPLY_COMPLETE;
|
||||
}
|
||||
|
||||
|
|
@ -652,7 +638,7 @@ void SpdyProxyClientSocket::OnHeadersReceived(
|
|||
const int rv = SpdyHeadersToHttpResponse(response_headers, &response_);
|
||||
DCHECK_NE(rv, ERR_INCOMPLETE_HTTP2_HEADERS);
|
||||
|
||||
OnIOComplete(OK);
|
||||
OnIOComplete(rv);
|
||||
}
|
||||
|
||||
// Called when data is received or on EOF (if `buffer is nullptr).
|
||||
|
|
|
|||
|
|
@ -202,7 +202,7 @@ class NET_EXPORT_PRIVATE SpdyProxyClientSocket : public ProxyClientSocket,
|
|||
|
||||
bool use_fastopen_ = false;
|
||||
std::optional<size_t> preamble_index_;
|
||||
bool read_headers_pending_ = false;
|
||||
std::optional<bool> read_headers_pending_;
|
||||
|
||||
const NetLogWithSource net_log_;
|
||||
const NetLogSource source_dependency_;
|
||||
|
|
|
|||
Loading…
Reference in New Issue