mirror of
https://github.com/openssl/openssl.git
synced 2024-11-24 02:23:51 +08:00
Generalize schmeme parsing of OSSL_HTTP_parse_url() to OSSL_parse_url()
Reviewed-by: Richard Levitte <levitte@openssl.org> (Merged from https://github.com/openssl/openssl/pull/14009)
This commit is contained in:
parent
7932982b88
commit
d546e8e267
@ -757,7 +757,7 @@ HTTP_R_FAILED_READING_DATA:128:failed reading data
|
||||
HTTP_R_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length
|
||||
HTTP_R_INVALID_PORT_NUMBER:123:invalid port number
|
||||
HTTP_R_INVALID_URL_PATH:125:invalid url path
|
||||
HTTP_R_INVALID_URL_PREFIX:124:invalid url prefix
|
||||
HTTP_R_INVALID_URL_SCHEME:124:invalid url scheme
|
||||
HTTP_R_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded
|
||||
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
||||
HTTP_R_MISSING_CONTENT_TYPE:121:missing content type
|
||||
|
@ -32,8 +32,8 @@ static const ERR_STRING_DATA HTTP_str_reasons[] = {
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER),
|
||||
"invalid port number"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PATH), "invalid url path"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PREFIX),
|
||||
"invalid url prefix"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_SCHEME),
|
||||
"invalid url scheme"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED),
|
||||
"max resp len exceeded"},
|
||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING),
|
||||
|
@ -36,21 +36,21 @@ static void free_pstring(char **pstr)
|
||||
}
|
||||
}
|
||||
|
||||
int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
char **ppath, char **pquery, char **pfrag)
|
||||
int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
char **ppath, char **pquery, char **pfrag)
|
||||
{
|
||||
const char *p, *tmp;
|
||||
const char *scheme, *scheme_end;
|
||||
const char *user, *user_end;
|
||||
const char *host, *host_end;
|
||||
const char *port = OSSL_HTTP_PORT, *port_end;
|
||||
const char *port, *port_end;
|
||||
unsigned int portnum;
|
||||
const char *path, *path_end;
|
||||
const char *query, *query_end;
|
||||
const char *frag, *frag_end;
|
||||
|
||||
if (pssl != NULL)
|
||||
*pssl = 0;
|
||||
init_pstring(pscheme);
|
||||
init_pstring(puser);
|
||||
init_pstring(phost);
|
||||
init_pstring(pport);
|
||||
@ -63,19 +63,15 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* check for optional prefix "http[s]://" */
|
||||
/* check for optional prefix "<scheme>://" */
|
||||
scheme = scheme_end = url;
|
||||
p = strstr(url, "://");
|
||||
if (p == NULL) {
|
||||
p = url;
|
||||
} else { /* p points to end of scheme name */
|
||||
if (strncmp(url, OSSL_HTTPS_NAME, strlen(OSSL_HTTPS_NAME)) == 0) {
|
||||
if (pssl != NULL)
|
||||
*pssl = 1;
|
||||
port = OSSL_HTTPS_PORT;
|
||||
} else if (strncmp(url, OSSL_HTTP_NAME, strlen(OSSL_HTTP_NAME)) != 0) {
|
||||
ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_URL_PREFIX);
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
scheme_end = p;
|
||||
if (scheme_end == scheme)
|
||||
goto parse_err;
|
||||
p += strlen("://");
|
||||
}
|
||||
|
||||
@ -110,11 +106,12 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
}
|
||||
|
||||
/* parse optional port specification starting with ':' */
|
||||
port = "0"; /* default */
|
||||
if (*p == ':')
|
||||
port = ++p;
|
||||
/* remaining port spec handling is also done for the default values */
|
||||
/* make sure a decimal port number is given */
|
||||
if (!sscanf(port, "%u", &portnum) || portnum < 1 || portnum > 65535) {
|
||||
if (!sscanf(port, "%u", &portnum) || portnum > 65535) {
|
||||
ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
@ -150,7 +147,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
frag = tmp + 1;
|
||||
}
|
||||
|
||||
if (!copy_substring(phost, host, host_end)
|
||||
if (!copy_substring(pscheme, scheme, scheme_end)
|
||||
|| !copy_substring(phost, host, host_end)
|
||||
|| !copy_substring(pport, port, port_end)
|
||||
|| !copy_substring(puser, user, user_end)
|
||||
|| !copy_substring(pquery, query, query_end)
|
||||
@ -174,6 +172,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_URL);
|
||||
|
||||
err:
|
||||
free_pstring(pscheme);
|
||||
free_pstring(puser);
|
||||
free_pstring(phost);
|
||||
free_pstring(pport);
|
||||
free_pstring(ppath);
|
||||
@ -182,6 +182,63 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
return 0;
|
||||
}
|
||||
|
||||
int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
char **ppath, char **pquery, char **pfrag)
|
||||
{
|
||||
char *scheme, *port;
|
||||
int ssl = 0, portnum;
|
||||
|
||||
init_pstring(pport);
|
||||
if (pssl != NULL)
|
||||
*pssl = 0;
|
||||
if (!OSSL_parse_url(url, &scheme, puser, phost, &port, pport_num,
|
||||
ppath, pquery, pfrag))
|
||||
return 0;
|
||||
|
||||
/* check for optional HTTP scheme "http[s]" */
|
||||
if (strcmp(scheme, OSSL_HTTPS_NAME) == 0) {
|
||||
ssl = 1;
|
||||
if (pssl != NULL)
|
||||
*pssl = ssl;
|
||||
} else if (*scheme != '\0' && strcmp(scheme, OSSL_HTTP_NAME) != 0) {
|
||||
ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_URL_SCHEME);
|
||||
OPENSSL_free(scheme);
|
||||
OPENSSL_free(port);
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(scheme);
|
||||
|
||||
if (strcmp(port, "0") == 0) {
|
||||
/* set default port */
|
||||
OPENSSL_free(port);
|
||||
port = ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
|
||||
if (!ossl_assert(sscanf(port, "%d", &portnum) == 1))
|
||||
goto err;
|
||||
if (pport_num != NULL)
|
||||
*pport_num = portnum;
|
||||
if (pport != NULL) {
|
||||
*pport = OPENSSL_strdup(port);
|
||||
if (*pport == NULL)
|
||||
goto err;
|
||||
}
|
||||
} else {
|
||||
if (pport != NULL)
|
||||
*pport = port;
|
||||
else
|
||||
OPENSSL_free(port);
|
||||
}
|
||||
return 1;
|
||||
|
||||
err:
|
||||
free_pstring(puser);
|
||||
free_pstring(phost);
|
||||
free_pstring(ppath);
|
||||
free_pstring(pquery);
|
||||
free_pstring(pfrag);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int http_use_proxy(const char *no_proxy, const char *server)
|
||||
{
|
||||
size_t sl;
|
||||
|
@ -2,6 +2,7 @@
|
||||
|
||||
=head1 NAME
|
||||
|
||||
OSSL_parse_url,
|
||||
OSSL_HTTP_parse_url,
|
||||
OCSP_parse_url
|
||||
- http utility functions
|
||||
@ -10,6 +11,9 @@ OCSP_parse_url
|
||||
|
||||
#include <openssl/http.h>
|
||||
|
||||
int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
char **ppath, char **pquery, char **pfrag);
|
||||
int OSSL_HTTP_parse_url(const char *url,
|
||||
int *pssl, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
@ -24,28 +28,34 @@ L<openssl_user_macros(7)>:
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
OSSL_HTTP_parse_url() parses its input string I<url> as a URL of the form
|
||||
C<[http[s]://][userinfo@]host[:port][/path][?query][#fragment]> and splits it up
|
||||
into userinfo, host, port, path, query, and fragment components
|
||||
and a flag indicating whether it begins with C<https>.
|
||||
OSSL_parse_url() parses its input string I<url> as a URL of the form
|
||||
C<[scheme://][userinfo@]host[:port][/path][?query][#fragment]> and splits it up
|
||||
into scheme, userinfo, host, port, path, query, and fragment components.
|
||||
The host component may be a DNS name or an IP address
|
||||
where IPv6 addresses should be enclosed in square brackets C<[> and C<]>.
|
||||
The port component is optional and defaults to "443" for HTTPS, else "80".
|
||||
The port component is optional and defaults to C<0>.
|
||||
If given, it must be in decimal form. If the I<pport_num> argument is not NULL
|
||||
the integer value of the port number is assigned to I<*pport_num> on success.
|
||||
The path component is also optional and defaults to C</>.
|
||||
If I<pssl> is not NULL, I<*pssl> is assigned 1 in case parsing was successful
|
||||
and the schema part is present and is C<https>, else 0.
|
||||
Each non-NULL result pointer argument I<puser>, I<phost>, I<pport>, I<ppath>,
|
||||
I<pquery>, and I<pfrag>, is assigned the respective url component.
|
||||
Each non-NULL result pointer argument I<pscheme>, I<puser>, I<phost>, I<pport>,
|
||||
I<ppath>, I<pquery>, and I<pfrag>, is assigned the respective url component.
|
||||
On success, they are guaranteed to contain non-NULL string pointers, else NULL.
|
||||
It is the reponsibility of the caller to free them using L<OPENSSL_free(3)>.
|
||||
If I<pquery> is NULL, any given query component is handled as part of the path.
|
||||
A string returned via I<*ppath> is guaranteed to begin with a C</> character.
|
||||
For absent userinfo, query, and fragment components an empty string is given.
|
||||
For absent scheme, userinfo, port, query, and fragment components
|
||||
an empty string is provided.
|
||||
|
||||
Calling the deprecated fucntion OCSP_parse_url(url, host, port, path, ssl) is
|
||||
equivalent to OSSL_HTTP_parse_url(url, ssl, NULL, host, port, NULL, path, NULL, NULL).
|
||||
OSSL_HTTP_parse_url() is a special form of OSSL_parse_url()
|
||||
where the scheme, if given, must be C<http> or C<https>.
|
||||
If I<pssl> is not NULL, I<*pssl> is assigned 1 in case parsing was successful
|
||||
and the scheme is C<https>, else 0.
|
||||
The port component is optional and defaults to C<443> if the scheme is C<https>,
|
||||
else C<80>.
|
||||
|
||||
Calling the deprecated function OCSP_parse_url(url, host, port, path, ssl)
|
||||
is equivalent to
|
||||
OSSL_HTTP_parse_url(url, ssl, NULL, host, port, NULL, path, NULL, NULL).
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
|
@ -96,6 +96,9 @@ int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port,
|
||||
const char *proxyuser, const char *proxypass,
|
||||
int timeout, BIO *bio_err, const char *prog);
|
||||
|
||||
int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
char **ppath, char **pquery, char **pfrag);
|
||||
int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||
char **pport, int *pport_num,
|
||||
char **ppath, char **pquery, char **pfrag);
|
||||
|
@ -32,7 +32,7 @@
|
||||
# define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120
|
||||
# define HTTP_R_INVALID_PORT_NUMBER 123
|
||||
# define HTTP_R_INVALID_URL_PATH 125
|
||||
# define HTTP_R_INVALID_URL_PREFIX 124
|
||||
# define HTTP_R_INVALID_URL_SCHEME 124
|
||||
# define HTTP_R_MAX_RESP_LEN_EXCEEDED 117
|
||||
# define HTTP_R_MISSING_ASN1_ENCODING 110
|
||||
# define HTTP_R_MISSING_CONTENT_TYPE 121
|
||||
|
@ -4880,6 +4880,7 @@ ASN1_item_verify_ex ? 3_0_0 EXIST::FUNCTION:
|
||||
BIO_socket_wait ? 3_0_0 EXIST::FUNCTION:SOCK
|
||||
BIO_wait ? 3_0_0 EXIST::FUNCTION:
|
||||
BIO_do_connect_retry ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_parse_url ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_HTTP_get ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_HTTP_get_asn1 ? 3_0_0 EXIST::FUNCTION:
|
||||
OSSL_HTTP_post_asn1 ? 3_0_0 EXIST::FUNCTION:
|
||||
|
Loading…
Reference in New Issue
Block a user