Commit 93935c08 authored by Daniel Stenberg's avatar Daniel Stenberg
Browse files

multi: multi_reconnect_request is the former Curl_reconnect_request

now a file local function in multi.c
parent 6b61d816
Loading
Loading
Loading
Loading
+58 −2
Original line number Diff line number Diff line
@@ -990,6 +990,62 @@ CURLMcode Curl_multi_add_perform(struct Curl_multi *multi,
  return rc;
}

static CURLcode multi_reconnect_request(struct connectdata **connp)
{
  CURLcode result = CURLE_OK;
  struct connectdata *conn = *connp;
  struct SessionHandle *data = conn->data;

  /* This was a re-use of a connection and we got a write error in the
   * DO-phase. Then we DISCONNECT this connection and have another attempt to
   * CONNECT and then DO again! The retry cannot possibly find another
   * connection to re-use, since we only keep one possible connection for
   * each.  */

  infof(data, "Re-used connection seems dead, get a new one\n");

  connclose(conn, "Reconnect dead connection"); /* enforce close */
  result = Curl_done(&conn, result, FALSE); /* we are so done with this */

  /* conn may no longer be a good pointer, clear it to avoid mistakes by
     parent functions */
  *connp = NULL;

  /*
   * According to bug report #1330310. We need to check for CURLE_SEND_ERROR
   * here as well. I figure this could happen when the request failed on a FTP
   * connection and thus Curl_done() itself tried to use the connection
   * (again). Slight Lack of feedback in the report, but I don't think this
   * extra check can do much harm.
   */
  if(!result || (CURLE_SEND_ERROR == result)) {
    bool async;
    bool protocol_done = TRUE;

    /* Now, redo the connect and get a new connection */
    result = Curl_connect(data, connp, &async, &protocol_done);
    if(!result) {
      /* We have connected or sent away a name resolve query fine */

      conn = *connp; /* setup conn to again point to something nice */
      if(async) {
        /* Now, if async is TRUE here, we need to wait for the name
           to resolve */
        result = Curl_resolver_wait_resolv(conn, NULL);
        if(result)
          return result;

        /* Resolved, continue with the connection */
        result = Curl_async_resolved(conn, &protocol_done);
        if(result)
          return result;
      }
    }
  }

  return result;
}

/*
 * do_complete is called when the DO actions are complete.
 *
@@ -1022,11 +1078,11 @@ static CURLcode multi_do(struct connectdata **connp, bool *done)
       * figure out how to re-establish the connection.
       */
      if(!data->multi) {
        result = Curl_reconnect_request(connp);
        result = multi_reconnect_request(connp);

        if(!result) {
          /* ... finally back to actually retry the DO phase */
          conn = *connp; /* re-assign conn since Curl_reconnect_request
          conn = *connp; /* re-assign conn since multi_reconnect_request
                            creates a new connection */
          result = conn->handler->do_it(conn, done);
        }
+0 −57
Original line number Diff line number Diff line
@@ -1838,63 +1838,6 @@ CURLcode Curl_follow(struct SessionHandle *data,
#endif /* CURL_DISABLE_HTTP */
}

CURLcode
Curl_reconnect_request(struct connectdata **connp)
{
  CURLcode result = CURLE_OK;
  struct connectdata *conn = *connp;
  struct SessionHandle *data = conn->data;

  /* This was a re-use of a connection and we got a write error in the
   * DO-phase. Then we DISCONNECT this connection and have another attempt to
   * CONNECT and then DO again! The retry cannot possibly find another
   * connection to re-use, since we only keep one possible connection for
   * each.  */

  infof(data, "Re-used connection seems dead, get a new one\n");

  connclose(conn, "Reconnect dead connection"); /* enforce close */
  result = Curl_done(&conn, result, FALSE); /* we are so done with this */

  /* conn may no longer be a good pointer, clear it to avoid mistakes by
     parent functions */
  *connp = NULL;

  /*
   * According to bug report #1330310. We need to check for CURLE_SEND_ERROR
   * here as well. I figure this could happen when the request failed on a FTP
   * connection and thus Curl_done() itself tried to use the connection
   * (again). Slight Lack of feedback in the report, but I don't think this
   * extra check can do much harm.
   */
  if(!result || (CURLE_SEND_ERROR == result)) {
    bool async;
    bool protocol_done = TRUE;

    /* Now, redo the connect and get a new connection */
    result = Curl_connect(data, connp, &async, &protocol_done);
    if(!result) {
      /* We have connected or sent away a name resolve query fine */

      conn = *connp; /* setup conn to again point to something nice */
      if(async) {
        /* Now, if async is TRUE here, we need to wait for the name
           to resolve */
        result = Curl_resolver_wait_resolv(conn, NULL);
        if(result)
          return result;

        /* Resolved, continue with the connection */
        result = Curl_async_resolved(conn, &protocol_done);
        if(result)
          return result;
      }
    }
  }

  return result;
}

/* Returns CURLE_OK *and* sets '*url' if a request retry is wanted.

   NOTE: that the *url is malloc()ed. */
+1 −2
Original line number Diff line number Diff line
@@ -7,7 +7,7 @@
 *                            | (__| |_| |  _ <| |___
 *                             \___|\___/|_| \_\_____|
 *
 * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al.
 * Copyright (C) 1998 - 2016, Daniel Stenberg, <daniel@haxx.se>, et al.
 *
 * This software is licensed as described in the file COPYING, which
 * you should have received as part of this distribution. The terms
@@ -49,7 +49,6 @@ int Curl_single_getsock(const struct connectdata *conn,
                        int numsocks);
CURLcode Curl_readrewind(struct connectdata *conn);
CURLcode Curl_fillreadbuffer(struct connectdata *conn, int bytes, int *nreadp);
CURLcode Curl_reconnect_request(struct connectdata **connp);
CURLcode Curl_retry_request(struct connectdata *conn, char **url);
bool Curl_meets_timecondition(struct SessionHandle *data, time_t timeofdoc);