protocol source, all about protocols and uri schemes

Add protocol.h and protocol.c containing all about libcurl's
known URI schemes and their protocol handlers (so they exist).

Moves the scheme definitions from the various sources files into
protocol.c. Schemes are known and used, even of the protocol
handler is not build or just not implemented at all.

Closes #20906
This commit is contained in:
Stefan Eissing 2026-03-12 13:11:38 +01:00 committed by Daniel Stenberg
parent 32531f20f9
commit eb14705280
No known key found for this signature in database
GPG Key ID: 5CC908FDB71E12C2
42 changed files with 1089 additions and 992 deletions

View File

@ -236,6 +236,7 @@ LIB_CFILES = \
pingpong.c \
pop3.c \
progress.c \
protocol.c \
psl.c \
rand.c \
ratelimit.c \
@ -327,6 +328,7 @@ LIB_HFILES = \
fileinfo.h \
formdata.h \
ftp.h \
ftp-int.h \
ftplistparser.h \
functypes.h \
getinfo.h \
@ -362,6 +364,7 @@ LIB_HFILES = \
pingpong.h \
pop3.h \
progress.h \
protocol.h \
psl.h \
rand.h \
ratelimit.h \

View File

@ -25,9 +25,6 @@
***************************************************************************/
extern const struct Curl_protocol Curl_protocol_ldap;
extern const struct Curl_scheme Curl_scheme_ldap;
extern const struct Curl_scheme Curl_scheme_ldaps;
void Curl_ldap_version(char *buf, size_t bufsz);
#endif /* HEADER_CURL_LDAP_H */

View File

