Chromium在发送重试请求之前检查了套接字是否已重用,我想知道为什么有必要发生ECONNRESET错误,如果服务器未在端口上处理,则会收到ECONNREFUSED错误,因此也许每次运行时我们都可以重试进入ECONNRESET错误。
https://cs.chromium.org/chromium/src/net/http/http_network_transaction.cc?g=0&l=1646
bool HttpNetworkTransaction::ShouldResendRequest() const {
bool connection_is_proven = stream_->IsConnectionReused();
bool has_received_headers = GetResponseHeaders() != nullptr;
// NOTE: we resend a request only if we reused a keep-alive connection.
// This automatically prevents an infinite resend loop because we'll run
// out of the cached keep-alive connections eventually.
if (connection_is_proven && !has_received_headers)
return true;
return false;
}
switch (error) {
// If we try to reuse a connection that the server is in the process of
// closing, we may end up successfully writing out our request (or a
// portion of our request) only to find a connection error when we try to
// read from (or finish writing to) the socket.
case ERR_CONNECTION_RESET:
case ERR_CONNECTION_CLOSED:
case ERR_CONNECTION_ABORTED:
// There can be a race between the socket pool checking checking whether a
// socket is still connected, receiving the FIN, and sending/reading data
// on a reused socket. If we receive the FIN between the connectedness
// check and writing/reading from the socket, we may first learn the socket
// is disconnected when we get a ERR_SOCKET_NOT_CONNECTED. This will most
// likely happen when trying to retrieve its IP address.
// See http://crbug.com/105824 for more details.
case ERR_SOCKET_NOT_CONNECTED:
// If a socket is closed on its initial request, HttpStreamParser returns
// ERR_EMPTY_RESPONSE. This may still be close/reuse race if the socket was
// preconnected but failed to be used before the server timed it out.
case ERR_EMPTY_RESPONSE:
if (ShouldResendRequest()) {
net_log_.AddEventWithNetErrorCode(
NetLogEventType::HTTP_TRANSACTION_RESTART_AFTER_ERROR, error);
ResetConnectionAndRequestForResend();
error = OK;
}
break;