Curl_done() and the protocol-specific conn->curl_done() functions now all

take a CURLcode as a second argument, that is non-zero when Curl_done()
is called after an error was returned from Curl_do() (or similar).
This commit is contained in:
Daniel Stenberg 2004-05-12 12:06:39 +00:00
parent 1d7ce36791
commit d60c22572b
11 changed files with 54 additions and 25 deletions

View File

@ -738,13 +738,14 @@ CURLcode Curl_ftp_connect(struct connectdata *conn)
* *
* Input argument is already checked for validity. * Input argument is already checked for validity.
*/ */
CURLcode Curl_ftp_done(struct connectdata *conn) CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status)
{ {
struct SessionHandle *data = conn->data; struct SessionHandle *data = conn->data;
struct FTP *ftp = conn->proto.ftp; struct FTP *ftp = conn->proto.ftp;
ssize_t nread; ssize_t nread;
int ftpcode; int ftpcode;
CURLcode result=CURLE_OK; CURLcode result=CURLE_OK;
bool was_ctl_valid = ftp->ctl_valid; bool was_ctl_valid = ftp->ctl_valid;
/* free the dir tree and file parts */ /* free the dir tree and file parts */
@ -784,8 +785,24 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
result = CURLE_FTP_COULDNT_RETR_FILE; result = CURLE_FTP_COULDNT_RETR_FILE;
} }
} }
ftp->ctl_valid = was_ctl_valid; switch(status) {
case CURLE_BAD_DOWNLOAD_RESUME:
case CURLE_FTP_WEIRD_PASV_REPLY:
case CURLE_FTP_PORT_FAILED:
case CURLE_FTP_COULDNT_SET_BINARY:
case CURLE_FTP_COULDNT_RETR_FILE:
case CURLE_FTP_ACCESS_DENIED:
/* the connection stays alive fine even though this happened */
/* fall-through */
case CURLE_OK: /* doesn't affect the control connection's status */
ftp->ctl_valid = was_ctl_valid;
break;
default: /* by default, an error means the control connection is
wedged and should not be used anymore */
ftp->ctl_valid = FALSE;
break;
}
#ifdef HAVE_KRB4 #ifdef HAVE_KRB4
Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]); Curl_sec_fflush_fd(conn, conn->sock[SECONDARYSOCKET]);
@ -794,12 +811,12 @@ CURLcode Curl_ftp_done(struct connectdata *conn)
sclose(conn->sock[SECONDARYSOCKET]); sclose(conn->sock[SECONDARYSOCKET]);
conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD; conn->sock[SECONDARYSOCKET] = CURL_SOCKET_BAD;
if(!ftp->no_transfer) { if(!ftp->no_transfer && !status) {
/* Let's see what the server says about the transfer we just performed, /* Let's see what the server says about the transfer we just performed,
but lower the timeout as sometimes this connection has died while * but lower the timeout as sometimes this connection has died while the
the data has been transfered. This happens when doing through NATs * data has been transfered. This happens when doing through NATs etc that
etc that abandon old silent connections. * abandon old silent connections.
*/ */
ftp->response_time = 60; /* give it only a minute for now */ ftp->response_time = 60; /* give it only a minute for now */
result = Curl_GetFTPResponse(&nread, conn, &ftpcode); result = Curl_GetFTPResponse(&nread, conn, &ftpcode);

View File

@ -25,7 +25,7 @@
#ifndef CURL_DISABLE_FTP #ifndef CURL_DISABLE_FTP
CURLcode Curl_ftp(struct connectdata *conn); CURLcode Curl_ftp(struct connectdata *conn);
CURLcode Curl_ftp_done(struct connectdata *conn); CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode);
CURLcode Curl_ftp_connect(struct connectdata *conn); CURLcode Curl_ftp_connect(struct connectdata *conn);
CURLcode Curl_ftp_disconnect(struct connectdata *conn); CURLcode Curl_ftp_disconnect(struct connectdata *conn);
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...); CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);

View File