@ -225,7 +225,7 @@ void Curl_rtmp_version(char *version, size_t len)
* RTMP protocol handler.h, based on https://rtmpdump.mplayerhq.hu/
*/
static const struct Curl_protocol Curl_protocol_rtmp = {
const struct Curl_protocol Curl_protocol_rtmp = {
rtmp_setup_connection, /* setup_connection */
rtmp_do, /* do_it */
rtmp_done, /* done */
@ -246,81 +246,3 @@ static const struct Curl_protocol Curl_protocol_rtmp = {
};
#endif /* USE_LIBRTMP */
const struct Curl_scheme Curl_scheme_rtmp = {
"rtmp", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMP, /* protocol */
CURLPROTO_RTMP, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMP, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpt = {
"rtmpt", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPT, /* protocol */
CURLPROTO_RTMPT, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPT, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpe = {
"rtmpe", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPE, /* protocol */
CURLPROTO_RTMPE, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMP, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpte = {
"rtmpte", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPTE, /* protocol */
CURLPROTO_RTMPTE, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPT, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmps = {
"rtmps", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPS, /* protocol */
CURLPROTO_RTMP, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPS, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpts = {
"rtmpts", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPTS, /* protocol */
CURLPROTO_RTMPT, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPS, /* defport */
};

View File

@ -23,13 +23,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_rtmp;
extern const struct Curl_scheme Curl_scheme_rtmpt;
extern const struct Curl_scheme Curl_scheme_rtmpe;
extern const struct Curl_scheme Curl_scheme_rtmpte;
extern const struct Curl_scheme Curl_scheme_rtmps;
extern const struct Curl_scheme Curl_scheme_rtmpts;
#ifdef USE_LIBRTMP
extern const struct Curl_protocol Curl_protocol_rtmp;
void Curl_rtmp_version(char *version, size_t len);
#endif

View File

@ -275,7 +275,7 @@ error:
/*
* DICT protocol
*/
static const struct Curl_protocol Curl_protocol_dict = {
const struct Curl_protocol Curl_protocol_dict = {
ZERO_NULL, /* setup_connection */
dict_do, /* do_it */
ZERO_NULL, /* done */
@ -296,19 +296,3 @@ static const struct Curl_protocol Curl_protocol_dict = {
};
#endif /* CURL_DISABLE_DICT */
/*
* DICT protocol handler.
*/
const struct Curl_scheme Curl_scheme_dict = {
"dict", /* scheme */
#ifdef CURL_DISABLE_DICT
ZERO_NULL,
#else
&Curl_protocol_dict,
#endif
CURLPROTO_DICT, /* protocol */
CURLPROTO_DICT, /* family */
PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */
PORT_DICT, /* defport */
};

View File

@ -23,6 +23,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_dict;
#ifndef CURL_DISABLE_DICT
extern const struct Curl_protocol Curl_protocol_dict;
#endif
#endif /* HEADER_CURL_DICT_H */

View File

@ -598,7 +598,7 @@ out:
return result;
}
static const struct Curl_protocol Curl_protocol_file = {
const struct Curl_protocol Curl_protocol_file = {
file_setup_connection, /* setup_connection */
file_do, /* do_it */
file_done, /* done */
@ -619,19 +619,3 @@ static const struct Curl_protocol Curl_protocol_file = {
};
#endif
/*
* FILE scheme handler.
*/
const struct Curl_scheme Curl_scheme_file = {
"file", /* scheme */
#ifdef CURL_DISABLE_FILE
ZERO_NULL,
#else
&Curl_protocol_file,
#endif
CURLPROTO_FILE, /* protocol */
CURLPROTO_FILE, /* family */
PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */
0 /* defport */
};

View File

@ -23,6 +23,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_file;
#ifndef CURL_DISABLE_FILE
extern const struct Curl_protocol Curl_protocol_file;
#endif
#endif /* HEADER_CURL_FILE_H */

160
lib/ftp-int.h Normal file
View File

@ -0,0 +1,160 @@
#ifndef HEADER_CURL_FTP_INT_H
#define HEADER_CURL_FTP_INT_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "curl_setup.h"
#include "pingpong.h"
#ifndef CURL_DISABLE_FTP
/****************************************************************************
* FTP unique setup
***************************************************************************/
enum {
FTP_STOP, /* do nothing state, stops the state machine */
FTP_WAIT220, /* waiting for the initial 220 response immediately after
a connect */
FTP_AUTH,
FTP_USER,
FTP_PASS,
FTP_ACCT,
FTP_PBSZ,
FTP_PROT,
FTP_CCC,
FTP_PWD,
FTP_SYST,
FTP_NAMEFMT,
FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
FTP_RETR_PREQUOTE,
FTP_STOR_PREQUOTE,
FTP_LIST_PREQUOTE,
FTP_POSTQUOTE,
FTP_CWD, /* change directory */
FTP_MKD, /* if the directory did not exist */
FTP_MDTM, /* to figure out the datestamp */
FTP_TYPE, /* to set type when doing a head-like request */
FTP_LIST_TYPE, /* set type when about to do a directory list */
FTP_RETR_LIST_TYPE,
FTP_RETR_TYPE, /* set type when about to RETR a file */
FTP_STOR_TYPE, /* set type when about to STOR a file */
FTP_SIZE, /* get the remote file's size for head-like request */
FTP_RETR_SIZE, /* get the remote file's size for RETR */
FTP_STOR_SIZE, /* get the size for STOR */
FTP_REST, /* when used to check if the server supports it in head-like */
FTP_RETR_REST, /* when asking for "resume" in for RETR */
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
FTP_PASV, /* generic state for PASV and EPSV, check count1 */
FTP_LIST, /* generic state for LIST, NLST or a custom list command */
FTP_RETR,
FTP_STOR, /* generic state for STOR and APPE */
FTP_QUIT,
FTP_LAST /* never used */
};
typedef unsigned char ftpstate; /* use the enum values */
struct ftp_parselist_data; /* defined later in ftplistparser.c */
struct ftp_wc {
struct ftp_parselist_data *parser;
struct {
curl_write_callback write_function;
FILE *file_descriptor;
} backup;
};
/* This FTP struct is used in the Curl_easy. All FTP data that is
connection-oriented must be in FTP_conn to properly deal with the fact that
perhaps the Curl_easy is changed between the times the connection is
used. */
struct FTP {
char *path; /* points to the urlpieces struct field */
char *pathalloc; /* if non-NULL a pointer to an allocated path */
/* transfer a file/body or not, done as a typedefed enum to make debuggers
display the full symbol and not the numerical value */
curl_pp_transfer transfer;
curl_off_t downloadsize;
};
/* one struct entry for each path component (of 'rawpath') */
struct pathcomp {
int start; /* start column */
int len; /* length in bytes */
};
/* ftp_conn is used for struct connection-oriented data in the connectdata
struct */
struct ftp_conn {
struct pingpong pp;
char *account;
char *alternative_to_user;
char *entrypath; /* the PWD reply when we logged on */
const char *file; /* url-decoded filename (or path), points into rawpath */
char *rawpath; /* URL decoded, allocated, version of the path */
struct pathcomp *dirs; /* allocated array for path components */
char *prevpath; /* url-decoded conn->path from the previous transfer */
char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
and others (A/I or zero) */
char *server_os; /* The target server operating system. */
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
it */
int count1; /* general purpose counter for the state machine */
int count2; /* general purpose counter for the state machine */
int count3; /* general purpose counter for the state machine */
unsigned short dirdepth; /* number of entries used in the 'dirs' array,
< FTP_MAX_DIR_DEPTH */
unsigned short cwdcount; /* number of CWD commands issued,
< FTP_MAX_DIR_DEPTH */
unsigned char state; /* (ftpstate enum) always use ftp.c:state() to change
state! */
unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
IMAP or POP3 or others! (type: curl_usessl)*/
unsigned char ccc; /* ccc level for this connection */
BIT(ftp_trying_alternative);
BIT(dont_check); /* Set to TRUE to prevent the final (post-transfer)
file size and 226/250 status check. It should still
read the line, ignore the result. */
BIT(ctl_valid); /* Tells Curl_ftp_quit() whether or not to do anything. If
the connection has timed out or been closed, this
should be FALSE when it gets to Curl_ftp_quit() */
BIT(cwddone); /* if it has been determined that the proper CWD combo
already has been done */
BIT(cwdfail); /* set TRUE if a CWD command fails, as then we must prevent
caching the current directory */
BIT(wait_data_conn); /* this is set TRUE if data connection is waited */
BIT(shutdown); /* connection is being shutdown, e.g. QUIT */
};
/* meta key for storing `struct FTP` as easy meta data */
#define CURL_META_FTP_EASY "meta:proto:ftp:easy"
/* meta key for storing `struct ftp_conn` as connection meta data */
#define CURL_META_FTP_CONN "meta:proto:ftp:conn"
#endif /* CURL_DISABLE_FTP */
#endif /* HEADER_CURL_FTP_INT_H */

View File

@ -49,6 +49,7 @@
#include "transfer.h"
#include "escape.h"
#include "ftp.h"
#include "ftp-int.h"
#include "ftplistparser.h"
#include "curl_range.h"
#include "strcase.h"
@ -4456,7 +4457,7 @@ bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn)
/*
* FTP protocol.
*/
static const struct Curl_protocol Curl_protocol_ftp = {
const struct Curl_protocol Curl_protocol_ftp = {
ftp_setup_connection, /* setup_connection */
ftp_do, /* do_it */
ftp_done, /* done */
@ -4477,40 +4478,3 @@ static const struct Curl_protocol Curl_protocol_ftp = {
};
#endif /* CURL_DISABLE_FTP */
/*
* FTP protocol handler.
*/
const struct Curl_scheme Curl_scheme_ftp = {
"ftp", /* scheme */
#ifdef CURL_DISABLE_FTP
ZERO_NULL,
#else
&Curl_protocol_ftp,
#endif
CURLPROTO_FTP, /* protocol */
CURLPROTO_FTP, /* family */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
PROTOPT_WILDCARD | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE, /* flags */
PORT_FTP, /* defport */
};
/*
* FTPS protocol handler.
*/
const struct Curl_scheme Curl_scheme_ftps = {
"ftps", /* scheme */
#if defined(CURL_DISABLE_FTP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_ftp,
#endif
CURLPROTO_FTPS, /* protocol */
CURLPROTO_FTP, /* family */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD |
PROTOPT_CONN_REUSE, /* flags */
PORT_FTPS, /* defport */
};

135
lib/ftp.h
View File

@ -25,73 +25,11 @@
***************************************************************************/
#include "curl_setup.h"
#include "pingpong.h"
extern const struct Curl_scheme Curl_scheme_ftp;
extern const struct Curl_scheme Curl_scheme_ftps;
#ifndef CURL_DISABLE_FTP
extern const struct Curl_protocol Curl_protocol_ftp;
bool ftp_conns_match(struct connectdata *needle, struct connectdata *conn);
#endif /* CURL_DISABLE_FTP */
/****************************************************************************
* FTP unique setup
***************************************************************************/
enum {
FTP_STOP, /* do nothing state, stops the state machine */
FTP_WAIT220, /* waiting for the initial 220 response immediately after
a connect */
FTP_AUTH,
FTP_USER,
FTP_PASS,
FTP_ACCT,
FTP_PBSZ,
FTP_PROT,
FTP_CCC,
FTP_PWD,
FTP_SYST,
FTP_NAMEFMT,
FTP_QUOTE, /* waiting for a response to a command sent in a quote list */
FTP_RETR_PREQUOTE,
FTP_STOR_PREQUOTE,
FTP_LIST_PREQUOTE,
FTP_POSTQUOTE,
FTP_CWD, /* change directory */
FTP_MKD, /* if the directory did not exist */
FTP_MDTM, /* to figure out the datestamp */
FTP_TYPE, /* to set type when doing a head-like request */
FTP_LIST_TYPE, /* set type when about to do a directory list */
FTP_RETR_LIST_TYPE,
FTP_RETR_TYPE, /* set type when about to RETR a file */
FTP_STOR_TYPE, /* set type when about to STOR a file */
FTP_SIZE, /* get the remote file's size for head-like request */
FTP_RETR_SIZE, /* get the remote file's size for RETR */
FTP_STOR_SIZE, /* get the size for STOR */
FTP_REST, /* when used to check if the server supports it in head-like */
FTP_RETR_REST, /* when asking for "resume" in for RETR */
FTP_PORT, /* generic state for PORT, LPRT and EPRT, check count1 */
FTP_PRET, /* generic state for PRET RETR, PRET STOR and PRET LIST/NLST */
FTP_PASV, /* generic state for PASV and EPSV, check count1 */
FTP_LIST, /* generic state for LIST, NLST or a custom list command */
FTP_RETR,
FTP_STOR, /* generic state for STOR and APPE */
FTP_QUIT,
FTP_LAST /* never used */
};
typedef unsigned char ftpstate; /* use the enum values */
struct ftp_parselist_data; /* defined later in ftplistparser.c */
struct ftp_wc {
struct ftp_parselist_data *parser;
struct {
curl_write_callback write_function;
FILE *file_descriptor;
} backup;
};
typedef enum {
FTPFILE_MULTICWD = 1, /* as defined by RFC1738 */
FTPFILE_NOCWD = 2, /* use SIZE / RETR / STOR on the full path */
@ -99,74 +37,7 @@ typedef enum {
file */
} curl_ftpfile;
/* This FTP struct is used in the Curl_easy. All FTP data that is
connection-oriented must be in FTP_conn to properly deal with the fact that
perhaps the Curl_easy is changed between the times the connection is
used. */
struct FTP {
char *path; /* points to the urlpieces struct field */
char *pathalloc; /* if non-NULL a pointer to an allocated path */
/* transfer a file/body or not, done as a typedefed enum to make debuggers
display the full symbol and not the numerical value */
curl_pp_transfer transfer;
curl_off_t downloadsize;
};
/* one struct entry for each path component (of 'rawpath') */
struct pathcomp {
int start; /* start column */
int len; /* length in bytes */
};
/* ftp_conn is used for struct connection-oriented data in the connectdata
struct */
struct ftp_conn {
struct pingpong pp;
char *account;
char *alternative_to_user;
char *entrypath; /* the PWD reply when we logged on */
const char *file; /* url-decoded filename (or path), points into rawpath */
char *rawpath; /* URL decoded, allocated, version of the path */
struct pathcomp *dirs; /* allocated array for path components */
char *prevpath; /* url-decoded conn->path from the previous transfer */
char transfertype; /* set by ftp_transfertype for use by Curl_client_write()a
and others (A/I or zero) */
char *server_os; /* The target server operating system. */
curl_off_t known_filesize; /* file size is different from -1, if wildcard
LIST parsing was done and wc_statemach set
it */
int count1; /* general purpose counter for the state machine */
int count2; /* general purpose counter for the state machine */
int count3; /* general purpose counter for the state machine */
unsigned short dirdepth; /* number of entries used in the 'dirs' array,
< FTP_MAX_DIR_DEPTH */
unsigned short cwdcount; /* number of CWD commands issued,
< FTP_MAX_DIR_DEPTH */
unsigned char state; /* (ftpstate enum) always use ftp.c:state() to change
state! */
unsigned char use_ssl; /* if AUTH TLS is to be attempted etc, for FTP or
IMAP or POP3 or others! (type: curl_usessl)*/
unsigned char ccc; /* ccc level for this connection */
BIT(ftp_trying_alternative);
BIT(dont_check); /* Set to TRUE to prevent the final (post-transfer)
file size and 226/250 status check. It should still
read the line, ignore the result. */
BIT(ctl_valid); /* Tells Curl_ftp_quit() whether or not to do anything. If
the connection has timed out or been closed, this
should be FALSE when it gets to Curl_ftp_quit() */
BIT(cwddone); /* if it has been determined that the proper CWD combo
already has been done */
BIT(cwdfail); /* set TRUE if a CWD command fails, as then we must prevent
caching the current directory */
BIT(wait_data_conn); /* this is set TRUE if data connection is waited */
BIT(shutdown); /* connection is being shutdown, e.g. QUIT */
};
/* meta key for storing `struct FTP` as easy meta data */
#define CURL_META_FTP_EASY "meta:proto:ftp:easy"
/* meta key for storing `struct ftp_conn` as connection meta data */
#define CURL_META_FTP_CONN "meta:proto:ftp:conn"
#endif /* CURL_DISABLE_FTP */
#define DEFAULT_ACCEPT_TIMEOUT 60000 /* milliseconds == one minute */

View File

@ -44,6 +44,7 @@
#include "fileinfo.h"
#include "llist.h"
#include "ftp.h"
#include "ftp-int.h"
#include "ftplistparser.h"
#include "curl_fnmatch.h"
#include "multiif.h"

View File

@ -172,7 +172,7 @@ static CURLcode gopher_do(struct Curl_easy *data, bool *done)
* connect-command-download protocols.
*/
static const struct Curl_protocol Curl_protocol_gopher = {
const struct Curl_protocol Curl_protocol_gopher = {
ZERO_NULL, /* setup_connection */
gopher_do, /* do_it */
ZERO_NULL, /* done */
@ -193,7 +193,7 @@ static const struct Curl_protocol Curl_protocol_gopher = {
};
#ifdef USE_SSL
static const struct Curl_protocol Curl_protocol_gophers = {
const struct Curl_protocol Curl_protocol_gophers = {
ZERO_NULL, /* setup_connection */
gopher_do, /* do_it */
ZERO_NULL, /* done */
@ -215,29 +215,3 @@ static const struct Curl_protocol Curl_protocol_gophers = {
#endif
#endif /* CURL_DISABLE_GOPHER */
const struct Curl_scheme Curl_scheme_gopher = {
"gopher", /* scheme */
#ifdef CURL_DISABLE_GOPHER
ZERO_NULL,
#else
&Curl_protocol_gopher,
#endif
CURLPROTO_GOPHER, /* protocol */
CURLPROTO_GOPHER, /* family */
PROTOPT_NONE, /* flags */
PORT_GOPHER, /* defport */
};
const struct Curl_scheme Curl_scheme_gophers = {
"gophers", /* scheme */
#if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_gophers,
#endif
CURLPROTO_GOPHERS, /* protocol */
CURLPROTO_GOPHER, /* family */
PROTOPT_SSL, /* flags */
PORT_GOPHER, /* defport */
};

View File

@ -23,7 +23,9 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_gopher;
extern const struct Curl_scheme Curl_scheme_gophers;
#ifndef CURL_DISABLE_GOPHER
extern const struct Curl_protocol Curl_protocol_gopher;
extern const struct Curl_protocol Curl_protocol_gophers;
#endif
#endif /* HEADER_CURL_GOPHER_H */

View File

@ -4996,7 +4996,7 @@ void Curl_http_resp_free(struct http_resp *resp)
/*
* HTTP handler interface.
*/
static const struct Curl_protocol Curl_protocol_http = {
const struct Curl_protocol Curl_protocol_http = {
Curl_http_setup_conn, /* setup_connection */
Curl_http, /* do_it */
Curl_http_done, /* done */
@ -5017,37 +5017,3 @@ static const struct Curl_protocol Curl_protocol_http = {
};
#endif /* CURL_DISABLE_HTTP */
/*
* HTTP handler interface.
*/
const struct Curl_scheme Curl_scheme_http = {
"http", /* scheme */
#ifdef CURL_DISABLE_HTTP
ZERO_NULL,
#else
&Curl_protocol_http,
#endif
CURLPROTO_HTTP, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
PORT_HTTP, /* defport */
};
/*
* HTTPS handler interface.
*/
const struct Curl_scheme Curl_scheme_https = {
"https", /* scheme */
#if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_http,
#endif
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
PORT_HTTPS, /* defport */
};

View File

@ -37,27 +37,16 @@ typedef enum {
HTTPREQ_HEAD
} Curl_HttpReq;
/* When redirecting transfers. */
typedef enum {
FOLLOW_NONE, /* not used within the function, a placeholder to allow
initing to this */
FOLLOW_FAKE, /* only records stuff, not actually following */
FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
redirect following */
FOLLOW_REDIR /* a full true redirect */
} followtype;
#define CURL_HTTP_V1x (1 << 0)
#define CURL_HTTP_V2x (1 << 1)
#define CURL_HTTP_V3x (1 << 2)
/* bitmask of CURL_HTTP_V* values */
typedef unsigned char http_majors;
extern const struct Curl_scheme Curl_scheme_http;
extern const struct Curl_scheme Curl_scheme_https;
#ifndef CURL_DISABLE_HTTP
extern const struct Curl_protocol Curl_protocol_http;
struct dynhds;
struct http_negotiation {

View File

@ -2302,7 +2302,7 @@ static CURLcode imap_setup_connection(struct Curl_easy *data,
/*
* IMAP protocol.
*/
static const struct Curl_protocol Curl_protocol_imap = {
const struct Curl_protocol Curl_protocol_imap = {
imap_setup_connection, /* setup_connection */
imap_do, /* do_it */
imap_done, /* done */
@ -2323,38 +2323,3 @@ static const struct Curl_protocol Curl_protocol_imap = {
};
#endif /* CURL_DISABLE_IMAP */
/*
* IMAP protocol handler.
*/
const struct Curl_scheme Curl_scheme_imap = {
"imap", /* scheme */
#ifdef CURL_DISABLE_IMAP
ZERO_NULL,
#else
&Curl_protocol_imap,
#endif
CURLPROTO_IMAP, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE,
PORT_IMAP, /* defport */
};
/*
* IMAPS protocol handler.
*/
const struct Curl_scheme Curl_scheme_imaps = {
"imaps", /* scheme */
#if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_imap,
#endif
CURLPROTO_IMAPS, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
PORT_IMAPS, /* defport */
};

View File

@ -23,8 +23,6 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_imap;
extern const struct Curl_scheme Curl_scheme_imaps;
/* Authentication type flags */
#define IMAP_TYPE_CLEARTEXT (1 << 0)
@ -34,4 +32,8 @@ extern const struct Curl_scheme Curl_scheme_imaps;
#define IMAP_TYPE_NONE 0
#define IMAP_TYPE_ANY (IMAP_TYPE_CLEARTEXT | IMAP_TYPE_SASL)
#ifndef CURL_DISABLE_IMAP
extern const struct Curl_protocol Curl_protocol_imap;
#endif
#endif /* HEADER_CURL_IMAP_H */

View File

@ -1001,35 +1001,3 @@ const struct Curl_protocol Curl_protocol_ldap = {
#endif
#endif /* !CURL_DISABLE_LDAP && !USE_OPENLDAP */
/*
* LDAP
*/
const struct Curl_scheme Curl_scheme_ldap = {
"ldap", /* scheme */
#ifdef CURL_DISABLE_LDAP
ZERO_NULL,
#else
&Curl_protocol_ldap,
#endif
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
PROTOPT_SSL_REUSE, /* flags */
PORT_LDAP, /* defport */
};
/*
* LDAPS
*/
const struct Curl_scheme Curl_scheme_ldaps = {
"ldaps", /* scheme */
#if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL)
ZERO_NULL,
#else
&Curl_protocol_ldap,
#endif
CURLPROTO_LDAPS, /* protocol */
CURLPROTO_LDAP, /* family */
PROTOPT_SSL, /* flags */
PORT_LDAPS, /* defport */
};

View File

@ -964,7 +964,7 @@ static CURLcode mqtts_connecting(struct Curl_easy *data, bool *done)
/*
* MQTTS protocol.
*/
static const struct Curl_protocol Curl_protocol_mqtts = {
const struct Curl_protocol Curl_protocol_mqtts = {
mqtt_setup_conn, /* setup_connection */
mqtt_do, /* do_it */
mqtt_done, /* done */
@ -989,7 +989,7 @@ static const struct Curl_protocol Curl_protocol_mqtts = {
/*
* MQTT protocol.
*/
static const struct Curl_protocol Curl_protocol_mqtt = {
const struct Curl_protocol Curl_protocol_mqtt = {
mqtt_setup_conn, /* setup_connection */
mqtt_do, /* do_it */
mqtt_done, /* done */
@ -1010,32 +1010,3 @@ static const struct Curl_protocol Curl_protocol_mqtt = {
};
#endif /* CURL_DISABLE_MQTT */
const struct Curl_scheme Curl_scheme_mqtts = {
"mqtts", /* scheme */
#if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_mqtts,
#endif
CURLPROTO_MQTTS, /* protocol */
CURLPROTO_MQTT, /* family */
PROTOPT_SSL, /* flags */
PORT_MQTTS, /* defport */
};
/*
* MQTT protocol.
*/
const struct Curl_scheme Curl_scheme_mqtt = {
"mqtt", /* scheme */
#ifdef CURL_DISABLE_MQTT
ZERO_NULL,
#else
&Curl_protocol_mqtt,
#endif
CURLPROTO_MQTT, /* protocol */
CURLPROTO_MQTT, /* family */
PROTOPT_NONE, /* flags */
PORT_MQTT, /* defport */
};

View File

@ -23,7 +23,11 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_mqtt;
extern const struct Curl_scheme Curl_scheme_mqtts;
#ifndef CURL_DISABLE_MQTT
extern const struct Curl_protocol Curl_protocol_mqtt;
#ifdef USE_SSL
extern const struct Curl_protocol Curl_protocol_mqtts;
#endif
#endif
#endif /* HEADER_CURL_MQTT_H */

View File

@ -1691,7 +1691,7 @@ static CURLcode pop3_setup_connection(struct Curl_easy *data,
/*
* POP3 protocol.
*/
static const struct Curl_protocol Curl_protocol_pop3 = {
const struct Curl_protocol Curl_protocol_pop3 = {
pop3_setup_connection, /* setup_connection */
pop3_do, /* do_it */
pop3_done, /* done */
@ -1712,37 +1712,3 @@ static const struct Curl_protocol Curl_protocol_pop3 = {
};
#endif /* CURL_DISABLE_POP3 */
/*
* POP3 protocol handler.
*/
const struct Curl_scheme Curl_scheme_pop3 = {
"pop3", /* scheme */
#ifdef CURL_DISABLE_POP3
ZERO_NULL,
#else
&Curl_protocol_pop3,
#endif
CURLPROTO_POP3, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
PORT_POP3, /* defport */
};
/*
* POP3S protocol handler.
*/
const struct Curl_scheme Curl_scheme_pop3s = {
"pop3s", /* scheme */
#if defined(CURL_DISABLE_POP3) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_pop3,
#endif
CURLPROTO_POP3S, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
PORT_POP3S, /* defport */
};

View File

@ -23,7 +23,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_pop3;
extern const struct Curl_scheme Curl_scheme_pop3s;
#ifndef CURL_DISABLE_POP3
extern const struct Curl_protocol Curl_protocol_pop3;
#endif
#endif /* HEADER_CURL_POP3_H */

571
lib/protocol.c Normal file
View File

@ -0,0 +1,571 @@
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
#include "curl_setup.h"
#include "protocol.h"
#include "strcase.h"
#include "dict.h"
#include "file.h"
#include "ftp.h"
#include "gopher.h"
#include "http.h"
#include "imap.h"
#include "curl_ldap.h"
#include "mqtt.h"
#include "pop3.h"
#include "curl_rtmp.h"
#include "rtsp.h"
#include "smb.h"
#include "smtp.h"
#include "telnet.h"
#include "tftp.h"
#include "ws.h"
#include "vssh/ssh.h"
/* All URI schemes known to libcurl, but not necessarily implemented
* by protocol handlers. */
const struct Curl_scheme Curl_scheme_dict = {
"dict", /* scheme */
#ifdef CURL_DISABLE_DICT
ZERO_NULL,
#else
&Curl_protocol_dict,
#endif
CURLPROTO_DICT, /* protocol */
CURLPROTO_DICT, /* family */
PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */
PORT_DICT, /* defport */
};
const struct Curl_scheme Curl_scheme_file = {
"file", /* scheme */
#ifdef CURL_DISABLE_FILE
ZERO_NULL,
#else
&Curl_protocol_file,
#endif
CURLPROTO_FILE, /* protocol */
CURLPROTO_FILE, /* family */
PROTOPT_NONETWORK | PROTOPT_NOURLQUERY, /* flags */
0 /* defport */
};
const struct Curl_scheme Curl_scheme_ftp = {
"ftp", /* scheme */
#ifdef CURL_DISABLE_FTP
ZERO_NULL,
#else
&Curl_protocol_ftp,
#endif
CURLPROTO_FTP, /* protocol */
CURLPROTO_FTP, /* family */
PROTOPT_DUAL | PROTOPT_CLOSEACTION | PROTOPT_NEEDSPWD |
PROTOPT_NOURLQUERY | PROTOPT_PROXY_AS_HTTP |
PROTOPT_WILDCARD | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE, /* flags */
PORT_FTP, /* defport */
};
const struct Curl_scheme Curl_scheme_ftps = {
"ftps", /* scheme */
#if defined(CURL_DISABLE_FTP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_ftp,
#endif
CURLPROTO_FTPS, /* protocol */
CURLPROTO_FTP, /* family */
PROTOPT_SSL | PROTOPT_DUAL | PROTOPT_CLOSEACTION |
PROTOPT_NEEDSPWD | PROTOPT_NOURLQUERY | PROTOPT_WILDCARD |
PROTOPT_CONN_REUSE, /* flags */
PORT_FTPS, /* defport */
};
const struct Curl_scheme Curl_scheme_gopher = {
"gopher", /* scheme */
#ifdef CURL_DISABLE_GOPHER
ZERO_NULL,
#else
&Curl_protocol_gopher,
#endif
CURLPROTO_GOPHER, /* protocol */
CURLPROTO_GOPHER, /* family */
PROTOPT_NONE, /* flags */
PORT_GOPHER, /* defport */
};
const struct Curl_scheme Curl_scheme_gophers = {
"gophers", /* scheme */
#if defined(CURL_DISABLE_GOPHER) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_gophers,
#endif
CURLPROTO_GOPHERS, /* protocol */
CURLPROTO_GOPHER, /* family */
PROTOPT_SSL, /* flags */
PORT_GOPHER, /* defport */
};
const struct Curl_scheme Curl_scheme_http = {
"http", /* scheme */
#ifdef CURL_DISABLE_HTTP
ZERO_NULL,
#else
&Curl_protocol_http,
#endif
CURLPROTO_HTTP, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
PORT_HTTP, /* defport */
};
const struct Curl_scheme Curl_scheme_https = {
"https", /* scheme */
#if defined(CURL_DISABLE_HTTP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_http,
#endif
CURLPROTO_HTTPS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | PROTOPT_ALPN | /* flags */
PROTOPT_USERPWDCTRL | PROTOPT_CONN_REUSE,
PORT_HTTPS, /* defport */
};
const struct Curl_scheme Curl_scheme_imap = {
"imap", /* scheme */
#ifdef CURL_DISABLE_IMAP
ZERO_NULL,
#else
&Curl_protocol_imap,
#endif
CURLPROTO_IMAP, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE |
PROTOPT_CONN_REUSE,
PORT_IMAP, /* defport */
};
const struct Curl_scheme Curl_scheme_imaps = {
"imaps", /* scheme */
#if defined(CURL_DISABLE_IMAP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_imap,
#endif
CURLPROTO_IMAPS, /* protocol */
CURLPROTO_IMAP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
PORT_IMAPS, /* defport */
};
const struct Curl_scheme Curl_scheme_ldap = {
"ldap", /* scheme */
#ifdef CURL_DISABLE_LDAP
ZERO_NULL,
#else
&Curl_protocol_ldap,
#endif
CURLPROTO_LDAP, /* protocol */
CURLPROTO_LDAP, /* family */
PROTOPT_SSL_REUSE, /* flags */
PORT_LDAP, /* defport */
};
const struct Curl_scheme Curl_scheme_ldaps = {
"ldaps", /* scheme */
#if defined(CURL_DISABLE_LDAP) || !defined(HAVE_LDAP_SSL)
ZERO_NULL,
#else
&Curl_protocol_ldap,
#endif
CURLPROTO_LDAPS, /* protocol */
CURLPROTO_LDAP, /* family */
PROTOPT_SSL, /* flags */
PORT_LDAPS, /* defport */
};
const struct Curl_scheme Curl_scheme_mqtt = {
"mqtt", /* scheme */
#ifdef CURL_DISABLE_MQTT
ZERO_NULL,
#else
&Curl_protocol_mqtt,
#endif
CURLPROTO_MQTT, /* protocol */
CURLPROTO_MQTT, /* family */
PROTOPT_NONE, /* flags */
PORT_MQTT, /* defport */
};
const struct Curl_scheme Curl_scheme_mqtts = {
"mqtts", /* scheme */
#if defined(CURL_DISABLE_MQTT) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_mqtts,
#endif
CURLPROTO_MQTTS, /* protocol */
CURLPROTO_MQTT, /* family */
PROTOPT_SSL, /* flags */
PORT_MQTTS, /* defport */
};
const struct Curl_scheme Curl_scheme_pop3 = {
"pop3", /* scheme */
#ifdef CURL_DISABLE_POP3
ZERO_NULL,
#else
&Curl_protocol_pop3,
#endif
CURLPROTO_POP3, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
PORT_POP3, /* defport */
};
const struct Curl_scheme Curl_scheme_pop3s = {
"pop3s", /* scheme */
#if defined(CURL_DISABLE_POP3) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_pop3,
#endif
CURLPROTO_POP3S, /* protocol */
CURLPROTO_POP3, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
PORT_POP3S, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmp = {
"rtmp", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMP, /* protocol */
CURLPROTO_RTMP, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMP, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpt = {
"rtmpt", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPT, /* protocol */
CURLPROTO_RTMPT, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPT, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpe = {
"rtmpe", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPE, /* protocol */
CURLPROTO_RTMPE, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMP, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpte = {
"rtmpte", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPTE, /* protocol */
CURLPROTO_RTMPTE, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPT, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmps = {
"rtmps", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPS, /* protocol */
CURLPROTO_RTMP, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPS, /* defport */
};
const struct Curl_scheme Curl_scheme_rtmpts = {
"rtmpts", /* scheme */
#ifndef USE_LIBRTMP
ZERO_NULL,
#else
&Curl_protocol_rtmp,
#endif
CURLPROTO_RTMPTS, /* protocol */
CURLPROTO_RTMPT, /* family */
PROTOPT_NONE, /* flags */
PORT_RTMPS, /* defport */
};
const struct Curl_scheme Curl_scheme_rtsp = {
"rtsp", /* scheme */
#ifdef CURL_DISABLE_RTSP
ZERO_NULL,
#else
&Curl_protocol_rtsp,
#endif
CURLPROTO_RTSP, /* protocol */
CURLPROTO_RTSP, /* family */
PROTOPT_CONN_REUSE, /* flags */
PORT_RTSP, /* defport */
};
const struct Curl_scheme Curl_scheme_sftp = {
"SFTP", /* scheme */
#ifndef USE_SSH
NULL,
#else
&Curl_protocol_sftp,
#endif
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
PORT_SSH /* defport */
};
const struct Curl_scheme Curl_scheme_scp = {
"SCP", /* scheme */
#ifndef USE_SSH
NULL,
#else
&Curl_protocol_scp,
#endif
CURLPROTO_SCP, /* protocol */
CURLPROTO_SCP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
PORT_SSH, /* defport */
};
const struct Curl_scheme Curl_scheme_smb = {
"smb", /* scheme */
#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE)
ZERO_NULL,
#else
&Curl_protocol_smb,
#endif
CURLPROTO_SMB, /* protocol */
CURLPROTO_SMB, /* family */
PROTOPT_CONN_REUSE, /* flags */
PORT_SMB, /* defport */
};
const struct Curl_scheme Curl_scheme_smbs = {
"smbs", /* scheme */
#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE) || \
!defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_smb,
#endif
CURLPROTO_SMBS, /* protocol */
CURLPROTO_SMB, /* family */
PROTOPT_SSL | PROTOPT_CONN_REUSE, /* flags */
PORT_SMBS, /* defport */
};
const struct Curl_scheme Curl_scheme_smtp = {
"smtp", /* scheme */
#ifdef CURL_DISABLE_SMTP
ZERO_NULL,
#else
&Curl_protocol_smtp,
#endif
CURLPROTO_SMTP, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
PORT_SMTP, /* defport */
};
const struct Curl_scheme Curl_scheme_smtps = {
"smtps", /* scheme */
#if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_smtp,
#endif
CURLPROTO_SMTPS, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
PORT_SMTPS, /* defport */
};
const struct Curl_scheme Curl_scheme_telnet = {
"telnet", /* scheme */
#ifdef CURL_DISABLE_TELNET
ZERO_NULL,
#else
&Curl_protocol_telnet,
#endif
CURLPROTO_TELNET, /* protocol */
CURLPROTO_TELNET, /* family */
PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */
PORT_TELNET, /* defport */
};
const struct Curl_scheme Curl_scheme_tftp = {
"tftp", /* scheme */
#ifdef CURL_DISABLE_TFTP
ZERO_NULL,
#else
&Curl_protocol_tftp,
#endif
CURLPROTO_TFTP, /* protocol */
CURLPROTO_TFTP, /* family */
PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */
PORT_TFTP, /* defport */
};
const struct Curl_scheme Curl_scheme_ws = {
"WS", /* scheme */
#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP)
ZERO_NULL,
#else
&Curl_protocol_ws,
#endif
CURLPROTO_WS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL,
PORT_HTTP /* defport */
};
const struct Curl_scheme Curl_scheme_wss = {
"WSS", /* scheme */
#if defined(CURL_DISABLE_WEBSOCKETS) || defined(CURL_DISABLE_HTTP) || \
!defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_ws,
#endif
CURLPROTO_WSS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL,
PORT_HTTPS /* defport */
};
/* Returns a struct scheme pointer if the name is a known scheme. Check the
->run struct field for non-NULL to figure out if an implementation is
present. */
const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len)
{
/* table generated by schemetable.c:
1. gcc schemetable.c && ./a.out
2. check how small the table gets
3. tweak the hash algorithm, then rerun from 1
4. when the table is good enough
5. copy the table into this source code
6. make sure this function uses the same hash function that worked for
schemetable.c
*/
static const struct Curl_scheme * const all_schemes[67] = {
&Curl_scheme_file,
&Curl_scheme_mqtts, NULL,
&Curl_scheme_gophers, NULL,
&Curl_scheme_rtmpe,
&Curl_scheme_smtp,
&Curl_scheme_sftp,
&Curl_scheme_smb,
&Curl_scheme_smtps,
&Curl_scheme_telnet,
&Curl_scheme_gopher,
&Curl_scheme_tftp, NULL, NULL, NULL,
&Curl_scheme_ftps,
&Curl_scheme_http,
&Curl_scheme_imap,
&Curl_scheme_rtmps,
&Curl_scheme_rtmpt, NULL, NULL, NULL,
&Curl_scheme_ldaps,
&Curl_scheme_wss,
&Curl_scheme_https, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&Curl_scheme_rtsp,
&Curl_scheme_smbs,
&Curl_scheme_scp, NULL, NULL, NULL,
&Curl_scheme_pop3, NULL, NULL,
&Curl_scheme_rtmp, NULL, NULL, NULL,
&Curl_scheme_rtmpte, NULL, NULL, NULL,
&Curl_scheme_dict, NULL, NULL, NULL,
&Curl_scheme_mqtt,
&Curl_scheme_pop3s,
&Curl_scheme_imaps, NULL,
&Curl_scheme_ws, NULL,
&Curl_scheme_rtmpts,
&Curl_scheme_ldap, NULL, NULL,
&Curl_scheme_ftp,
};
if(len && (len <= 7)) {
const char *s = scheme;
size_t l = len;
const struct Curl_scheme *h;
unsigned int c = 978;
while(l) {
c <<= 5;
c += (unsigned int)Curl_raw_tolower(*s);
s++;
l--;
}
h = all_schemes[c % 67];
if(h && curl_strnequal(scheme, h->name, len) && !h->name[len])
return h;
}
return NULL;
}
const struct Curl_scheme *Curl_get_scheme(const char *scheme)
{
return Curl_getn_scheme(scheme, strlen(scheme));
}

291
lib/protocol.h Normal file
View File

@ -0,0 +1,291 @@
#ifndef HEADER_CURL_PROTOCOL_H
#define HEADER_CURL_PROTOCOL_H
/***************************************************************************
* _ _ ____ _
* Project ___| | | | _ \| |
* / __| | | | |_) | |
* | (__| |_| | _ <| |___
* \___|\___/|_| \_\_____|
*
* Copyright (C) Daniel Stenberg, <daniel@haxx.se>, et al.
*
* This software is licensed as described in the file COPYING, which
* you should have received as part of this distribution. The terms
* are also available at https://curl.se/docs/copyright.html.
*
* You may opt to use, copy, modify, merge, publish, distribute and/or sell
* copies of the Software, and permit persons to whom the Software is
* furnished to do so, under the terms of the COPYING file.
*
* This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY
* KIND, either express or implied.
*
* SPDX-License-Identifier: curl
*
***************************************************************************/
/* This file is for lib internal stuff */
#include "curl_setup.h"
struct Curl_easy;
struct connectdata;
struct easy_pollset;
/* Known protocol default port numbers */
#define PORT_FTP 21
#define PORT_FTPS 990
#define PORT_TELNET 23
#define PORT_HTTP 80
#define PORT_HTTPS 443
#define PORT_DICT 2628
#define PORT_LDAP 389
#define PORT_LDAPS 636
#define PORT_TFTP 69
#define PORT_SSH 22
#define PORT_IMAP 143
#define PORT_IMAPS 993
#define PORT_POP3 110
#define PORT_POP3S 995
#define PORT_SMB 445
#define PORT_SMBS 445
#define PORT_SMTP 25
#define PORT_SMTPS 465 /* sometimes called SSMTP */
#define PORT_RTSP 554
#define PORT_RTMP 1935
#define PORT_RTMPT PORT_HTTP
#define PORT_RTMPS PORT_HTTPS
#define PORT_GOPHER 70
#define PORT_MQTT 1883
#define PORT_MQTTS 8883
#ifndef CURL_DISABLE_WEBSOCKETS
/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
* the rest are internal information. If we use higher bits we only do this on
* platforms that have a >= 64-bit type and then we use such a type for the
* protocol fields in the scheme definition.
*/
#define CURLPROTO_WS (1L << 30)
#define CURLPROTO_WSS ((curl_prot_t)1 << 31)
#else
#define CURLPROTO_WS 0L
#define CURLPROTO_WSS 0L
#endif
#define CURLPROTO_MQTTS (1LL << 32)
#define CURLPROTO_64ALL ((uint64_t)0xffffffffffffffff)
/* the default protocols accepting a redirect to */
#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \
CURLPROTO_FTPS)
typedef curl_off_t curl_prot_t;
/* This mask is for all the old protocols that are provided and defined in the
public header and shall exclude protocols added since which are not exposed
in the API */
#define CURLPROTO_MASK 0x3ffffff
/* Convenience defines for checking protocols or their SSL based version. Each
protocol scheme should only ever have a single CURLPROTO_ in its protocol
field. */
#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_WS | \
CURLPROTO_WSS)
#define PROTO_FAMILY_FTP (CURLPROTO_FTP | CURLPROTO_FTPS)
#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S)
#define PROTO_FAMILY_SMB (CURLPROTO_SMB | CURLPROTO_SMBS)
#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS)
#define PROTO_FAMILY_SSH (CURLPROTO_SCP | CURLPROTO_SFTP)
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \
!defined(CURL_DISABLE_POP3)
/* these protocols support CURLOPT_DIRLISTONLY */
#define CURL_LIST_ONLY_PROTOCOL 1
#endif
/* When redirecting transfers. */
typedef enum {
FOLLOW_NONE, /* not used within the function, a placeholder to allow
initing to this */
FOLLOW_FAKE, /* only records stuff, not actually following */
FOLLOW_RETRY, /* set if this is a request retry as opposed to a real
redirect following */
FOLLOW_REDIR /* a full true redirect */
} followtype;
/*
* Specific protocol handler, an implementation of one or more URI schemes.
*/
struct Curl_protocol {
/* Complement to setup_connection_internals(). This is done before the
transfer "owns" the connection. */
CURLcode (*setup_connection)(struct Curl_easy *data,
struct connectdata *conn);
/* These two functions MUST be set to be protocol dependent */
CURLcode (*do_it)(struct Curl_easy *data, bool *done);
CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
/* 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.
*/
CURLcode (*do_more)(struct Curl_easy *, int *);
/* 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 does not complete, the caller
* should call the ->connecting() function until it is.
*/
CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
/* See above. */
CURLcode (*connecting)(struct Curl_easy *data, bool *done);
CURLcode (*doing)(struct Curl_easy *data, bool *done);
/* Called from the multi interface during the PROTOCONNECT phase, and it
should then return a proper fd set */
CURLcode (*proto_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* Called from the multi interface during the DOING phase, and it should
then return a proper fd set */
CURLcode (*doing_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* Called from the multi interface during the DO_MORE phase, and it should
then return a proper fd set */
CURLcode (*domore_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* Called from the multi interface during the DO_DONE, PERFORM and
WAITPERFORM phases, and it should then return a proper fd set. Not setting
this will make libcurl use the generic default one. */
CURLcode (*perform_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* This function *MAY* be set to a protocol-dependent function that is run
* by the curl_disconnect(), as a step in the disconnection. If the handler
* is called because the connection has been considered dead,
* dead_connection is set to TRUE. The connection is (again) associated with
* the transfer here.
*/
CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
bool dead_connection);
/* If used, this function gets called from transfer.c to
allow the protocol to do extra handling in writing response to
the client. */
CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
bool is_eos);
/* If used, this function gets called from transfer.c to
allow the protocol to do extra handling in writing a single response
header line to the client. */
CURLcode (*write_resp_hd)(struct Curl_easy *data,
const char *hd, size_t hdlen, bool is_eos);
/* If used, this function checks for a connection managed by this
protocol and currently not in use, if it should be considered dead. */
bool (*connection_is_dead)(struct Curl_easy *data,
struct connectdata *conn);
/* attach() attaches this transfer to this connection */
void (*attach)(struct Curl_easy *data, struct connectdata *conn);
/* return CURLE_OK if a redirect to `newurl` should be followed,
CURLE_TOO_MANY_REDIRECTS otherwise. May alter `data` to change
the way the follow request is performed. */
CURLcode (*follow)(struct Curl_easy *data, const char *newurl,
followtype type);
};
#define PROTOPT_NONE 0 /* nothing extra */
#define PROTOPT_SSL (1 << 0) /* uses SSL */
#define PROTOPT_DUAL (1 << 1) /* this protocol uses two connections */
#define PROTOPT_CLOSEACTION (1 << 2) /* need action before socket close */
/* some protocols will have to call the underlying functions without regard to
what exact state the socket signals. IE even if the socket says "readable",
the send function might need to be called while uploading, or vice versa.
*/
#define PROTOPT_DIRLOCK (1 << 3)
#define PROTOPT_NONETWORK (1 << 4) /* protocol does not use the network! */
#define PROTOPT_NEEDSPWD (1 << 5) /* needs a password, and if none is set it
gets a default */
#define PROTOPT_NOURLQUERY (1 << 6) /* protocol cannot handle
URL query strings (?foo=bar) ! */
#define PROTOPT_CREDSPERREQUEST (1 << 7) /* requires login credentials per
request instead of per
connection */
#define PROTOPT_ALPN (1 << 8) /* set ALPN for this */
/* (1 << 9) was PROTOPT_STREAM, now free */
#define PROTOPT_URLOPTIONS (1 << 10) /* allow options part in the userinfo
field of the URL */
#define PROTOPT_PROXY_AS_HTTP (1 << 11) /* allow this non-HTTP scheme over a
HTTP proxy as HTTP proxies may know
this protocol and act as
a gateway */
#define PROTOPT_WILDCARD (1 << 12) /* protocol supports wildcard matching */
#define PROTOPT_USERPWDCTRL (1 << 13) /* Allow "control bytes" (< 32 ASCII) in
username and password */
#define PROTOPT_NOTCPPROXY (1 << 14) /* this protocol cannot proxy over TCP */
#define PROTOPT_SSL_REUSE (1 << 15) /* this protocol may reuse an existing
SSL connection in the same family
without having PROTOPT_SSL. */
#define PROTOPT_CONN_REUSE (1 << 16) /* this protocol can reuse connections */
/* Everything about a URI scheme. */
struct Curl_scheme {
const char *name; /* URL scheme name in lowercase */
const struct Curl_protocol *run; /* implementation, optional */
curl_prot_t protocol; /* See CURLPROTO_* - this needs to be the single
specific protocol bit */
curl_prot_t family; /* single bit for protocol family; the non-TLS name
of the protocol this is */
uint32_t flags; /* Extra particular characteristics, see PROTOPT_* */
uint16_t defport; /* Default port. */
};
/* Get scheme definition for a URI scheme name
* @param scheme URI scheme name, case-insensitive
* @return NULL if scheme is not known
*/
const struct Curl_scheme *Curl_get_scheme(const char *scheme);
const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len);
/* For direct access to a URI scheme */
extern const struct Curl_scheme Curl_scheme_dict;
extern const struct Curl_scheme Curl_scheme_file;
extern const struct Curl_scheme Curl_scheme_ftp;
extern const struct Curl_scheme Curl_scheme_ftps;
extern const struct Curl_scheme Curl_scheme_gopher;
extern const struct Curl_scheme Curl_scheme_gophers;
extern const struct Curl_scheme Curl_scheme_http;
extern const struct Curl_scheme Curl_scheme_https;
extern const struct Curl_scheme Curl_scheme_imap;
extern const struct Curl_scheme Curl_scheme_imaps;
extern const struct Curl_scheme Curl_scheme_ldap;
extern const struct Curl_scheme Curl_scheme_ldaps;
extern const struct Curl_scheme Curl_scheme_mqtt;
extern const struct Curl_scheme Curl_scheme_mqtts;
extern const struct Curl_scheme Curl_scheme_pop3;
extern const struct Curl_scheme Curl_scheme_pop3s;
extern const struct Curl_scheme Curl_scheme_rtmp;
extern const struct Curl_scheme Curl_scheme_rtmpe;
extern const struct Curl_scheme Curl_scheme_rtmpt;
extern const struct Curl_scheme Curl_scheme_rtmpte;
extern const struct Curl_scheme Curl_scheme_rtmps;
extern const struct Curl_scheme Curl_scheme_rtmpts;
extern const struct Curl_scheme Curl_scheme_rtsp;
extern const struct Curl_scheme Curl_scheme_scp;
extern const struct Curl_scheme Curl_scheme_sftp;
extern const struct Curl_scheme Curl_scheme_smb;
extern const struct Curl_scheme Curl_scheme_smbs;
extern const struct Curl_scheme Curl_scheme_smtp;
extern const struct Curl_scheme Curl_scheme_smtps;
extern const struct Curl_scheme Curl_scheme_telnet;
extern const struct Curl_scheme Curl_scheme_tftp;
extern const struct Curl_scheme Curl_scheme_ws;
extern const struct Curl_scheme Curl_scheme_wss;
#endif /* HEADER_CURL_PROTOCOL_H */

View File

@ -1051,7 +1051,7 @@ CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header)
/*
* RTSP handler interface.
*/
static const struct Curl_protocol Curl_protocol_rtsp = {
const struct Curl_protocol Curl_protocol_rtsp = {
rtsp_setup_connection, /* setup_connection */
rtsp_do, /* do_it */
rtsp_done, /* done */
@ -1072,19 +1072,3 @@ static const struct Curl_protocol Curl_protocol_rtsp = {
};
#endif /* CURL_DISABLE_RTSP */
/*
* RTSP handler interface.
*/
const struct Curl_scheme Curl_scheme_rtsp = {
"rtsp", /* scheme */
#ifdef CURL_DISABLE_RTSP
ZERO_NULL,
#else
&Curl_protocol_rtsp,
#endif
CURLPROTO_RTSP, /* protocol */
CURLPROTO_RTSP, /* family */
PROTOPT_CONN_REUSE, /* flags */
PORT_RTSP, /* defport */
};

View File

@ -23,9 +23,9 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_rtsp;
#ifndef CURL_DISABLE_RTSP
CURLcode Curl_rtsp_parseheader(struct Curl_easy *data, const char *header);
extern const struct Curl_protocol Curl_protocol_rtsp;
#else
#define Curl_rtsp_parseheader(x, y) CURLE_NOT_BUILT_IN
#endif

View File

@ -1208,7 +1208,7 @@ static CURLcode smb_do(struct Curl_easy *data, bool *done)
/*
* SMB handler interface
*/
static const struct Curl_protocol Curl_protocol_smb = {
const struct Curl_protocol Curl_protocol_smb = {
smb_setup_connection, /* setup_connection */
smb_do, /* do_it */
ZERO_NULL, /* done */
@ -1229,36 +1229,3 @@ static const struct Curl_protocol Curl_protocol_smb = {
};
#endif /* CURL_DISABLE_SMB && USE_CURL_NTLM_CORE && SIZEOF_CURL_OFF_T > 4 */
/*
* SMB handler interface
*/
const struct Curl_scheme Curl_scheme_smb = {
"smb", /* scheme */
#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE)
ZERO_NULL,
#else
&Curl_protocol_smb,
#endif
CURLPROTO_SMB, /* protocol */
CURLPROTO_SMB, /* family */
PROTOPT_CONN_REUSE, /* flags */
PORT_SMB, /* defport */
};
/*
* SMBS handler interface
*/
const struct Curl_scheme Curl_scheme_smbs = {
"smbs", /* scheme */
#if defined(CURL_DISABLE_SMB) || !defined(USE_CURL_NTLM_CORE) || \
!defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_smb,
#endif
CURLPROTO_SMBS, /* protocol */
CURLPROTO_SMB, /* family */
PROTOPT_SSL | PROTOPT_CONN_REUSE, /* flags */
PORT_SMBS, /* defport */
};

View File

@ -24,7 +24,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_smb;
extern const struct Curl_scheme Curl_scheme_smbs;
#if !defined(CURL_DISABLE_SMB) && defined(USE_CURL_NTLM_CORE)
extern const struct Curl_protocol Curl_protocol_smb;
#endif
#endif /* HEADER_CURL_SMB_H */

View File

@ -1984,7 +1984,7 @@ out:
/*
* SMTP protocol handler.
*/
static const struct Curl_protocol Curl_protocol_smtp = {
const struct Curl_protocol Curl_protocol_smtp = {
smtp_setup_connection, /* setup_connection */
smtp_do, /* do_it */
smtp_done, /* done */
@ -2005,37 +2005,3 @@ static const struct Curl_protocol Curl_protocol_smtp = {
};
#endif /* CURL_DISABLE_SMTP */
/*
* SMTP protocol handler.
*/
const struct Curl_scheme Curl_scheme_smtp = {
"smtp", /* scheme */
#ifdef CURL_DISABLE_SMTP
ZERO_NULL,
#else
&Curl_protocol_smtp,
#endif
CURLPROTO_SMTP, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_NOURLQUERY | /* flags */
PROTOPT_URLOPTIONS | PROTOPT_SSL_REUSE | PROTOPT_CONN_REUSE,
PORT_SMTP, /* defport */
};
/*
* SMTPS protocol handler.
*/
const struct Curl_scheme Curl_scheme_smtps = {
"smtps", /* scheme */
#if defined(CURL_DISABLE_SMTP) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_smtp,
#endif
CURLPROTO_SMTPS, /* protocol */
CURLPROTO_SMTP, /* family */
PROTOPT_CLOSEACTION | PROTOPT_SSL | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_URLOPTIONS | PROTOPT_CONN_REUSE,
PORT_SMTPS, /* defport */
};

View File

@ -23,7 +23,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_smtp;
extern const struct Curl_scheme Curl_scheme_smtps;
#ifndef CURL_DISABLE_SMTP
extern const struct Curl_protocol Curl_protocol_smtp;
#endif
#endif /* HEADER_CURL_SMTP_H */

View File

@ -1569,7 +1569,7 @@ static CURLcode telnet_do(struct Curl_easy *data, bool *done)
/*
* TELNET protocol handler.
*/
static const struct Curl_protocol Curl_protocol_telnet = {
const struct Curl_protocol Curl_protocol_telnet = {
ZERO_NULL, /* setup_connection */
telnet_do, /* do_it */
telnet_done, /* done */
@ -1590,19 +1590,3 @@ static const struct Curl_protocol Curl_protocol_telnet = {
};
#endif /* !CURL_DISABLE_TELNET */
/*
* TELNET protocol handler.
*/
const struct Curl_scheme Curl_scheme_telnet = {
"telnet", /* scheme */
#ifdef CURL_DISABLE_TELNET
ZERO_NULL,
#else
&Curl_protocol_telnet,
#endif
CURLPROTO_TELNET, /* protocol */
CURLPROTO_TELNET, /* family */
PROTOPT_NONE | PROTOPT_NOURLQUERY, /* flags */
PORT_TELNET, /* defport */
};

View File

@ -23,6 +23,8 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_telnet;
#ifndef CURL_DISABLE_TELNET
extern const struct Curl_protocol Curl_protocol_telnet;
#endif
#endif /* HEADER_CURL_TELNET_H */

View File

@ -1332,7 +1332,7 @@ static CURLcode tftp_setup_connection(struct Curl_easy *data,
/*
* TFTP protocol handler.
*/
static const struct Curl_protocol Curl_protocol_tftp = {
const struct Curl_protocol Curl_protocol_tftp = {
tftp_setup_connection, /* setup_connection */
tftp_do, /* do_it */
tftp_done, /* done */
@ -1353,19 +1353,3 @@ static const struct Curl_protocol Curl_protocol_tftp = {
};
#endif
/*
* TFTP protocol handler.
*/
const struct Curl_scheme Curl_scheme_tftp = {
"tftp", /* scheme */
#ifdef CURL_DISABLE_TFTP
ZERO_NULL,
#else
&Curl_protocol_tftp,
#endif
CURLPROTO_TFTP, /* protocol */
CURLPROTO_TFTP, /* family */
PROTOPT_NOTCPPROXY | PROTOPT_NOURLQUERY, /* flags */
PORT_TFTP, /* defport */
};

View File

@ -23,7 +23,9 @@
* SPDX-License-Identifier: curl
*
***************************************************************************/
extern const struct Curl_scheme Curl_scheme_tftp;
#ifndef CURL_DISABLE_TFTP
extern const struct Curl_protocol Curl_protocol_tftp;
#endif
#define TFTP_BLKSIZE_MIN 8
#define TFTP_BLKSIZE_MAX 65464

View File

@ -1433,80 +1433,6 @@ error:
return NULL;
}
const struct Curl_scheme *Curl_get_scheme(const char *scheme)
{
return Curl_getn_scheme(scheme, strlen(scheme));
}
/* Returns a struct scheme pointer if the name is a known scheme. Check the
->run struct field for non-NULL to figure out if an implementation is
present. */
const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len)
{
/* table generated by schemetable.c:
1. gcc schemetable.c && ./a.out
2. check how small the table gets
3. tweak the hash algorithm, then rerun from 1
4. when the table is good enough
5. copy the table into this source code
6. make sure this function uses the same hash function that worked for
schemetable.c
*/
static const struct Curl_scheme * const all_schemes[67] = {
&Curl_scheme_file,
&Curl_scheme_mqtts, NULL,
&Curl_scheme_gophers, NULL,
&Curl_scheme_rtmpe,
&Curl_scheme_smtp,
&Curl_scheme_sftp,
&Curl_scheme_smb,
&Curl_scheme_smtps,
&Curl_scheme_telnet,
&Curl_scheme_gopher,
&Curl_scheme_tftp, NULL, NULL, NULL,
&Curl_scheme_ftps,
&Curl_scheme_http,
&Curl_scheme_imap,
&Curl_scheme_rtmps,
&Curl_scheme_rtmpt, NULL, NULL, NULL,
&Curl_scheme_ldaps,
&Curl_scheme_wss,
&Curl_scheme_https, NULL, NULL, NULL, NULL, NULL, NULL, NULL, NULL,
&Curl_scheme_rtsp,
&Curl_scheme_smbs,
&Curl_scheme_scp, NULL, NULL, NULL,
&Curl_scheme_pop3, NULL, NULL,
&Curl_scheme_rtmp, NULL, NULL, NULL,
&Curl_scheme_rtmpte, NULL, NULL, NULL,
&Curl_scheme_dict, NULL, NULL, NULL,
&Curl_scheme_mqtt,
&Curl_scheme_pop3s,
&Curl_scheme_imaps, NULL,
&Curl_scheme_ws, NULL,
&Curl_scheme_rtmpts,
&Curl_scheme_ldap, NULL, NULL,
&Curl_scheme_ftp,
};
if(len && (len <= 7)) {
const char *s = scheme;
size_t l = len;
const struct Curl_scheme *h;
unsigned int c = 978;
while(l) {
c <<= 5;
c += (unsigned int)Curl_raw_tolower(*s);
s++;
l--;
}
h = all_schemes[c % 67];
if(h && curl_strnequal(scheme, h->name, len) && !h->name[len])
return h;
}
return NULL;
}
static CURLcode findprotocol(struct Curl_easy *data,
struct connectdata *conn,
const char *protostr)

View File

@ -69,13 +69,6 @@ CURLcode Curl_conn_meta_set(struct connectdata *conn, const char *key,
void Curl_conn_meta_remove(struct connectdata *conn, const char *key);
void *Curl_conn_meta_get(struct connectdata *conn, const char *key);
/* Get protocol handler for a URI scheme
* @param scheme URI scheme, case-insensitive
* @return NULL of handler not found
*/
const struct Curl_scheme *Curl_get_scheme(const char *scheme);
const struct Curl_scheme *Curl_getn_scheme(const char *scheme, size_t len);
#define CURL_DEFAULT_PROXY_PORT 1080 /* default proxy port unless specified */
#define CURL_DEFAULT_HTTPS_PROXY_PORT 443 /* default https proxy port unless
specified */

View File

@ -26,60 +26,6 @@
/* This file is for lib internal stuff */
#include "curl_setup.h"
#define PORT_FTP 21
#define PORT_FTPS 990
#define PORT_TELNET 23
#define PORT_HTTP 80
#define PORT_HTTPS 443
#define PORT_DICT 2628
#define PORT_LDAP 389
#define PORT_LDAPS 636
#define PORT_TFTP 69
#define PORT_SSH 22
#define PORT_IMAP 143
#define PORT_IMAPS 993
#define PORT_POP3 110
#define PORT_POP3S 995
#define PORT_SMB 445
#define PORT_SMBS 445
#define PORT_SMTP 25
#define PORT_SMTPS 465 /* sometimes called SSMTP */
#define PORT_RTSP 554
#define PORT_RTMP 1935
#define PORT_RTMPT PORT_HTTP
#define PORT_RTMPS PORT_HTTPS
#define PORT_GOPHER 70
#define PORT_MQTT 1883
#define PORT_MQTTS 8883
#ifndef CURL_DISABLE_WEBSOCKETS
/* CURLPROTO_GOPHERS (29) is the highest publicly used protocol bit number,
* the rest are internal information. If we use higher bits we only do this on
* platforms that have a >= 64-bit type and then we use such a type for the
* protocol fields in the protocol handler.
*/
#define CURLPROTO_WS (1L << 30)
#define CURLPROTO_WSS ((curl_prot_t)1 << 31)
#else
#define CURLPROTO_WS 0L
#define CURLPROTO_WSS 0L
#endif
#define CURLPROTO_MQTTS (1LL << 32)
#define CURLPROTO_64ALL ((uint64_t)0xffffffffffffffff)
/* the default protocols accepting a redirect to */
#define CURLPROTO_REDIR (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_FTP | \
CURLPROTO_FTPS)
typedef curl_off_t curl_prot_t;
/* This mask is for all the old protocols that are provided and defined in the
public header and shall exclude protocols added since which are not exposed
in the API */
#define CURLPROTO_MASK 0x3ffffff
#define CURL_DEFAULT_USER "anonymous"
#define CURL_DEFAULT_PASSWORD "ftp@example.com"
@ -89,23 +35,6 @@ typedef curl_off_t curl_prot_t;
#define CURL_PREFER_LF_LINEENDS
#endif
/* Convenience defines for checking protocols or their SSL based version. Each
protocol handler should only ever have a single CURLPROTO_ in its protocol
field. */
#define PROTO_FAMILY_HTTP (CURLPROTO_HTTP | CURLPROTO_HTTPS | CURLPROTO_WS | \
CURLPROTO_WSS)
#define PROTO_FAMILY_FTP (CURLPROTO_FTP | CURLPROTO_FTPS)
#define PROTO_FAMILY_POP3 (CURLPROTO_POP3 | CURLPROTO_POP3S)
#define PROTO_FAMILY_SMB (CURLPROTO_SMB | CURLPROTO_SMBS)
#define PROTO_FAMILY_SMTP (CURLPROTO_SMTP | CURLPROTO_SMTPS)
#define PROTO_FAMILY_SSH (CURLPROTO_SCP | CURLPROTO_SFTP)
#if !defined(CURL_DISABLE_FTP) || defined(USE_SSH) || \
!defined(CURL_DISABLE_POP3)
/* these protocols support CURLOPT_DIRLISTONLY */
#define CURL_LIST_ONLY_PROTOCOL 1
#endif
#define DEFAULT_CONNCACHE_SIZE 5
/* length of longest IPv6 address string including the trailing null */
@ -155,6 +84,7 @@ typedef CURLcode (Curl_recv)(struct Curl_easy *data, /* transfer */
size_t *pnread); /* how much received */
#include "mime.h"
#include "protocol.h"
#include "ftp.h"
#include "http.h"
#include "smb.h"
@ -391,140 +321,6 @@ struct hostname {
#define FIRSTSOCKET 0
#define SECONDARYSOCKET 1
/*
* Specific protocol handler.
*/
struct Curl_protocol {
/* Complement to setup_connection_internals(). This is done before the
transfer "owns" the connection. */
CURLcode (*setup_connection)(struct Curl_easy *data,
struct connectdata *conn);
/* These two functions MUST be set to be protocol dependent */
CURLcode (*do_it)(struct Curl_easy *data, bool *done);
CURLcode (*done)(struct Curl_easy *, CURLcode, bool);
/* 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.
*/
CURLcode (*do_more)(struct Curl_easy *, int *);
/* 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 does not complete, the caller
* should call the ->connecting() function until it is.
*/
CURLcode (*connect_it)(struct Curl_easy *data, bool *done);
/* See above. */
CURLcode (*connecting)(struct Curl_easy *data, bool *done);
CURLcode (*doing)(struct Curl_easy *data, bool *done);
/* Called from the multi interface during the PROTOCONNECT phase, and it
should then return a proper fd set */
CURLcode (*proto_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* Called from the multi interface during the DOING phase, and it should
then return a proper fd set */
CURLcode (*doing_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* Called from the multi interface during the DO_MORE phase, and it should
then return a proper fd set */
CURLcode (*domore_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* Called from the multi interface during the DO_DONE, PERFORM and
WAITPERFORM phases, and it should then return a proper fd set. Not setting
this will make libcurl use the generic default one. */
CURLcode (*perform_pollset)(struct Curl_easy *data,
struct easy_pollset *ps);
/* This function *MAY* be set to a protocol-dependent function that is run
* by the curl_disconnect(), as a step in the disconnection. If the handler
* is called because the connection has been considered dead,
* dead_connection is set to TRUE. The connection is (again) associated with
* the transfer here.
*/
CURLcode (*disconnect)(struct Curl_easy *, struct connectdata *,
bool dead_connection);
/* If used, this function gets called from transfer.c to
allow the protocol to do extra handling in writing response to
the client. */
CURLcode (*write_resp)(struct Curl_easy *data, const char *buf, size_t blen,
bool is_eos);
/* If used, this function gets called from transfer.c to
allow the protocol to do extra handling in writing a single response
header line to the client. */
CURLcode (*write_resp_hd)(struct Curl_easy *data,
const char *hd, size_t hdlen, bool is_eos);
/* If used, this function checks for a connection managed by this
protocol and currently not in use, if it should be considered dead. */
bool (*connection_is_dead)(struct Curl_easy *data,
struct connectdata *conn);
/* attach() attaches this transfer to this connection */
void (*attach)(struct Curl_easy *data, struct connectdata *conn);
/* return CURLE_OK if a redirect to `newurl` should be followed,
CURLE_TOO_MANY_REDIRECTS otherwise. May alter `data` to change
the way the follow request is performed. */
CURLcode (*follow)(struct Curl_easy *data, const char *newurl,
followtype type);
};
struct Curl_scheme {
const char *name; /* URL scheme name in lowercase */
const struct Curl_protocol *run; /* implementation */
curl_prot_t protocol; /* See CURLPROTO_* - this needs to be the single
specific protocol bit */
curl_prot_t family; /* single bit for protocol family; the non-TLS name
of the protocol this is */
uint32_t flags; /* Extra particular characteristics, see PROTOPT_* */
uint16_t defport; /* Default port. */
};
#define PROTOPT_NONE 0 /* nothing extra */
#define PROTOPT_SSL (1 << 0) /* uses SSL */
#define PROTOPT_DUAL (1 << 1) /* this protocol uses two connections */
#define PROTOPT_CLOSEACTION (1 << 2) /* need action before socket close */
/* some protocols will have to call the underlying functions without regard to
what exact state the socket signals. IE even if the socket says "readable",
the send function might need to be called while uploading, or vice versa.
*/
#define PROTOPT_DIRLOCK (1 << 3)
#define PROTOPT_NONETWORK (1 << 4) /* protocol does not use the network! */
#define PROTOPT_NEEDSPWD (1 << 5) /* needs a password, and if none is set it
gets a default */
#define PROTOPT_NOURLQUERY (1 << 6) /* protocol cannot handle
URL query strings (?foo=bar) ! */
#define PROTOPT_CREDSPERREQUEST (1 << 7) /* requires login credentials per
request instead of per
connection */
#define PROTOPT_ALPN (1 << 8) /* set ALPN for this */
/* (1 << 9) was PROTOPT_STREAM, now free */
#define PROTOPT_URLOPTIONS (1 << 10) /* allow options part in the userinfo
field of the URL */
#define PROTOPT_PROXY_AS_HTTP (1 << 11) /* allow this non-HTTP scheme over a
HTTP proxy as HTTP proxies may know
this protocol and act as
a gateway */
#define PROTOPT_WILDCARD (1 << 12) /* protocol supports wildcard matching */
#define PROTOPT_USERPWDCTRL (1 << 13) /* Allow "control bytes" (< 32 ASCII) in
username and password */
#define PROTOPT_NOTCPPROXY (1 << 14) /* this protocol cannot proxy over TCP */
#define PROTOPT_SSL_REUSE (1 << 15) /* this protocol may reuse an existing
SSL connection in the same family
without having PROTOPT_SSL. */
#define PROTOPT_CONN_REUSE (1 << 16) /* this protocol can reuse connections */
#define TRNSPRT_NONE 0
#define TRNSPRT_TCP 3
#define TRNSPRT_UDP 4

View File

@ -29,9 +29,6 @@
extern const struct Curl_protocol Curl_protocol_sftp;
extern const struct Curl_protocol Curl_protocol_scp;
extern const struct Curl_scheme Curl_scheme_sftp;
extern const struct Curl_scheme Curl_scheme_scp;
#ifdef USE_SSH
#ifdef USE_LIBSSH2

View File

@ -331,34 +331,3 @@ CURLcode Curl_ssh_range(struct Curl_easy *data,
}
#endif /* USE_SSH */
/*
* SFTP protocol handler.
*/
const struct Curl_scheme Curl_scheme_sftp = {
"SFTP", /* scheme */
#ifndef USE_SSH
NULL,
#else
&Curl_protocol_sftp,
#endif
CURLPROTO_SFTP, /* protocol */
CURLPROTO_SFTP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
PORT_SSH /* defport */
};
const struct Curl_scheme Curl_scheme_scp = {
"SCP", /* scheme */
#ifndef USE_SSH
NULL,
#else
&Curl_protocol_scp,
#endif
CURLPROTO_SCP, /* protocol */
CURLPROTO_SCP, /* family */
PROTOPT_DIRLOCK | PROTOPT_CLOSEACTION | /* flags */
PROTOPT_NOURLQUERY | PROTOPT_CONN_REUSE,
PORT_SSH, /* defport */
};

View File

@ -1915,7 +1915,7 @@ out:
return result;
}
static const struct Curl_protocol Curl_protocol_ws = {
const struct Curl_protocol Curl_protocol_ws = {
ws_setup_conn, /* setup_connection */
Curl_http, /* do_it */
Curl_http_done, /* done */
@ -1980,32 +1980,3 @@ CURL_EXTERN CURLcode curl_ws_start_frame(CURL *curl,
}
#endif /* !CURL_DISABLE_WEBSOCKETS */
const struct Curl_scheme Curl_scheme_ws = {
"WS", /* scheme */
#ifdef CURL_DISABLE_WEBSOCKETS
ZERO_NULL,
#else
&Curl_protocol_ws,
#endif
CURLPROTO_WS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL,
PORT_HTTP /* defport */
}
;
const struct Curl_scheme Curl_scheme_wss = {
"WSS", /* scheme */
#if defined(CURL_DISABLE_WEBSOCKETS) || !defined(USE_SSL)
ZERO_NULL,
#else
&Curl_protocol_ws,
#endif
CURLPROTO_WSS, /* protocol */
CURLPROTO_HTTP, /* family */
PROTOPT_SSL | PROTOPT_CREDSPERREQUEST | /* flags */
PROTOPT_USERPWDCTRL,
PORT_HTTPS /* defport */
};

View File

@ -25,11 +25,10 @@
***************************************************************************/
#include "curl_setup.h"
extern const struct Curl_scheme Curl_scheme_ws;
extern const struct Curl_scheme Curl_scheme_wss;
#if !defined(CURL_DISABLE_WEBSOCKETS) && !defined(CURL_DISABLE_HTTP)
extern const struct Curl_protocol Curl_protocol_ws;
/* meta key for storing protocol meta at connection */
#define CURL_META_PROTO_WS_CONN "meta:proto:ws:conn"