Необходимо ли повторно использовать сокет проверки хрома перед отправкой повторной попытки при ошибке connreset? - PullRequest
0 голосов
/ 15 октября 2019

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