mirror of
https://github.com/moparisthebest/curl
synced 2024-11-11 20:15:03 -05:00
merged the multi-dev branch back into MAIN again
This commit is contained in:
parent
6de7dc5879
commit
8b6314ccfb
@ -57,7 +57,8 @@ escape.h getpass.c netrc.c telnet.h \
|
|||||||
getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \
|
getinfo.c getinfo.h transfer.c strequal.c strequal.h easy.c \
|
||||||
security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \
|
security.h security.c krb4.c krb4.h memdebug.c memdebug.h inet_ntoa_r.h \
|
||||||
http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h \
|
http_chunks.c http_chunks.h strtok.c strtok.h connect.c connect.h \
|
||||||
llist.c llist.h hash.c hash.h
|
llist.c llist.h hash.c hash.h multi.c multi.h
|
||||||
|
|
||||||
|
|
||||||
noinst_HEADERS = setup.h transfer.h
|
noinst_HEADERS = setup.h transfer.h
|
||||||
|
|
||||||
|
56
lib/multi.c
56
lib/multi.c
@ -22,10 +22,16 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
|
|
||||||
#include "setup.h"
|
#include "setup.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
#include <curl/curl.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
#include "multi.h" /* will become <curl/multi.h> soon */
|
#include "multi.h" /* will become <curl/multi.h> soon */
|
||||||
|
|
||||||
|
#include "urldata.h"
|
||||||
|
#include "transfer.h"
|
||||||
|
#include "url.h"
|
||||||
|
|
||||||
struct Curl_message {
|
struct Curl_message {
|
||||||
/* the 'CURLMsg' is the part that is visible to the external user */
|
/* the 'CURLMsg' is the part that is visible to the external user */
|
||||||
struct CURLMsg extmsg;
|
struct CURLMsg extmsg;
|
||||||
@ -48,7 +54,9 @@ struct Curl_one_easy {
|
|||||||
struct Curl_one_easy *next;
|
struct Curl_one_easy *next;
|
||||||
struct Curl_one_easy *prev;
|
struct Curl_one_easy *prev;
|
||||||
|
|
||||||
CURL *easy_handle; /* this is the easy handle for this unit */
|
struct SessionHandle *easy_handle; /* the easy handle for this unit */
|
||||||
|
struct connectdata *easy_conn; /* the "unit's" connection */
|
||||||
|
|
||||||
CURLMstate state; /* the handle's state */
|
CURLMstate state; /* the handle's state */
|
||||||
CURLcode result; /* previous result */
|
CURLcode result; /* previous result */
|
||||||
};
|
};
|
||||||
@ -134,7 +142,7 @@ CURLMcode curl_multi_add_handle(CURLM *multi_handle,
|
|||||||
/* increase the node-counter */
|
/* increase the node-counter */
|
||||||
multi->num_easy++;
|
multi->num_easy++;
|
||||||
|
|
||||||
return CURLM_OK;
|
return CURLM_CALL_MULTI_PERFORM;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
CURLMcode curl_multi_remove_handle(CURLM *multi_handle,
|
||||||
@ -190,23 +198,30 @@ CURLMcode curl_multi_fdset(CURLM *multi_handle,
|
|||||||
and then we must make sure that is done. */
|
and then we must make sure that is done. */
|
||||||
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
struct Curl_multi *multi=(struct Curl_multi *)multi_handle;
|
||||||
struct Curl_one_easy *easy;
|
struct Curl_one_easy *easy;
|
||||||
|
int this_max_fd=-1;
|
||||||
|
|
||||||
if(!GOOD_MULTI_HANDLE(multi))
|
if(!GOOD_MULTI_HANDLE(multi))
|
||||||
return CURLM_BAD_HANDLE;
|
return CURLM_BAD_HANDLE;
|
||||||
|
|
||||||
|
*max_fd = -1; /* so far none! */
|
||||||
|
|
||||||
easy=multi->easy.next;
|
easy=multi->easy.next;
|
||||||
while(easy) {
|
while(easy) {
|
||||||
switch(easy->state) {
|
switch(easy->state) {
|
||||||
case CURLM_STATE_INIT:
|
default:
|
||||||
case CURLM_STATE_CONNECT:
|
|
||||||
case CURLM_STATE_DO:
|
|
||||||
case CURLM_STATE_DONE:
|
|
||||||
/* we want curl_multi_perform() to get called, but we don't have any
|
|
||||||
file descriptors to set */
|
|
||||||
break;
|
break;
|
||||||
case CURLM_STATE_PERFORM:
|
case CURLM_STATE_PERFORM:
|
||||||
/* This should have a set of file descriptors for us to set. */
|
/* This should have a set of file descriptors for us to set. */
|
||||||
/* after the transfer is done, go DONE */
|
/* after the transfer is done, go DONE */
|
||||||
|
|
||||||
|
Curl_single_fdset(easy->easy_conn,
|
||||||
|
read_fd_set, write_fd_set,
|
||||||
|
exc_fd_set, &this_max_fd);
|
||||||
|
|
||||||
|
/* remember the maximum file descriptor */
|
||||||
|
if(this_max_fd > *max_fd)
|
||||||
|
*max_fd = this_max_fd;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
easy = easy->next; /* check next handle */
|
easy = easy->next; /* check next handle */
|
||||||
@ -222,6 +237,8 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
bool done;
|
bool done;
|
||||||
CURLMcode result=CURLM_OK;
|
CURLMcode result=CURLM_OK;
|
||||||
|
|
||||||
|
*running_handles = 0; /* bump this once for every living handle */
|
||||||
|
|
||||||
if(!GOOD_MULTI_HANDLE(multi))
|
if(!GOOD_MULTI_HANDLE(multi))
|
||||||
return CURLM_BAD_HANDLE;
|
return CURLM_BAD_HANDLE;
|
||||||
|
|
||||||
@ -239,8 +256,9 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CURLM_STATE_CONNECT:
|
case CURLM_STATE_CONNECT:
|
||||||
/* connect */
|
/* Connect. We get a connection identifier filled in. */
|
||||||
easy->result = Curl_connect(easy->easy_handle);
|
easy->result = Curl_connect(easy->easy_handle, &easy->easy_conn);
|
||||||
|
|
||||||
/* after connect, go DO */
|
/* after connect, go DO */
|
||||||
if(CURLE_OK == easy->result) {
|
if(CURLE_OK == easy->result) {
|
||||||
easy->state = CURLM_STATE_DO;
|
easy->state = CURLM_STATE_DO;
|
||||||
@ -249,15 +267,18 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
break;
|
break;
|
||||||
case CURLM_STATE_DO:
|
case CURLM_STATE_DO:
|
||||||
/* Do the fetch or put request */
|
/* Do the fetch or put request */
|
||||||
easy->result = Curl_do(easy->easy_handle);
|
easy->result = Curl_do(&easy->easy_conn);
|
||||||
/* after do, go PERFORM */
|
/* after do, go PERFORM */
|
||||||
if(CURLE_OK == easy->result) {
|
if(CURLE_OK == easy->result) {
|
||||||
|
if(CURLE_OK == Curl_readwrite_init(easy->easy_conn)) {
|
||||||
easy->state = CURLM_STATE_PERFORM;
|
easy->state = CURLM_STATE_PERFORM;
|
||||||
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CURLM_STATE_PERFORM:
|
case CURLM_STATE_PERFORM:
|
||||||
/* read/write data if it is ready to do so */
|
/* read/write data if it is ready to do so */
|
||||||
easy->result = Curl_readwrite(easy->easy_handle, &done);
|
easy->result = Curl_readwrite(easy->easy_conn, &done);
|
||||||
/* hm, when we follow redirects, we may need to go back to the CONNECT
|
/* hm, when we follow redirects, we may need to go back to the CONNECT
|
||||||
state */
|
state */
|
||||||
/* after the transfer is done, go DONE */
|
/* after the transfer is done, go DONE */
|
||||||
@ -265,11 +286,12 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
/* call this even if the readwrite function returned error */
|
/* call this even if the readwrite function returned error */
|
||||||
easy->result = Curl_posttransfer(easy->easy_handle);
|
easy->result = Curl_posttransfer(easy->easy_handle);
|
||||||
easy->state = CURLM_STATE_DONE;
|
easy->state = CURLM_STATE_DONE;
|
||||||
|
result = CURLM_CALL_MULTI_PERFORM;
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CURLM_STATE_DONE:
|
case CURLM_STATE_DONE:
|
||||||
/* post-transfer command */
|
/* post-transfer command */
|
||||||
easy->result = Curl_done(easy->easy_handle);
|
easy->result = Curl_done(easy->easy_conn);
|
||||||
/* after we have DONE what we're supposed to do, go COMPLETED */
|
/* after we have DONE what we're supposed to do, go COMPLETED */
|
||||||
if(CURLE_OK == easy->result)
|
if(CURLE_OK == easy->result)
|
||||||
easy->state = CURLM_STATE_COMPLETED;
|
easy->state = CURLM_STATE_COMPLETED;
|
||||||
@ -280,7 +302,10 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
/* This node should be delinked from the list now and we should post
|
/* This node should be delinked from the list now and we should post
|
||||||
an information message that we are complete. */
|
an information message that we are complete. */
|
||||||
break;
|
break;
|
||||||
|
default:
|
||||||
|
return CURLM_INTERNAL_ERROR;
|
||||||
}
|
}
|
||||||
|
|
||||||
if((CURLM_STATE_COMPLETED != easy->state) &&
|
if((CURLM_STATE_COMPLETED != easy->state) &&
|
||||||
(CURLE_OK != easy->result)) {
|
(CURLE_OK != easy->result)) {
|
||||||
/*
|
/*
|
||||||
@ -289,10 +314,13 @@ CURLMcode curl_multi_perform(CURLM *multi_handle, int *running_handles)
|
|||||||
*/
|
*/
|
||||||
easy->state = CURLM_STATE_COMPLETED;
|
easy->state = CURLM_STATE_COMPLETED;
|
||||||
}
|
}
|
||||||
|
else if(CURLM_STATE_COMPLETED != easy->state)
|
||||||
|
/* this one still lives! */
|
||||||
|
(*running_handles)++;
|
||||||
|
|
||||||
easy = easy->next; /* operate on next handle */
|
easy = easy->next; /* operate on next handle */
|
||||||
}
|
}
|
||||||
return CURLM_OK;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
CURLMcode curl_multi_cleanup(CURLM *multi_handle)
|
||||||
|
@ -50,7 +50,7 @@
|
|||||||
#ifdef HAVE_SYS_SOCKET_H
|
#ifdef HAVE_SYS_SOCKET_H
|
||||||
#include <sys/socket.h>
|
#include <sys/socket.h>
|
||||||
#endif
|
#endif
|
||||||
#include <curl/types.h>
|
#include <curl/curl.h>
|
||||||
|
|
||||||
typedef void CURLM;
|
typedef void CURLM;
|
||||||
|
|
||||||
@ -60,6 +60,7 @@ typedef enum {
|
|||||||
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
CURLM_BAD_HANDLE, /* the passed-in handle is not a valid CURLM handle */
|
||||||
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
CURLM_BAD_EASY_HANDLE, /* an easy handle was not good/valid */
|
||||||
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
CURLM_OUT_OF_MEMORY, /* if you ever get this, you're in deep sh*t */
|
||||||
|
CURLM_INTERNAL_ERROR, /* this is a libcurl bug */
|
||||||
CURLM_LAST
|
CURLM_LAST
|
||||||
} CURLMcode;
|
} CURLMcode;
|
||||||
|
|
||||||
|
740
lib/transfer.c
740
lib/transfer.c
File diff suppressed because it is too large
Load Diff
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* In order to be useful for every potential user, curl and libcurl are
|
* In order to be useful for every potential user, curl and libcurl are
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||||
@ -24,6 +24,17 @@
|
|||||||
*****************************************************************************/
|
*****************************************************************************/
|
||||||
CURLcode Curl_perform(struct SessionHandle *data);
|
CURLcode Curl_perform(struct SessionHandle *data);
|
||||||
|
|
||||||
|
CURLcode Curl_pretransfer(struct SessionHandle *data);
|
||||||
|
CURLcode Curl_posttransfer(struct SessionHandle *data);
|
||||||
|
|
||||||
|
CURLcode Curl_readwrite(struct connectdata *conn, bool *done);
|
||||||
|
void Curl_single_fdset(struct connectdata *conn,
|
||||||
|
fd_set *read_fd_set,
|
||||||
|
fd_set *write_fd_set,
|
||||||
|
fd_set *exc_fd_set,
|
||||||
|
int *max_fd);
|
||||||
|
CURLcode Curl_readwrite_init(struct connectdata *conn);
|
||||||
|
|
||||||
/* This sets up a forthcoming transfer */
|
/* This sets up a forthcoming transfer */
|
||||||
CURLcode
|
CURLcode
|
||||||
Curl_Transfer (struct connectdata *data,
|
Curl_Transfer (struct connectdata *data,
|
||||||
|
57
lib/url.c
57
lib/url.c
@ -1214,8 +1214,7 @@ static CURLcode ConnectPlease(struct connectdata *conn)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static CURLcode CreateConnection(struct SessionHandle *data,
|
static CURLcode CreateConnection(struct SessionHandle *data,
|
||||||
struct connectdata **in_connect,
|
struct connectdata **in_connect)
|
||||||
bool allow_port) /* allow set.use_port? */
|
|
||||||
{
|
{
|
||||||
char *tmp;
|
char *tmp;
|
||||||
char *buf;
|
char *buf;
|
||||||
@ -1614,7 +1613,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
*************************************************************/
|
*************************************************************/
|
||||||
|
|
||||||
if (strequal(conn->protostr, "HTTP")) {
|
if (strequal(conn->protostr, "HTTP")) {
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTP;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port:PORT_HTTP;
|
||||||
conn->remote_port = PORT_HTTP;
|
conn->remote_port = PORT_HTTP;
|
||||||
conn->protocol |= PROT_HTTP;
|
conn->protocol |= PROT_HTTP;
|
||||||
conn->curl_do = Curl_http;
|
conn->curl_do = Curl_http;
|
||||||
@ -1624,7 +1624,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
else if (strequal(conn->protostr, "HTTPS")) {
|
else if (strequal(conn->protostr, "HTTPS")) {
|
||||||
#ifdef USE_SSLEAY
|
#ifdef USE_SSLEAY
|
||||||
|
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_HTTPS;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port:PORT_HTTPS;
|
||||||
conn->remote_port = PORT_HTTPS;
|
conn->remote_port = PORT_HTTPS;
|
||||||
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
|
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
|
||||||
|
|
||||||
@ -1639,7 +1640,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
#endif /* !USE_SSLEAY */
|
#endif /* !USE_SSLEAY */
|
||||||
}
|
}
|
||||||
else if (strequal(conn->protostr, "GOPHER")) {
|
else if (strequal(conn->protostr, "GOPHER")) {
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_GOPHER;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port:PORT_GOPHER;
|
||||||
conn->remote_port = PORT_GOPHER;
|
conn->remote_port = PORT_GOPHER;
|
||||||
/* Skip /<item-type>/ in path if present */
|
/* Skip /<item-type>/ in path if present */
|
||||||
if (isdigit((int)conn->path[1])) {
|
if (isdigit((int)conn->path[1])) {
|
||||||
@ -1665,7 +1667,8 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
#endif /* !USE_SSLEAY */
|
#endif /* !USE_SSLEAY */
|
||||||
}
|
}
|
||||||
|
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_FTP;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port:PORT_FTP;
|
||||||
conn->remote_port = PORT_FTP;
|
conn->remote_port = PORT_FTP;
|
||||||
conn->protocol |= PROT_FTP;
|
conn->protocol |= PROT_FTP;
|
||||||
|
|
||||||
@ -1720,21 +1723,24 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
/* telnet testing factory */
|
/* telnet testing factory */
|
||||||
conn->protocol |= PROT_TELNET;
|
conn->protocol |= PROT_TELNET;
|
||||||
|
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port: PORT_TELNET;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port: PORT_TELNET;
|
||||||
conn->remote_port = PORT_TELNET;
|
conn->remote_port = PORT_TELNET;
|
||||||
conn->curl_do = Curl_telnet;
|
conn->curl_do = Curl_telnet;
|
||||||
conn->curl_done = Curl_telnet_done;
|
conn->curl_done = Curl_telnet_done;
|
||||||
}
|
}
|
||||||
else if (strequal(conn->protostr, "DICT")) {
|
else if (strequal(conn->protostr, "DICT")) {
|
||||||
conn->protocol |= PROT_DICT;
|
conn->protocol |= PROT_DICT;
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_DICT;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port:PORT_DICT;
|
||||||
conn->remote_port = PORT_DICT;
|
conn->remote_port = PORT_DICT;
|
||||||
conn->curl_do = Curl_dict;
|
conn->curl_do = Curl_dict;
|
||||||
conn->curl_done = NULL; /* no DICT-specific done */
|
conn->curl_done = NULL; /* no DICT-specific done */
|
||||||
}
|
}
|
||||||
else if (strequal(conn->protostr, "LDAP")) {
|
else if (strequal(conn->protostr, "LDAP")) {
|
||||||
conn->protocol |= PROT_LDAP;
|
conn->protocol |= PROT_LDAP;
|
||||||
conn->port = (data->set.use_port && allow_port)?data->set.use_port:PORT_LDAP;
|
conn->port = (data->set.use_port && data->state.allow_port)?
|
||||||
|
data->set.use_port:PORT_LDAP;
|
||||||
conn->remote_port = PORT_LDAP;
|
conn->remote_port = PORT_LDAP;
|
||||||
conn->curl_do = Curl_ldap;
|
conn->curl_do = Curl_ldap;
|
||||||
conn->curl_done = NULL; /* no LDAP-specific done */
|
conn->curl_done = NULL; /* no LDAP-specific done */
|
||||||
@ -2228,14 +2234,13 @@ static CURLcode CreateConnection(struct SessionHandle *data,
|
|||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_connect(struct SessionHandle *data,
|
CURLcode Curl_connect(struct SessionHandle *data,
|
||||||
struct connectdata **in_connect,
|
struct connectdata **in_connect)
|
||||||
bool allow_port)
|
|
||||||
{
|
{
|
||||||
CURLcode code;
|
CURLcode code;
|
||||||
struct connectdata *conn;
|
struct connectdata *conn;
|
||||||
|
|
||||||
/* call the stuff that needs to be called */
|
/* call the stuff that needs to be called */
|
||||||
code = CreateConnection(data, in_connect, allow_port);
|
code = CreateConnection(data, in_connect);
|
||||||
|
|
||||||
if(CURLE_OK != code) {
|
if(CURLE_OK != code) {
|
||||||
/* We're not allowed to return failure with memory left allocated
|
/* We're not allowed to return failure with memory left allocated
|
||||||
@ -2291,14 +2296,38 @@ CURLcode Curl_done(struct connectdata *conn)
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
CURLcode Curl_do(struct connectdata *conn)
|
CURLcode Curl_do(struct connectdata **connp)
|
||||||
{
|
{
|
||||||
CURLcode result=CURLE_OK;
|
CURLcode result=CURLE_OK;
|
||||||
|
struct connectdata *conn = *connp;
|
||||||
|
struct SessionHandle *data=conn->data;
|
||||||
|
|
||||||
if(conn->curl_do)
|
if(conn->curl_do) {
|
||||||
/* generic protocol-specific function pointer set in curl_connect() */
|
/* generic protocol-specific function pointer set in curl_connect() */
|
||||||
result = conn->curl_do(conn);
|
result = conn->curl_do(conn);
|
||||||
|
|
||||||
|
/* This was formerly done in transfer.c, but we better do it here */
|
||||||
|
|
||||||
|
if((CURLE_WRITE_ERROR == result) && conn->bits.reuse) {
|
||||||
|
/* 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");
|
||||||
|
|
||||||
|
conn->bits.close = TRUE; /* enforce close of this connetion */
|
||||||
|
result = Curl_done(conn); /* we are so done with this */
|
||||||
|
if(CURLE_OK == result) {
|
||||||
|
/* Now, redo the connect and get a new connection */
|
||||||
|
result = Curl_connect(data, connp);
|
||||||
|
if(CURLE_OK == result)
|
||||||
|
/* ... finally back to actually retry the DO phase */
|
||||||
|
result = conn->curl_do(*connp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
10
lib/url.h
10
lib/url.h
@ -7,7 +7,7 @@
|
|||||||
* | (__| |_| | _ <| |___
|
* | (__| |_| | _ <| |___
|
||||||
* \___|\___/|_| \_\_____|
|
* \___|\___/|_| \_\_____|
|
||||||
*
|
*
|
||||||
* Copyright (C) 2000, Daniel Stenberg, <daniel@haxx.se>, et al.
|
* Copyright (C) 2001, Daniel Stenberg, <daniel@haxx.se>, et al.
|
||||||
*
|
*
|
||||||
* In order to be useful for every potential user, curl and libcurl are
|
* In order to be useful for every potential user, curl and libcurl are
|
||||||
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
* dual-licensed under the MPL and the MIT/X-derivate licenses.
|
||||||
@ -29,11 +29,9 @@
|
|||||||
|
|
||||||
CURLcode Curl_open(struct SessionHandle **curl);
|
CURLcode Curl_open(struct SessionHandle **curl);
|
||||||
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
|
CURLcode Curl_setopt(struct SessionHandle *data, CURLoption option, ...);
|
||||||
CURLcode Curl_close(struct SessionHandle *data); /* the opposite of curl_open() */
|
CURLcode Curl_close(struct SessionHandle *data); /* opposite of curl_open() */
|
||||||
CURLcode Curl_connect(struct SessionHandle *,
|
CURLcode Curl_connect(struct SessionHandle *, struct connectdata **);
|
||||||
struct connectdata **,
|
CURLcode Curl_do(struct connectdata **);
|
||||||
bool allow_port);
|
|
||||||
CURLcode Curl_do(struct connectdata *);
|
|
||||||
CURLcode Curl_done(struct connectdata *);
|
CURLcode Curl_done(struct connectdata *);
|
||||||
CURLcode Curl_disconnect(struct connectdata *);
|
CURLcode Curl_disconnect(struct connectdata *);
|
||||||
|
|
||||||
|
@ -211,6 +211,57 @@ struct ConnectBits {
|
|||||||
complete */
|
complete */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/*
|
||||||
|
* This struct is all the previously local variables from Curl_perform() moved
|
||||||
|
* to struct to allow the function to return and get re-invoked better without
|
||||||
|
* losing state.
|
||||||
|
*/
|
||||||
|
|
||||||
|
struct Curl_transfer_keeper {
|
||||||
|
int bytecount; /* total number of bytes read */
|
||||||
|
int writebytecount; /* number of bytes written */
|
||||||
|
long contentlength; /* size of incoming data */
|
||||||
|
struct timeval start; /* transfer started at this time */
|
||||||
|
struct timeval now; /* current time */
|
||||||
|
bool header; /* incoming data has HTTP header */
|
||||||
|
int headerline; /* counts header lines to better track the
|
||||||
|
first one */
|
||||||
|
char *hbufp; /* points at *end* of header line */
|
||||||
|
int hbuflen;
|
||||||
|
char *str; /* within buf */
|
||||||
|
char *str_start; /* within buf */
|
||||||
|
char *end_ptr; /* within buf */
|
||||||
|
char *p; /* within headerbuff */
|
||||||
|
bool content_range; /* set TRUE if Content-Range: was found */
|
||||||
|
int offset; /* possible resume offset read from the
|
||||||
|
Content-Range: header */
|
||||||
|
int httpcode; /* error code from the 'HTTP/1.? XXX' line */
|
||||||
|
int httpversion; /* the HTTP version*10 */
|
||||||
|
bool write_after_100_header; /* should we enable the write after
|
||||||
|
we received a 100-continue/timeout
|
||||||
|
or directly */
|
||||||
|
|
||||||
|
/* for the low speed checks: */
|
||||||
|
time_t timeofdoc;
|
||||||
|
long bodywrites;
|
||||||
|
int writetype;
|
||||||
|
|
||||||
|
/* the highest fd we use + 1 */
|
||||||
|
struct SessionHandle *data;
|
||||||
|
struct connectdata *conn;
|
||||||
|
char *buf;
|
||||||
|
int maxfd;
|
||||||
|
|
||||||
|
/* the file descriptors to play with */
|
||||||
|
fd_set readfd;
|
||||||
|
fd_set writefd;
|
||||||
|
fd_set rkeepfd;
|
||||||
|
fd_set wkeepfd;
|
||||||
|
int keepon;
|
||||||
|
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The connectdata struct contains all fields and variables that should be
|
* The connectdata struct contains all fields and variables that should be
|
||||||
* unique for an entire connection.
|
* unique for an entire connection.
|
||||||
@ -355,6 +406,8 @@ struct connectdata {
|
|||||||
void *generic;
|
void *generic;
|
||||||
} proto;
|
} proto;
|
||||||
|
|
||||||
|
/* This struct is inited when needed */
|
||||||
|
struct Curl_transfer_keeper keep;
|
||||||
};
|
};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -460,6 +513,13 @@ struct UrlState {
|
|||||||
bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
|
bool errorbuf; /* Set to TRUE if the error buffer is already filled in.
|
||||||
This must be set to FALSE every time _easy_perform() is
|
This must be set to FALSE every time _easy_perform() is
|
||||||
called. */
|
called. */
|
||||||
|
|
||||||
|
#ifdef HAVE_SIGNAL
|
||||||
|
/* storage for the previous bag^H^H^HSIGPIPE signal handler :-) */
|
||||||
|
void (*prev_signal)(int sig);
|
||||||
|
#endif
|
||||||
|
bool allow_port; /* Is set.use_port allowed to take effect or not. This
|
||||||
|
is always set TRUE when curl_easy_perform() is called. */
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
@ -569,7 +629,6 @@ struct UserDefined {
|
|||||||
bool hide_progress;
|
bool hide_progress;
|
||||||
bool http_fail_on_error;
|
bool http_fail_on_error;
|
||||||
bool http_follow_location;
|
bool http_follow_location;
|
||||||
|
|
||||||
bool include_header;
|
bool include_header;
|
||||||
#define http_include_header include_header /* former name */
|
#define http_include_header include_header /* former name */
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user