diff options
Diffstat (limited to 'lib')
| -rw-r--r-- | lib/multi.c | 60 | ||||
| -rw-r--r-- | lib/transfer.c | 57 | ||||
| -rw-r--r-- | lib/transfer.h | 3 | 
3 files changed, 59 insertions, 61 deletions
| diff --git a/lib/multi.c b/lib/multi.c index 3856a7ac2..e88d7d492 100644 --- a/lib/multi.c +++ b/lib/multi.c @@ -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);          } diff --git a/lib/transfer.c b/lib/transfer.c index 7481e0c8a..da74ac1fd 100644 --- a/lib/transfer.c +++ b/lib/transfer.c @@ -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. */ diff --git a/lib/transfer.h b/lib/transfer.h index 52b762abf..802344f23 100644 --- a/lib/transfer.h +++ b/lib/transfer.h @@ -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); | 