@ -1172,10 +1172,12 @@ CURLcode Curl_http_connect(struct connectdata *conn)
* has been performed. * has been performed.
*/ */
CURLcode Curl_http_done(struct connectdata *conn) CURLcode Curl_http_done(struct connectdata *conn,
CURLcode status)
{ {
struct SessionHandle *data; struct SessionHandle *data;
struct HTTP *http; struct HTTP *http;
(void)status; /* no use for us */
data=conn->data; data=conn->data;
http=conn->proto.http; http=conn->proto.http;

View File

@ -35,7 +35,7 @@ CURLcode Curl_ConnectHTTPProxyTunnel(struct connectdata *conn,
/* protocol-specific functions set up to be called by the main engine */ /* protocol-specific functions set up to be called by the main engine */
CURLcode Curl_http(struct connectdata *conn); CURLcode Curl_http(struct connectdata *conn);
CURLcode Curl_http_done(struct connectdata *conn); CURLcode Curl_http_done(struct connectdata *, CURLcode);
CURLcode Curl_http_connect(struct connectdata *conn); CURLcode Curl_http_connect(struct connectdata *conn);
/* The following functions are defined in http_chunks.c */ /* The following functions are defined in http_chunks.c */

View File

@ -329,7 +329,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
char *gotourl; char *gotourl;
Curl_posttransfer(easy->easy_handle); Curl_posttransfer(easy->easy_handle);
easy->result = Curl_done(easy->easy_conn); easy->result = Curl_done(easy->easy_conn, CURLE_OK);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
gotourl = strdup(easy->easy_handle->change.url); gotourl = strdup(easy->easy_handle->change.url);
easy->easy_handle->change.url_changed = FALSE; easy->easy_handle->change.url_changed = FALSE;
@ -491,7 +491,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
easy->easy_conn->sock[SECONDARYSOCKET]=-1; easy->easy_conn->sock[SECONDARYSOCKET]=-1;
} }
Curl_posttransfer(easy->easy_handle); Curl_posttransfer(easy->easy_handle);
Curl_done(easy->easy_conn); Curl_done(easy->easy_conn, easy->result);
} }
/* after the transfer is done, go DONE */ /* after the transfer is done, go DONE */
@ -504,7 +504,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
if(easy->easy_conn->newurl) { if(easy->easy_conn->newurl) {
char *newurl = easy->easy_conn->newurl; char *newurl = easy->easy_conn->newurl;
easy->easy_conn->newurl = NULL; easy->easy_conn->newurl = NULL;
easy->result = Curl_done(easy->easy_conn); easy->result = Curl_done(easy->easy_conn, CURLE_OK);
if(easy->result == CURLE_OK) if(easy->result == CURLE_OK)
easy->result = Curl_follow(easy->easy_handle, newurl); easy->result = Curl_follow(easy->easy_handle, newurl);
if(CURLE_OK == easy->result) { if(CURLE_OK == easy->result) {
@ -520,7 +520,7 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
break; break;
case CURLM_STATE_DONE: case CURLM_STATE_DONE:
/* post-transfer command */ /* post-transfer command */
easy->result = Curl_done(easy->easy_conn); easy->result = Curl_done(easy->easy_conn, CURLE_OK);
/* after we have DONE what we're supposed to do, go COMPLETED, and /* after we have DONE what we're supposed to do, go COMPLETED, and
it doesn't matter what the Curl_done() returned! */ it doesn't matter what the Curl_done() returned! */

View File

@ -1063,9 +1063,11 @@ void telrcv(struct connectdata *conn,
} }
} }
CURLcode Curl_telnet_done(struct connectdata *conn) CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status)
{ {
struct TELNET *tn = (struct TELNET *)conn->proto.telnet; struct TELNET *tn = (struct TELNET *)conn->proto.telnet;
(void)status; /* unused */
curl_slist_free_all(tn->telnet_vars); curl_slist_free_all(tn->telnet_vars);
free(conn->proto.telnet); free(conn->proto.telnet);

View File

@ -25,6 +25,6 @@
***************************************************************************/ ***************************************************************************/
#ifndef CURL_DISABLE_TELNET #ifndef CURL_DISABLE_TELNET
CURLcode Curl_telnet(struct connectdata *conn); CURLcode Curl_telnet(struct connectdata *conn);
CURLcode Curl_telnet_done(struct connectdata *conn); CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode);
#endif #endif
#endif #endif

View File

@ -853,6 +853,8 @@ CURLcode Curl_readwrite(struct connectdata *conn,
*ptr = '\0'; /* zero terminate */ *ptr = '\0'; /* zero terminate */
conn->newurl = strdup(start); /* clone string */ conn->newurl = strdup(start); /* clone string */
*ptr = backup; /* restore ending letter */ *ptr = backup; /* restore ending letter */
if(!conn->newurl)
return CURLE_OUT_OF_MEMORY;
} }
} }
#if 0 /* for consideration */ #if 0 /* for consideration */
@ -1967,7 +1969,7 @@ CURLcode Curl_perform(struct SessionHandle *data)
to the new URL */ to the new URL */
urlchanged = data->change.url_changed; urlchanged = data->change.url_changed;
if ((CURLE_OK == res) && urlchanged) { if ((CURLE_OK == res) && urlchanged) {
res = Curl_done(conn); res = Curl_done(conn, res);
if(CURLE_OK == res) { if(CURLE_OK == res) {
char *gotourl = strdup(data->change.url); char *gotourl = strdup(data->change.url);
res = Curl_follow(data, gotourl); res = Curl_follow(data, gotourl);
@ -2024,14 +2026,14 @@ CURLcode Curl_perform(struct SessionHandle *data)
/* Always run Curl_done(), even if some of the previous calls /* Always run Curl_done(), even if some of the previous calls
failed, but return the previous (original) error code */ failed, but return the previous (original) error code */
res2 = Curl_done(conn); res2 = Curl_done(conn, res);
if(CURLE_OK == res) if(CURLE_OK == res)
res = res2; res = res2;
} }
else else
/* Curl_do() failed, clean up left-overs in the done-call */ /* Curl_do() failed, clean up left-overs in the done-call */
res2 = Curl_done(conn); res2 = Curl_done(conn, res);
/* /*
* Important: 'conn' cannot be used here, since it may have been closed * Important: 'conn' cannot be used here, since it may have been closed

View File

@ -3229,6 +3229,8 @@ static CURLcode SetupConnection(struct connectdata *conn,
Curl_safefree(conn->allocptr.uagent); Curl_safefree(conn->allocptr.uagent);
conn->allocptr.uagent = conn->allocptr.uagent =
aprintf("User-Agent: %s\015\012", data->set.useragent); aprintf("User-Agent: %s\015\012", data->set.useragent);
if(!conn->allocptr.uagent)
return CURLE_OUT_OF_MEMORY;
} }
} }
@ -3236,6 +3238,8 @@ static CURLcode SetupConnection(struct connectdata *conn,
Curl_safefree(conn->allocptr.accept_encoding); Curl_safefree(conn->allocptr.accept_encoding);
conn->allocptr.accept_encoding = conn->allocptr.accept_encoding =
aprintf("Accept-Encoding: %s\015\012", data->set.encoding); aprintf("Accept-Encoding: %s\015\012", data->set.encoding);
if(!conn->allocptr.accept_encoding)
return CURLE_OUT_OF_MEMORY;
} }
conn->bytecount = 0; conn->bytecount = 0;
@ -3340,7 +3344,9 @@ CURLcode Curl_async_resolved(struct connectdata *conn)
} }
CURLcode Curl_done(struct connectdata *conn) CURLcode Curl_done(struct connectdata *conn,
CURLcode status) /* an error if this is called after an
error was detected */
{ {
struct SessionHandle *data=conn->data; struct SessionHandle *data=conn->data;
CURLcode result; CURLcode result;
@ -3371,7 +3377,7 @@ CURLcode Curl_done(struct connectdata *conn)
/* this calls the protocol-specific function pointer previously set */ /* this calls the protocol-specific function pointer previously set */
if(conn->curl_done) if(conn->curl_done)
result = conn->curl_done(conn); result = conn->curl_done(conn, status);
else else
result = CURLE_OK; result = CURLE_OK;
@ -3423,7 +3429,7 @@ CURLcode Curl_do(struct connectdata **connp)
infof(data, "Re-used connection seems dead, get a new one\n"); infof(data, "Re-used connection seems dead, get a new one\n");
conn->bits.close = TRUE; /* enforce close of this connection */ conn->bits.close = TRUE; /* enforce close of this connection */
result = Curl_done(conn); /* we are so done with this */ result = Curl_done(conn, result); /* we are so done with this */
/* conn is no longer a good pointer */ /* conn is no longer a good pointer */

View File

@ -35,7 +35,7 @@ CURLcode Curl_connect(struct SessionHandle *, struct connectdata **,
CURLcode Curl_async_resolved(struct connectdata *conn); CURLcode Curl_async_resolved(struct connectdata *conn);
CURLcode Curl_do(struct connectdata **); CURLcode Curl_do(struct connectdata **);
CURLcode Curl_do_more(struct connectdata *); CURLcode Curl_do_more(struct connectdata *);
CURLcode Curl_done(struct connectdata *); CURLcode Curl_done(struct connectdata *, CURLcode);
CURLcode Curl_disconnect(struct connectdata *); CURLcode Curl_disconnect(struct connectdata *);
CURLcode Curl_protocol_connect(struct connectdata *conn); CURLcode Curl_protocol_connect(struct connectdata *conn);
bool Curl_ssl_config_matches(struct ssl_config_data* data, bool Curl_ssl_config_matches(struct ssl_config_data* data,

View File

@ -482,7 +482,7 @@ struct connectdata {
/* These two functions MUST be set by the curl_connect() function to be /* These two functions MUST be set by the curl_connect() function to be
be protocol dependent */ be protocol dependent */
CURLcode (*curl_do)(struct connectdata *); CURLcode (*curl_do)(struct connectdata *);
CURLcode (*curl_done)(struct connectdata *); CURLcode (*curl_done)(struct connectdata *, CURLcode);
/* If the curl_do() function is better made in two halves, this /* If the curl_do() function is better made in two halves, this
* curl_do_more() function will be called afterwards, if set. For example * curl_do_more() function will be called afterwards, if set. For example