mirror of
https://github.com/moparisthebest/curl
synced 2024-12-21 15:48:49 -05:00
Added per-protocol callback static tables, replacing callback ptr storage
in the connectdata structure by a single handler table ptr.
This commit is contained in:
parent
2741f97a69
commit
07b6e7363d
4
CHANGES
4
CHANGES
@ -6,6 +6,10 @@
|
||||
|
||||
Changelog
|
||||
|
||||
Patrick M (12 October 2007)
|
||||
- Added per-protocol callback static tables, replacing callback ptr storage
|
||||
in the connectdata structure by a single handler table ptr.
|
||||
|
||||
Dan F (11 October 2007)
|
||||
- Fixed the -l option of runtests.pl
|
||||
|
||||
|
@ -24,6 +24,11 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
CURLcode Curl_ldap(struct connectdata *conn, bool *done);
|
||||
extern const struct Curl_handler Curl_handler_ldap;
|
||||
|
||||
#ifdef HAVE_LDAP_SSL
|
||||
extern const struct Curl_handler Curl_handler_ldaps;
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* __CURL_LDAP_H */
|
||||
|
29
lib/dict.c
29
lib/dict.c
@ -82,6 +82,33 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode Curl_dict(struct connectdata *conn, bool *done);
|
||||
|
||||
/*
|
||||
* DICT protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_dict = {
|
||||
"DICT", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_dict, /* do_it */
|
||||
NULL, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_DICT, /* defport */
|
||||
PROT_DICT /* protocol */
|
||||
};
|
||||
|
||||
static char *unescape_word(struct SessionHandle *data, const char *inp)
|
||||
{
|
||||
char *newp;
|
||||
@ -115,7 +142,7 @@ static char *unescape_word(struct SessionHandle *data, const char *inp)
|
||||
return dictp;
|
||||
}
|
||||
|
||||
CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_dict(struct connectdata *conn, bool *done)
|
||||
{
|
||||
char *word;
|
||||
char *eword;
|
||||
|
@ -24,7 +24,6 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_DICT
|
||||
CURLcode Curl_dict(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_dict_done(struct connectdata *conn);
|
||||
extern const struct Curl_handler Curl_handler_dict;
|
||||
#endif
|
||||
#endif
|
||||
|
29
lib/file.c
29
lib/file.c
@ -89,6 +89,33 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode Curl_file(struct connectdata *, bool *done);
|
||||
|
||||
/*
|
||||
* FILE scheme handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_file = {
|
||||
"FILE", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_file, /* do_it */
|
||||
Curl_file_done, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
0, /* defport */
|
||||
PROT_FILE /* protocol */
|
||||
};
|
||||
|
||||
/*
|
||||
* Curl_file_connect() gets called from Curl_protocol_connect() to allow us to
|
||||
* do protocol-specific actions at connect-time. We emulate a
|
||||
@ -316,7 +343,7 @@ static CURLcode file_upload(struct connectdata *conn)
|
||||
* opposed to sockets) we instead perform the whole do-operation in this
|
||||
* function.
|
||||
*/
|
||||
CURLcode Curl_file(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_file(struct connectdata *conn, bool *done)
|
||||
{
|
||||
/* This implementation ignores the host name in conformance with
|
||||
RFC 1738. Only local files (reachable via the standard file system)
|
||||
|
@ -24,7 +24,8 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
CURLcode Curl_file(struct connectdata *, bool *done);
|
||||
extern const struct Curl_handler Curl_handler_file;
|
||||
|
||||
CURLcode Curl_file_done(struct connectdata *, CURLcode, bool premature);
|
||||
CURLcode Curl_file_connect(struct connectdata *);
|
||||
#endif
|
||||
|
191
lib/ftp.c
191
lib/ftp.c
@ -133,6 +133,20 @@ static CURLcode ftp_nb_type(struct connectdata *conn,
|
||||
bool ascii, ftpstate newstate);
|
||||
static int ftp_need_type(struct connectdata *conn,
|
||||
bool ascii);
|
||||
static CURLcode Curl_ftp(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_ftp_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_ftp_disconnect(struct connectdata *conn);
|
||||
static CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
||||
static CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
|
||||
static int Curl_ftp_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
static CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
static CURLcode Curl_ftp_setup_connection(struct connectdata * conn);
|
||||
static CURLcode Curl_ftps_setup_connection(struct connectdata * conn);
|
||||
|
||||
/* easy-to-use macro: */
|
||||
#define FTPSENDF(x,y,z) if ((result = Curl_ftpsendf(x,y,z)) != CURLE_OK) \
|
||||
@ -141,6 +155,95 @@ static int ftp_need_type(struct connectdata *conn,
|
||||
return result
|
||||
|
||||
|
||||
/*
|
||||
* FTP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ftp = {
|
||||
"FTP", /* scheme */
|
||||
Curl_ftp_setup_connection, /* setup_connection */
|
||||
Curl_ftp, /* do_it */
|
||||
Curl_ftp_done, /* done */
|
||||
Curl_ftp_nextconnect, /* do_more */
|
||||
Curl_ftp_connect, /* connect_it */
|
||||
Curl_ftp_multi_statemach, /* connecting */
|
||||
Curl_ftp_doing, /* doing */
|
||||
Curl_ftp_getsock, /* proto_getsock */
|
||||
Curl_ftp_getsock, /* doing_getsock */
|
||||
Curl_ftp_disconnect, /* disconnect */
|
||||
PORT_FTP, /* defport */
|
||||
PROT_FTP /* protocol */
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* FTPS protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ftps = {
|
||||
"FTPS", /* scheme */
|
||||
Curl_ftps_setup_connection, /* setup_connection */
|
||||
Curl_ftp, /* do_it */
|
||||
Curl_ftp_done, /* done */
|
||||
Curl_ftp_nextconnect, /* do_more */
|
||||
Curl_ftp_connect, /* connect_it */
|
||||
Curl_ftp_multi_statemach, /* connecting */
|
||||
Curl_ftp_doing, /* doing */
|
||||
Curl_ftp_getsock, /* proto_getsock */
|
||||
Curl_ftp_getsock, /* doing_getsock */
|
||||
Curl_ftp_disconnect, /* disconnect */
|
||||
PORT_FTPS, /* defport */
|
||||
PROT_FTP | PROT_FTPS | PROT_SSL /* protocol */
|
||||
};
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
/*
|
||||
* HTTP-proxyed FTP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ftp_proxy = {
|
||||
"FTP", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_FTP, /* defport */
|
||||
PROT_HTTP /* protocol */
|
||||
};
|
||||
|
||||
|
||||
# ifdef USE_SSL
|
||||
/*
|
||||
* HTTP-proxyed FTPS protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ftps_proxy = {
|
||||
"FTPS", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_FTPS, /* defport */
|
||||
PROT_HTTP /* protocol */
|
||||
};
|
||||
# endif
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* NOTE: back in the old days, we added code in the FTP code that made NOBODY
|
||||
* requests on files respond with headers passed to the client/stdout that
|
||||
@ -706,9 +809,9 @@ static CURLcode ftp_state_pwd(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* For the FTP "protocol connect" and "doing" phases only */
|
||||
int Curl_ftp_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
static int Curl_ftp_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
struct ftp_conn *ftpc = &conn->proto.ftpc;
|
||||
|
||||
@ -2819,8 +2922,8 @@ static long ftp_state_timeout(struct connectdata *conn)
|
||||
|
||||
|
||||
/* called repeatedly until done from multi.c */
|
||||
CURLcode Curl_ftp_multi_statemach(struct connectdata *conn,
|
||||
bool *done)
|
||||
static CURLcode Curl_ftp_multi_statemach(struct connectdata *conn,
|
||||
bool *done)
|
||||
{
|
||||
curl_socket_t sock = conn->sock[FIRSTSOCKET];
|
||||
int rc;
|
||||
@ -2928,8 +3031,8 @@ static CURLcode ftp_init(struct connectdata *conn)
|
||||
* phase is done when this function returns, or FALSE is not. When called as
|
||||
* a part of the easy interface, it will always be TRUE.
|
||||
*/
|
||||
CURLcode Curl_ftp_connect(struct connectdata *conn,
|
||||
bool *done) /* see description above */
|
||||
static CURLcode Curl_ftp_connect(struct connectdata *conn,
|
||||
bool *done) /* see description above */
|
||||
{
|
||||
CURLcode result;
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
@ -3017,8 +3120,8 @@ CURLcode Curl_ftp_connect(struct connectdata *conn,
|
||||
*
|
||||
* Input argument is already checked for validity.
|
||||
*/
|
||||
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
static CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
struct FTP *ftp = data->reqdata.proto.ftp;
|
||||
@ -3368,7 +3471,7 @@ static CURLcode ftp_range(struct connectdata *conn)
|
||||
* connected.
|
||||
*/
|
||||
|
||||
CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
static CURLcode Curl_ftp_nextconnect(struct connectdata *conn)
|
||||
{
|
||||
struct SessionHandle *data=conn->data;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -3485,7 +3588,7 @@ CURLcode ftp_perform(struct connectdata *conn,
|
||||
*
|
||||
* The input argument is already checked for validity.
|
||||
*/
|
||||
CURLcode Curl_ftp(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_ftp(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode retcode = CURLE_OK;
|
||||
|
||||
@ -3682,7 +3785,7 @@ static CURLcode ftp_quit(struct connectdata *conn)
|
||||
* Disconnect from an FTP server. Cleanup protocol-specific per-connection
|
||||
* resources. BLOCKING.
|
||||
*/
|
||||
CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
static CURLcode Curl_ftp_disconnect(struct connectdata *conn)
|
||||
{
|
||||
struct ftp_conn *ftpc= &conn->proto.ftpc;
|
||||
|
||||
@ -3933,8 +4036,8 @@ static CURLcode ftp_dophase_done(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
static CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
result = Curl_ftp_multi_statemach(conn, dophase_done);
|
||||
@ -3996,4 +4099,64 @@ CURLcode ftp_regular_transfer(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
static CURLcode Curl_ftp_setup_connection(struct connectdata * conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
char * type;
|
||||
char command;
|
||||
|
||||
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
|
||||
/* Unless we have asked to tunnel ftp operations through the proxy, we
|
||||
switch and use HTTP operations only */
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
if (conn->handler == &Curl_handler_ftp)
|
||||
conn->handler = &Curl_handler_ftp_proxy;
|
||||
else
|
||||
conn->handler = &Curl_handler_ftps_proxy;
|
||||
#else
|
||||
failf(data, "FTP over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
data->reqdata.path++; /* don't include the initial slash */
|
||||
|
||||
/* FTP URLs support an extension like ";type=<typecode>" that
|
||||
* we'll try to get now! */
|
||||
type = strstr(data->reqdata.path, ";type=");
|
||||
|
||||
if (!type)
|
||||
type = strstr(conn->host.rawalloc, ";type=");
|
||||
|
||||
if (type) {
|
||||
*type = 0; /* it was in the middle of the hostname */
|
||||
command = (char) toupper((int) type[6]);
|
||||
|
||||
switch (command) {
|
||||
case 'A': /* ASCII mode */
|
||||
data->set.prefer_ascii = TRUE;
|
||||
break;
|
||||
|
||||
case 'D': /* directory mode */
|
||||
data->set.ftp_list_only = TRUE;
|
||||
break;
|
||||
|
||||
case 'I': /* binary mode */
|
||||
default:
|
||||
/* switch off ASCII */
|
||||
data->set.prefer_ascii = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
static CURLcode Curl_ftps_setup_connection(struct connectdata * conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
||||
conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLUSESSL_CONTROL;
|
||||
return Curl_ftp_setup_connection(conn);
|
||||
}
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
|
25
lib/ftp.h
25
lib/ftp.h
@ -24,20 +24,23 @@
|
||||
***************************************************************************/
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
CURLcode Curl_ftp(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_ftp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
CURLcode Curl_ftp_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_ftp_disconnect(struct connectdata *conn);
|
||||
extern const struct Curl_handler Curl_handler_ftp;
|
||||
|
||||
#ifdef USE_SSL
|
||||
extern const struct Curl_handler Curl_handler_ftps;
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
extern const struct Curl_handler Curl_handler_ftp_proxy;
|
||||
|
||||
# ifdef USE_SSL
|
||||
extern const struct Curl_handler Curl_handler_ftps_proxy;
|
||||
# endif
|
||||
#endif
|
||||
|
||||
CURLcode Curl_ftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
CURLcode Curl_nbftpsendf(struct connectdata *, const char *fmt, ...);
|
||||
CURLcode Curl_GetFTPResponse(ssize_t *nread, struct connectdata *conn,
|
||||
int *ftpcode);
|
||||
CURLcode Curl_ftp_nextconnect(struct connectdata *conn);
|
||||
CURLcode Curl_ftp_multi_statemach(struct connectdata *conn, bool *done);
|
||||
int Curl_ftp_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
CURLcode Curl_ftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
#endif /* CURL_DISABLE_FTP */
|
||||
#endif /* __FTP_H */
|
||||
|
59
lib/http.c
59
lib/http.c
@ -104,6 +104,57 @@
|
||||
/* The last #include file should be: */
|
||||
#include "memdebug.h"
|
||||
|
||||
|
||||
/*
|
||||
* Forward declarations.
|
||||
*/
|
||||
|
||||
static CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
|
||||
static int Curl_https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/*
|
||||
* HTTP handler interface.
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_http = {
|
||||
"HTTP", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
NULL, /* do_more */
|
||||
Curl_http_connect, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_HTTP, /* defport */
|
||||
PROT_HTTP, /* protocol */
|
||||
};
|
||||
|
||||
#ifdef USE_SSL
|
||||
/*
|
||||
* HTTPS handler interface.
|
||||
*/
|
||||
const struct Curl_handler Curl_handler_https = {
|
||||
"HTTPS", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_http, /* do_it */
|
||||
Curl_http_done, /* done */
|
||||
NULL, /* do_more */
|
||||
Curl_http_connect, /* connect_it */
|
||||
Curl_https_connecting, /* connecting */
|
||||
NULL, /* doing */
|
||||
Curl_https_getsock, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_HTTPS, /* defport */
|
||||
PROT_HTTP | PROT_HTTPS | PROT_SSL /* protocol */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* checkheaders() checks the linked list of custom HTTP headers for a
|
||||
* particular header (prefix).
|
||||
@ -1619,7 +1670,7 @@ CURLcode Curl_http_connect(struct connectdata *conn, bool *done)
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_https_connecting(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_https_connecting(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode result;
|
||||
DEBUGASSERT((conn) && (conn->protocol & PROT_HTTPS));
|
||||
@ -1635,9 +1686,9 @@ CURLcode Curl_https_connecting(struct connectdata *conn, bool *done)
|
||||
#ifdef USE_SSLEAY
|
||||
/* This function is OpenSSL-specific. It should be made to query the generic
|
||||
SSL layer instead. */
|
||||
int Curl_https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
static int Curl_https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if (conn->protocol & PROT_HTTPS) {
|
||||
struct ssl_connect_data *connssl = &conn->ssl[FIRSTSOCKET];
|
||||
|
11
lib/http.h
11
lib/http.h
@ -24,6 +24,13 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
|
||||
extern const struct Curl_handler Curl_handler_http;
|
||||
|
||||
#ifdef USE_SSL
|
||||
extern const struct Curl_handler Curl_handler_https;
|
||||
#endif
|
||||
|
||||
bool Curl_compareheader(const char *headerline, /* line to check */
|
||||
const char *header, /* header keyword _with_ colon */
|
||||
const char *content); /* content string to find */
|
||||
@ -37,10 +44,6 @@ CURLcode Curl_proxyCONNECT(struct connectdata *conn,
|
||||
CURLcode Curl_http(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_http_done(struct connectdata *, CURLcode, bool premature);
|
||||
CURLcode Curl_http_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_https_connecting(struct connectdata *conn, bool *done);
|
||||
int Curl_https_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* The following functions are defined in http_chunks.c */
|
||||
void Curl_httpchunk_init(struct connectdata *conn);
|
||||
|
47
lib/ldap.c
47
lib/ldap.c
@ -118,7 +118,52 @@ static void _ldap_free_urldesc (LDAPURLDesc *ludp);
|
||||
#endif
|
||||
|
||||
|
||||
CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_ldap(struct connectdata *conn, bool *done);
|
||||
|
||||
/*
|
||||
* LDAP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ldap = {
|
||||
"LDAP", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_ldap, /* do_it */
|
||||
NULL, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_LDAP, /* defport */
|
||||
PROT_LDAP /* protocol */
|
||||
};
|
||||
|
||||
#ifdef HAVE_LDAP_SSL
|
||||
/*
|
||||
* LDAPS protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_ldaps = {
|
||||
"LDAPS", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_ldap, /* do_it */
|
||||
NULL, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_LDAPS, /* defport */
|
||||
PROT_LDAP | PROT_SSL /* protocol */
|
||||
};
|
||||
#endif
|
||||
|
||||
|
||||
static CURLcode Curl_ldap(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode status = CURLE_OK;
|
||||
int rc = 0;
|
||||
|
82
lib/ssh.c
82
lib/ssh.c
@ -134,6 +134,63 @@ static LIBSSH2_FREE_FUNC(libssh2_free);
|
||||
|
||||
static int get_pathname(const char **cpp, char **path);
|
||||
|
||||
static CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_ssh_multi_statemach(struct connectdata *conn, bool *done);
|
||||
|
||||
static CURLcode Curl_scp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_scp_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode Curl_scp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
|
||||
static CURLcode Curl_sftp_do(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_sftp_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode Curl_sftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
|
||||
/*
|
||||
* SCP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_scp = {
|
||||
"SCP", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_scp_do, /* do_it */
|
||||
Curl_scp_done, /* done */
|
||||
NULL, /* do_more */
|
||||
Curl_ssh_connect, /* connect_it */
|
||||
Curl_ssh_multi_statemach, /* connecting */
|
||||
Curl_scp_doing, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_SSH, /* defport */
|
||||
PROT_SCP /* protocol */
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* SFTP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_sftp = {
|
||||
"SFTP", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_sftp_do, /* do_it */
|
||||
Curl_sftp_done, /* done */
|
||||
NULL, /* do_more */
|
||||
Curl_ssh_connect, /* connect_it */
|
||||
Curl_ssh_multi_statemach, /* connecting */
|
||||
Curl_sftp_doing, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_SSH, /* defport */
|
||||
PROT_SFTP /* protocol */
|
||||
};
|
||||
|
||||
|
||||
static void
|
||||
kbd_callback(const char *name, int name_len, const char *instruction,
|
||||
int instruction_len, int num_prompts,
|
||||
@ -1719,8 +1776,7 @@ static CURLcode ssh_statemach_act(struct connectdata *conn)
|
||||
}
|
||||
|
||||
/* called repeatedly until done from multi.c */
|
||||
CURLcode Curl_ssh_multi_statemach(struct connectdata *conn,
|
||||
bool *done)
|
||||
static CURLcode Curl_ssh_multi_statemach(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct ssh_conn *sshc = &conn->proto.sshc;
|
||||
CURLcode result = CURLE_OK;
|
||||
@ -1783,7 +1839,7 @@ static CURLcode ssh_init(struct connectdata *conn)
|
||||
* Curl_ssh_connect() gets called from Curl_protocol_connect() to allow us to
|
||||
* do protocol-specific actions at connect-time.
|
||||
*/
|
||||
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SSHPROTO *ssh;
|
||||
curl_socket_t sock;
|
||||
@ -1878,8 +1934,8 @@ CURLcode scp_perform(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
CURLcode Curl_scp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
static CURLcode Curl_scp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
result = Curl_ssh_multi_statemach(conn, dophase_done);
|
||||
@ -1891,7 +1947,7 @@ CURLcode Curl_scp_doing(struct connectdata *conn,
|
||||
}
|
||||
|
||||
|
||||
CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode res;
|
||||
bool connected = 0;
|
||||
@ -1931,8 +1987,8 @@ CURLcode Curl_scp_do(struct connectdata *conn, bool *done)
|
||||
return res;
|
||||
}
|
||||
|
||||
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
static CURLcode Curl_scp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
bool done = FALSE;
|
||||
@ -2048,8 +2104,8 @@ CURLcode sftp_perform(struct connectdata *conn,
|
||||
}
|
||||
|
||||
/* called from multi.c while DOing */
|
||||
CURLcode Curl_sftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
static CURLcode Curl_sftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done)
|
||||
{
|
||||
CURLcode result;
|
||||
result = Curl_ssh_multi_statemach(conn, dophase_done);
|
||||
@ -2060,7 +2116,7 @@ CURLcode Curl_sftp_doing(struct connectdata *conn,
|
||||
return result;
|
||||
}
|
||||
|
||||
CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode res;
|
||||
bool connected = 0;
|
||||
@ -2100,8 +2156,8 @@ CURLcode Curl_sftp_do(struct connectdata *conn, bool *done)
|
||||
return res;
|
||||
}
|
||||
|
||||
CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
static CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
CURLcode result = CURLE_OK;
|
||||
bool done = FALSE;
|
||||
|
14
lib/ssh.h
14
lib/ssh.h
@ -25,28 +25,18 @@
|
||||
***************************************************************************/
|
||||
|
||||
#ifdef USE_LIBSSH2
|
||||
|
||||
CURLcode Curl_ssh_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_ssh_multi_statemach(struct connectdata *conn, bool *done);
|
||||
|
||||
CURLcode Curl_scp_do(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_scp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
extern const struct Curl_handler Curl_handler_scp;
|
||||
extern const struct Curl_handler Curl_handler_sftp;
|
||||
|
||||
ssize_t Curl_scp_send(struct connectdata *conn, int sockindex,
|
||||
void *mem, size_t len);
|
||||
ssize_t Curl_scp_recv(struct connectdata *conn, int sockindex,
|
||||
char *mem, size_t len);
|
||||
CURLcode Curl_sftp_do(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_sftp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
|
||||
ssize_t Curl_sftp_send(struct connectdata *conn, int sockindex,
|
||||
void *mem, size_t len);
|
||||
ssize_t Curl_sftp_recv(struct connectdata *conn, int sockindex,
|
||||
char *mem, size_t len);
|
||||
CURLcode Curl_sftp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
CURLcode Curl_scp_doing(struct connectdata *conn,
|
||||
bool *dophase_done);
|
||||
|
||||
#endif /* USE_LIBSSH2 */
|
||||
|
||||
|
31
lib/telnet.c
31
lib/telnet.c
@ -125,6 +125,10 @@ static void printsub(struct SessionHandle *data,
|
||||
size_t length);
|
||||
static void suboption(struct connectdata *);
|
||||
|
||||
static CURLcode Curl_telnet(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_telnet_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
|
||||
/* For negotiation compliant to RFC 1143 */
|
||||
#define CURL_NO 0
|
||||
#define CURL_YES 1
|
||||
@ -170,6 +174,28 @@ struct TELNET {
|
||||
TelnetReceive telrcv_state;
|
||||
};
|
||||
|
||||
|
||||
/*
|
||||
* TELNET protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_telnet = {
|
||||
"TELNET", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
Curl_telnet, /* do_it */
|
||||
Curl_telnet_done, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_TELNET, /* defport */
|
||||
PROT_TELNET /* protocol */
|
||||
};
|
||||
|
||||
|
||||
#ifdef USE_WINSOCK
|
||||
static CURLcode
|
||||
check_wsock2 ( struct SessionHandle *data )
|
||||
@ -1074,7 +1100,8 @@ void telrcv(struct connectdata *conn,
|
||||
}
|
||||
}
|
||||
|
||||
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premature)
|
||||
static CURLcode Curl_telnet_done(struct connectdata *conn,
|
||||
CURLcode status, bool premature)
|
||||
{
|
||||
struct TELNET *tn = (struct TELNET *)conn->data->reqdata.proto.telnet;
|
||||
(void)status; /* unused */
|
||||
@ -1088,7 +1115,7 @@ CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode status, bool premat
|
||||
return CURLE_OK;
|
||||
}
|
||||
|
||||
CURLcode Curl_telnet(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_telnet(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode code;
|
||||
struct SessionHandle *data = conn->data;
|
||||
|
@ -24,7 +24,6 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
CURLcode Curl_telnet(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_telnet_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
extern const struct Curl_handler Curl_handler_telnet;
|
||||
#endif
|
||||
#endif
|
||||
|
72
lib/tftp.c
72
lib/tftp.c
@ -151,6 +151,33 @@ typedef struct tftp_state_data {
|
||||
/* Forward declarations */
|
||||
static CURLcode tftp_rx(tftp_state_data_t *state, tftp_event_t event) ;
|
||||
static CURLcode tftp_tx(tftp_state_data_t *state, tftp_event_t event) ;
|
||||
static CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_tftp(struct connectdata *conn, bool *done);
|
||||
static CURLcode Curl_tftp_done(struct connectdata *conn,
|
||||
CURLcode, bool premature);
|
||||
static CURLcode Curl_tftp_setup_connection(struct connectdata * conn);
|
||||
|
||||
|
||||
/*
|
||||
* TFTP protocol handler.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_tftp = {
|
||||
"TFTP", /* scheme */
|
||||
Curl_tftp_setup_connection, /* setup_connection */
|
||||
Curl_tftp, /* do_it */
|
||||
Curl_tftp_done, /* done */
|
||||
NULL, /* do_more */
|
||||
Curl_tftp_connect, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
PORT_TFTP, /* defport */
|
||||
PROT_TFTP /* protocol */
|
||||
};
|
||||
|
||||
|
||||
/**********************************************************
|
||||
*
|
||||
@ -575,7 +602,7 @@ static CURLcode tftp_state_machine(tftp_state_data_t *state,
|
||||
* The connect callback
|
||||
*
|
||||
**********************************************************/
|
||||
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode code;
|
||||
tftp_state_data_t *state;
|
||||
@ -636,8 +663,8 @@ CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done)
|
||||
* The done callback
|
||||
*
|
||||
**********************************************************/
|
||||
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
static CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status,
|
||||
bool premature)
|
||||
{
|
||||
(void)status; /* unused */
|
||||
(void)premature; /* not used */
|
||||
@ -662,7 +689,7 @@ CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode status,
|
||||
*
|
||||
**********************************************************/
|
||||
|
||||
CURLcode Curl_tftp(struct connectdata *conn, bool *done)
|
||||
static CURLcode Curl_tftp(struct connectdata *conn, bool *done)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
tftp_state_data_t *state =
|
||||
@ -836,4 +863,41 @@ CURLcode Curl_tftp(struct connectdata *conn, bool *done)
|
||||
code = CURLE_OK;
|
||||
return code;
|
||||
}
|
||||
|
||||
static CURLcode Curl_tftp_setup_connection(struct connectdata * conn)
|
||||
{
|
||||
struct SessionHandle *data = conn->data;
|
||||
char * type;
|
||||
char command;
|
||||
|
||||
conn->socktype = SOCK_DGRAM; /* UDP datagram based */
|
||||
|
||||
/* TFTP URLs support an extension like ";mode=<typecode>" that
|
||||
* we'll try to get now! */
|
||||
type = strstr(data->reqdata.path, ";mode=");
|
||||
|
||||
if (!type)
|
||||
type = strstr(conn->host.rawalloc, ";mode=");
|
||||
|
||||
if (type) {
|
||||
*type = 0; /* it was in the middle of the hostname */
|
||||
command = (char) toupper((int) type[6]);
|
||||
|
||||
switch (command) {
|
||||
case 'A': /* ASCII mode */
|
||||
case 'N': /* NETASCII mode */
|
||||
data->set.prefer_ascii = TRUE;
|
||||
break;
|
||||
|
||||
case 'O': /* octet mode */
|
||||
case 'I': /* binary mode */
|
||||
default:
|
||||
/* switch off ASCII */
|
||||
data->set.prefer_ascii = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return CURLE_OK;
|
||||
}
|
||||
#endif
|
||||
|
@ -24,8 +24,6 @@
|
||||
* $Id$
|
||||
***************************************************************************/
|
||||
#ifndef CURL_DISABLE_TFTP
|
||||
CURLcode Curl_tftp_connect(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_tftp(struct connectdata *conn, bool *done);
|
||||
CURLcode Curl_tftp_done(struct connectdata *conn, CURLcode, bool premature);
|
||||
extern const struct Curl_handler Curl_handler_tftp;
|
||||
#endif
|
||||
#endif
|
||||
|
411
lib/url.c
411
lib/url.c
@ -178,6 +178,7 @@ static void flush_cookies(struct SessionHandle *data, int cleanup);
|
||||
|
||||
#define ZERO_NULL 0
|
||||
|
||||
|
||||
#ifndef USE_ARES
|
||||
/* not for ares builds */
|
||||
|
||||
@ -188,6 +189,82 @@ static void flush_cookies(struct SessionHandle *data, int cleanup);
|
||||
extern sigjmp_buf curl_jmpenv;
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* Protocol table.
|
||||
*/
|
||||
|
||||
static const struct Curl_handler * protocols[] = {
|
||||
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
&Curl_handler_http,
|
||||
#endif
|
||||
|
||||
#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
|
||||
&Curl_handler_https,
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
&Curl_handler_ftp,
|
||||
#endif
|
||||
|
||||
#if defined(USE_SSL) && !defined(CURL_DISABLE_FTP)
|
||||
&Curl_handler_ftps,
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
&Curl_handler_telnet,
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_DICT
|
||||
&Curl_handler_dict,
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
&Curl_handler_ldap,
|
||||
#endif
|
||||
|
||||
#if defined(HAVE_LDAP_SSL) && !defined(CURL_DISABLE_SSL)
|
||||
&Curl_handler_ldaps,
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
&Curl_handler_file,
|
||||
#endif
|
||||
|
||||
#ifndef CURL_DISABLE_TFTP
|
||||
&Curl_handler_tftp,
|
||||
#endif
|
||||
|
||||
#ifdef USE_LIBSSH2
|
||||
&Curl_handler_scp,
|
||||
&Curl_handler_sftp,
|
||||
#endif
|
||||
|
||||
(struct Curl_handler *) NULL
|
||||
};
|
||||
|
||||
/*
|
||||
* Dummy handler for undefined protocol schemes.
|
||||
*/
|
||||
|
||||
const struct Curl_handler Curl_handler_dummy = {
|
||||
"<no protocol>", /* scheme */
|
||||
NULL, /* setup_connection */
|
||||
NULL, /* do_it */
|
||||
NULL, /* done */
|
||||
NULL, /* do_more */
|
||||
NULL, /* connect_it */
|
||||
NULL, /* connecting */
|
||||
NULL, /* doing */
|
||||
NULL, /* proto_getsock */
|
||||
NULL, /* doing_getsock */
|
||||
NULL, /* disconnect */
|
||||
0, /* defport */
|
||||
0 /* protocol */
|
||||
};
|
||||
|
||||
|
||||
#ifdef SIGALRM
|
||||
static
|
||||
RETSIGTYPE alarmfunc(int sig)
|
||||
@ -1999,9 +2076,9 @@ CURLcode Curl_disconnect(struct connectdata *conn)
|
||||
Curl_ntlm_cleanup(conn);
|
||||
}
|
||||
|
||||
if(conn->curl_disconnect)
|
||||
if(conn->handler->disconnect)
|
||||
/* This is set if protocol-specific cleanups should be made */
|
||||
conn->curl_disconnect(conn);
|
||||
conn->handler->disconnect(conn);
|
||||
|
||||
if(-1 != conn->connectindex) {
|
||||
/* unlink ourselves! */
|
||||
@ -2519,8 +2596,8 @@ int Curl_protocol_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if(conn->curl_proto_getsock)
|
||||
return conn->curl_proto_getsock(conn, socks, numsocks);
|
||||
if(conn->handler->proto_getsock)
|
||||
return conn->handler->proto_getsock(conn, socks, numsocks);
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
|
||||
@ -2528,8 +2605,8 @@ int Curl_doing_getsock(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks)
|
||||
{
|
||||
if(conn && conn->curl_doing_getsock)
|
||||
return conn->curl_doing_getsock(conn, socks, numsocks);
|
||||
if(conn && conn->handler && conn->handler->doing_getsock)
|
||||
return conn->handler->doing_getsock(conn, socks, numsocks);
|
||||
return GETSOCK_BLANK;
|
||||
}
|
||||
|
||||
@ -2544,9 +2621,9 @@ CURLcode Curl_protocol_connecting(struct connectdata *conn,
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
|
||||
if(conn && conn->curl_connecting) {
|
||||
if(conn && conn->handler && conn->handler->connecting) {
|
||||
*done = FALSE;
|
||||
result = conn->curl_connecting(conn, done);
|
||||
result = conn->handler->connecting(conn, done);
|
||||
}
|
||||
else
|
||||
*done = TRUE;
|
||||
@ -2563,9 +2640,9 @@ CURLcode Curl_protocol_doing(struct connectdata *conn, bool *done)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
|
||||
if(conn && conn->curl_doing) {
|
||||
if(conn && conn->handler && conn->handler->doing) {
|
||||
*done = FALSE;
|
||||
result = conn->curl_doing(conn, done);
|
||||
result = conn->handler->doing(conn, done);
|
||||
}
|
||||
else
|
||||
*done = TRUE;
|
||||
@ -2593,7 +2670,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
|
||||
|
||||
Unless this protocol doesn't have any protocol-connect callback, as
|
||||
then we know we're done. */
|
||||
if(!conn->curl_connecting)
|
||||
if(!conn->handler->connecting)
|
||||
*protocol_done = TRUE;
|
||||
|
||||
return CURLE_OK;
|
||||
@ -2608,7 +2685,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
|
||||
}
|
||||
|
||||
if(!conn->bits.protoconnstart) {
|
||||
if(conn->curl_connect) {
|
||||
if(conn->handler->connect_it) {
|
||||
/* is there a protocol-specific connect() procedure? */
|
||||
|
||||
/* Set start time here for timeout purposes in the connect procedure, it
|
||||
@ -2616,7 +2693,7 @@ CURLcode Curl_protocol_connect(struct connectdata *conn,
|
||||
conn->now = Curl_tvnow();
|
||||
|
||||
/* Call the protocol-specific connect function */
|
||||
result = conn->curl_connect(conn, protocol_done);
|
||||
result = conn->handler->connect_it(conn, protocol_done);
|
||||
}
|
||||
else
|
||||
*protocol_done = TRUE;
|
||||
@ -2943,285 +3020,39 @@ static CURLcode setup_range(struct SessionHandle *data)
|
||||
static CURLcode setup_connection_internals(struct SessionHandle *data,
|
||||
struct connectdata *conn)
|
||||
{
|
||||
const struct Curl_handler * * pp;
|
||||
const struct Curl_handler * p;
|
||||
CURLcode result;
|
||||
|
||||
conn->socktype = SOCK_STREAM; /* most of them are TCP streams */
|
||||
|
||||
if (strequal(conn->protostr, "HTTP")) {
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
conn->port = PORT_HTTP;
|
||||
conn->remote_port = PORT_HTTP;
|
||||
conn->protocol |= PROT_HTTP;
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
|
||||
conn->curl_done = Curl_http_done;
|
||||
conn->curl_connect = Curl_http_connect;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with HTTP disabled, http: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
/* Scan protocol handler table. */
|
||||
|
||||
else if (strequal(conn->protostr, "HTTPS")) {
|
||||
#if defined(USE_SSL) && !defined(CURL_DISABLE_HTTP)
|
||||
for (pp = protocols; p = *pp; pp++)
|
||||
if (strequal(p->scheme, conn->protostr)) {
|
||||
/* Protocol found in table. Perform setup complement if some. */
|
||||
conn->handler = p;
|
||||
|
||||
conn->port = PORT_HTTPS;
|
||||
conn->remote_port = PORT_HTTPS;
|
||||
conn->protocol |= PROT_HTTP|PROT_HTTPS|PROT_SSL;
|
||||
if (p->setup_connection) {
|
||||
result = (*p->setup_connection)(conn);
|
||||
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
|
||||
conn->curl_done = Curl_http_done;
|
||||
conn->curl_connect = Curl_http_connect;
|
||||
conn->curl_connecting = Curl_https_connecting;
|
||||
conn->curl_proto_getsock = Curl_https_getsock;
|
||||
if (result != CURLE_OK)
|
||||
return result;
|
||||
|
||||
#else /* USE_SSL */
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with SSL disabled, https: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif /* !USE_SSL */
|
||||
}
|
||||
|
||||
else if(strequal(conn->protostr, "FTP") ||
|
||||
strequal(conn->protostr, "FTPS")) {
|
||||
|
||||
#ifndef CURL_DISABLE_FTP
|
||||
char *type;
|
||||
int port = PORT_FTP;
|
||||
|
||||
if(strequal(conn->protostr, "FTPS")) {
|
||||
#ifdef USE_SSL
|
||||
conn->protocol |= PROT_FTPS|PROT_SSL;
|
||||
/* send data securely unless specifically requested otherwise */
|
||||
conn->ssl[SECONDARYSOCKET].use = data->set.ftp_ssl != CURLUSESSL_CONTROL;
|
||||
port = PORT_FTPS;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with SSL disabled, ftps: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif /* !USE_SSL */
|
||||
}
|
||||
|
||||
conn->port = port;
|
||||
conn->remote_port = (unsigned short)port;
|
||||
conn->protocol |= PROT_FTP;
|
||||
|
||||
if(conn->bits.httpproxy && !data->set.tunnel_thru_httpproxy) {
|
||||
/* Unless we have asked to tunnel ftp operations through the proxy, we
|
||||
switch and use HTTP operations only */
|
||||
#ifndef CURL_DISABLE_HTTP
|
||||
conn->curl_do = Curl_http;
|
||||
conn->curl_done = Curl_http_done;
|
||||
conn->protocol = PROT_HTTP; /* switch to HTTP */
|
||||
#else
|
||||
failf(data, "FTP over http proxy requires HTTP support built-in!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
conn->curl_do = Curl_ftp;
|
||||
conn->curl_do_more = Curl_ftp_nextconnect;
|
||||
conn->curl_done = Curl_ftp_done;
|
||||
conn->curl_connect = Curl_ftp_connect;
|
||||
conn->curl_connecting = Curl_ftp_multi_statemach;
|
||||
conn->curl_doing = Curl_ftp_doing;
|
||||
conn->curl_proto_getsock = Curl_ftp_getsock;
|
||||
conn->curl_doing_getsock = Curl_ftp_getsock;
|
||||
conn->curl_disconnect = Curl_ftp_disconnect;
|
||||
}
|
||||
|
||||
data->reqdata.path++; /* don't include the initial slash */
|
||||
|
||||
/* FTP URLs support an extension like ";type=<typecode>" that
|
||||
* we'll try to get now! */
|
||||
type=strstr(data->reqdata.path, ";type=");
|
||||
if(!type) {
|
||||
type=strstr(conn->host.rawalloc, ";type=");
|
||||
}
|
||||
if(type) {
|
||||
char command;
|
||||
*type=0; /* it was in the middle of the hostname */
|
||||
command = (char)toupper((int)type[6]);
|
||||
switch(command) {
|
||||
case 'A': /* ASCII mode */
|
||||
data->set.prefer_ascii = TRUE;
|
||||
break;
|
||||
case 'D': /* directory mode */
|
||||
data->set.ftp_list_only = TRUE;
|
||||
break;
|
||||
case 'I': /* binary mode */
|
||||
default:
|
||||
/* switch off ASCII */
|
||||
data->set.prefer_ascii = FALSE;
|
||||
break;
|
||||
p = conn->handler; /* May have changed. */
|
||||
}
|
||||
|
||||
conn->port = p->defport;
|
||||
conn->remote_port = p->defport;
|
||||
conn->protocol |= p->protocol;
|
||||
return CURLE_OK;
|
||||
}
|
||||
#else /* CURL_DISABLE_FTP */
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with FTP disabled, ftp/ftps: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if(strequal(conn->protostr, "TELNET")) {
|
||||
#ifndef CURL_DISABLE_TELNET
|
||||
/* telnet testing factory */
|
||||
conn->protocol |= PROT_TELNET;
|
||||
|
||||
conn->port = PORT_TELNET;
|
||||
conn->remote_port = PORT_TELNET;
|
||||
conn->curl_do = Curl_telnet;
|
||||
conn->curl_done = Curl_telnet_done;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with TELNET disabled!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (strequal(conn->protostr, "DICT")) {
|
||||
#ifndef CURL_DISABLE_DICT
|
||||
conn->protocol |= PROT_DICT;
|
||||
conn->port = PORT_DICT;
|
||||
conn->remote_port = PORT_DICT;
|
||||
conn->curl_do = Curl_dict;
|
||||
/* no DICT-specific done */
|
||||
conn->curl_done = (Curl_done_func)ZERO_NULL;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with DICT disabled!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (strequal(conn->protostr, "LDAP")) {
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
conn->protocol |= PROT_LDAP;
|
||||
conn->port = PORT_LDAP;
|
||||
conn->remote_port = PORT_LDAP;
|
||||
conn->curl_do = Curl_ldap;
|
||||
/* no LDAP-specific done */
|
||||
conn->curl_done = (Curl_done_func)ZERO_NULL;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with LDAP disabled!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
#ifdef HAVE_LDAP_SSL
|
||||
else if (strequal(conn->protostr, "LDAPS")) {
|
||||
#ifndef CURL_DISABLE_LDAP
|
||||
conn->protocol |= PROT_LDAP|PROT_SSL;
|
||||
conn->port = PORT_LDAPS;
|
||||
conn->remote_port = PORT_LDAPS;
|
||||
conn->curl_do = Curl_ldap;
|
||||
/* no LDAP-specific done */
|
||||
conn->curl_done = (Curl_done_func)ZERO_NULL;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with LDAP disabled!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
#endif /* CURL_LDAP_USE_SSL */
|
||||
|
||||
else if (strequal(conn->protostr, "FILE")) {
|
||||
#ifndef CURL_DISABLE_FILE
|
||||
conn->protocol |= PROT_FILE;
|
||||
|
||||
conn->curl_do = Curl_file;
|
||||
conn->curl_done = Curl_file_done;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with FILE disabled!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (strequal(conn->protostr, "TFTP")) {
|
||||
#ifndef CURL_DISABLE_TFTP
|
||||
char *type;
|
||||
conn->socktype = SOCK_DGRAM; /* UDP datagram based */
|
||||
conn->protocol |= PROT_TFTP;
|
||||
conn->port = PORT_TFTP;
|
||||
conn->remote_port = PORT_TFTP;
|
||||
conn->curl_connect = Curl_tftp_connect;
|
||||
conn->curl_do = Curl_tftp;
|
||||
conn->curl_done = Curl_tftp_done;
|
||||
/* TFTP URLs support an extension like ";mode=<typecode>" that
|
||||
* we'll try to get now! */
|
||||
type=strstr(data->reqdata.path, ";mode=");
|
||||
if(!type) {
|
||||
type=strstr(conn->host.rawalloc, ";mode=");
|
||||
}
|
||||
if(type) {
|
||||
char command;
|
||||
*type=0; /* it was in the middle of the hostname */
|
||||
command = (char)toupper((int)type[6]);
|
||||
switch(command) {
|
||||
case 'A': /* ASCII mode */
|
||||
case 'N': /* NETASCII mode */
|
||||
data->set.prefer_ascii = TRUE;
|
||||
break;
|
||||
case 'O': /* octet mode */
|
||||
case 'I': /* binary mode */
|
||||
default:
|
||||
/* switch off ASCII */
|
||||
data->set.prefer_ascii = FALSE;
|
||||
break;
|
||||
}
|
||||
}
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built with TFTP disabled!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (strequal(conn->protostr, "SCP")) {
|
||||
#ifdef USE_LIBSSH2
|
||||
conn->port = PORT_SSH;
|
||||
conn->remote_port = PORT_SSH;
|
||||
conn->protocol = PROT_SCP;
|
||||
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
|
||||
conn->curl_do = Curl_scp_do;
|
||||
conn->curl_done = Curl_scp_done;
|
||||
conn->curl_connecting = Curl_ssh_multi_statemach;
|
||||
conn->curl_doing = Curl_scp_doing;
|
||||
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built without LIBSSH2, scp: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else if (strequal(conn->protostr, "SFTP")) {
|
||||
#ifdef USE_LIBSSH2
|
||||
conn->port = PORT_SSH;
|
||||
conn->remote_port = PORT_SSH;
|
||||
conn->protocol = PROT_SFTP;
|
||||
conn->curl_connect = Curl_ssh_connect; /* ssh_connect? */
|
||||
conn->curl_do = Curl_sftp_do;
|
||||
conn->curl_done = Curl_sftp_done;
|
||||
conn->curl_connecting = Curl_ssh_multi_statemach;
|
||||
conn->curl_doing = Curl_sftp_doing;
|
||||
conn->curl_do_more = (Curl_do_more_func)ZERO_NULL;
|
||||
#else
|
||||
failf(data, LIBCURL_NAME
|
||||
" was built without LIBSSH2, scp: not supported!");
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
#endif
|
||||
}
|
||||
|
||||
else {
|
||||
/* We fell through all checks and thus we don't support the specified
|
||||
protocol */
|
||||
failf(data, "Unsupported protocol: %s", conn->protostr);
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
return CURLE_OK;
|
||||
/* Protocol not found in table. */
|
||||
conn->handler = &Curl_handler_dummy; /* Be sure we have a handler defined. */
|
||||
failf(data, "Protocol %s not supported or disabled in " LIBCURL_NAME,
|
||||
conn->protostr);
|
||||
return CURLE_UNSUPPORTED_PROTOCOL;
|
||||
}
|
||||
|
||||
/****************************************************************
|
||||
@ -4495,8 +4326,8 @@ CURLcode Curl_done(struct connectdata **connp,
|
||||
}
|
||||
|
||||
/* this calls the protocol-specific function pointer previously set */
|
||||
if(conn->curl_done)
|
||||
result = conn->curl_done(conn, status, premature);
|
||||
if(conn->handler->done)
|
||||
result = conn->handler->done(conn, status, premature);
|
||||
else
|
||||
result = CURLE_OK;
|
||||
|
||||
@ -4548,9 +4379,9 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
|
||||
conn->bits.done = FALSE; /* Curl_done() is not called yet */
|
||||
conn->bits.do_more = FALSE; /* by default there's no curl_do_more() to use */
|
||||
|
||||
if(conn->curl_do) {
|
||||
if(conn->handler->do_it) {
|
||||
/* generic protocol-specific function pointer set in curl_connect() */
|
||||
result = conn->curl_do(conn, done);
|
||||
result = conn->handler->do_it(conn, done);
|
||||
|
||||
/* This was formerly done in transfer.c, but we better do it here */
|
||||
|
||||
@ -4599,7 +4430,7 @@ CURLcode Curl_do(struct connectdata **connp, bool *done)
|
||||
}
|
||||
|
||||
/* ... finally back to actually retry the DO phase */
|
||||
result = conn->curl_do(conn, done);
|
||||
result = conn->handler->do_it(conn, done);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -4611,8 +4442,8 @@ CURLcode Curl_do_more(struct connectdata *conn)
|
||||
{
|
||||
CURLcode result=CURLE_OK;
|
||||
|
||||
if(conn->curl_do_more)
|
||||
result = conn->curl_do_more(conn);
|
||||
if(conn->handler->do_more)
|
||||
result = conn->handler->do_more(conn);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
@ -809,6 +809,59 @@ struct HandleData {
|
||||
} proto;
|
||||
};
|
||||
|
||||
/*
|
||||
* Specific protocol handler.
|
||||
*/
|
||||
|
||||
struct Curl_handler {
|
||||
const char * scheme; /* URL scheme name. */
|
||||
|
||||
/* Complement to setup_connection_internals(). */
|
||||
CURLcode (*setup_connection)(struct connectdata *);
|
||||
|
||||
/* These two functions MUST be set to be protocol dependent */
|
||||
CURLcode (*do_it)(struct connectdata *, bool *done);
|
||||
Curl_done_func done;
|
||||
|
||||
/* If the curl_do() function is better made in two halves, this
|
||||
* curl_do_more() function will be called afterwards, if set. For example
|
||||
* for doing the FTP stuff after the PASV/PORT command.
|
||||
*/
|
||||
Curl_do_more_func do_more;
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* after the connect() and everything is done, as a step in the connection.
|
||||
* The 'done' pointer points to a bool that should be set to TRUE if the
|
||||
* function completes before return. If it doesn't complete, the caller
|
||||
* should call the curl_connecting() function until it is.
|
||||
*/
|
||||
CURLcode (*connect_it)(struct connectdata *, bool *done);
|
||||
|
||||
/* See above. Currently only used for FTP. */
|
||||
CURLcode (*connecting)(struct connectdata *, bool *done);
|
||||
CURLcode (*doing)(struct connectdata *, bool *done);
|
||||
|
||||
/* Called from the multi interface during the PROTOCONNECT phase, and it
|
||||
should then return a proper fd set */
|
||||
int (*proto_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* Called from the multi interface during the DOING phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*doing_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* by the curl_disconnect(), as a step in the disconnection.
|
||||
*/
|
||||
CURLcode (*disconnect)(struct connectdata *);
|
||||
|
||||
long defport; /* Default port. */
|
||||
long protocol; /* PROT_* flags concerning the protocol set */
|
||||
};
|
||||
|
||||
/*
|
||||
* The connectdata struct contains all fields and variables that should be
|
||||
* unique for an entire connection.
|
||||
@ -894,50 +947,7 @@ struct connectdata {
|
||||
|
||||
struct ConnectBits bits; /* various state-flags for this connection */
|
||||
|
||||
/* These two functions MUST be set by the curl_connect() function to be
|
||||
be protocol dependent */
|
||||
CURLcode (*curl_do)(struct connectdata *, bool *done);
|
||||
Curl_done_func curl_done;
|
||||
|
||||
/* If the curl_do() function is better made in two halves, this
|
||||
* curl_do_more() function will be called afterwards, if set. For example
|
||||
* for doing the FTP stuff after the PASV/PORT command.
|
||||
*/
|
||||
Curl_do_more_func curl_do_more;
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* after the connect() and everything is done, as a step in the connection.
|
||||
* The 'done' pointer points to a bool that should be set to TRUE if the
|
||||
* function completes before return. If it doesn't complete, the caller
|
||||
* should call the curl_connecting() function until it is.
|
||||
*/
|
||||
CURLcode (*curl_connect)(struct connectdata *, bool *done);
|
||||
|
||||
/* See above. Currently only used for FTP. */
|
||||
CURLcode (*curl_connecting)(struct connectdata *, bool *done);
|
||||
CURLcode (*curl_doing)(struct connectdata *, bool *done);
|
||||
|
||||
/* Called from the multi interface during the PROTOCONNECT phase, and it
|
||||
should then return a proper fd set */
|
||||
int (*curl_proto_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* Called from the multi interface during the DOING phase, and it should
|
||||
then return a proper fd set */
|
||||
int (*curl_doing_getsock)(struct connectdata *conn,
|
||||
curl_socket_t *socks,
|
||||
int numsocks);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* by the curl_disconnect(), as a step in the disconnection.
|
||||
*/
|
||||
CURLcode (*curl_disconnect)(struct connectdata *);
|
||||
|
||||
/* This function *MAY* be set to a protocol-dependent function that is run
|
||||
* in the curl_close() function if protocol-specific cleanups are required.
|
||||
*/
|
||||
CURLcode (*curl_close)(struct connectdata *);
|
||||
const struct Curl_handler * handler; /* Connection's protocol handler. */
|
||||
|
||||
/**** curl_get() phase fields */
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user