mirror of
https://github.com/QuasarApp/openssl.git
synced 2025-05-03 21:19:39 +00: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_INCONSISTENT_CONTENT_LENGTH:120:inconsistent content length
|
||||||
HTTP_R_INVALID_PORT_NUMBER:123:invalid port number
|
HTTP_R_INVALID_PORT_NUMBER:123:invalid port number
|
||||||
HTTP_R_INVALID_URL_PATH:125:invalid url path
|
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_MAX_RESP_LEN_EXCEEDED:117:max resp len exceeded
|
||||||
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
HTTP_R_MISSING_ASN1_ENCODING:110:missing asn1 encoding
|
||||||
HTTP_R_MISSING_CONTENT_TYPE:121:missing content type
|
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),
|
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_PORT_NUMBER),
|
||||||
"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_PATH), "invalid url path"},
|
||||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_PREFIX),
|
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_INVALID_URL_SCHEME),
|
||||||
"invalid url prefix"},
|
"invalid url scheme"},
|
||||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED),
|
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MAX_RESP_LEN_EXCEEDED),
|
||||||
"max resp len exceeded"},
|
"max resp len exceeded"},
|
||||||
{ERR_PACK(ERR_LIB_HTTP, 0, HTTP_R_MISSING_ASN1_ENCODING),
|
{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,
|
int OSSL_parse_url(const char *url, char **pscheme, char **puser, char **phost,
|
||||||
char **pport, int *pport_num,
|
char **pport, int *pport_num,
|
||||||
char **ppath, char **pquery, char **pfrag)
|
char **ppath, char **pquery, char **pfrag)
|
||||||
{
|
{
|
||||||
const char *p, *tmp;
|
const char *p, *tmp;
|
||||||
|
const char *scheme, *scheme_end;
|
||||||
const char *user, *user_end;
|
const char *user, *user_end;
|
||||||
const char *host, *host_end;
|
const char *host, *host_end;
|
||||||
const char *port = OSSL_HTTP_PORT, *port_end;
|
const char *port, *port_end;
|
||||||
unsigned int portnum;
|
unsigned int portnum;
|
||||||
const char *path, *path_end;
|
const char *path, *path_end;
|
||||||
const char *query, *query_end;
|
const char *query, *query_end;
|
||||||
const char *frag, *frag_end;
|
const char *frag, *frag_end;
|
||||||
|
|
||||||
if (pssl != NULL)
|
init_pstring(pscheme);
|
||||||
*pssl = 0;
|
|
||||||
init_pstring(puser);
|
init_pstring(puser);
|
||||||
init_pstring(phost);
|
init_pstring(phost);
|
||||||
init_pstring(pport);
|
init_pstring(pport);
|
||||||
@ -63,19 +63,15 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* check for optional prefix "http[s]://" */
|
/* check for optional prefix "<scheme>://" */
|
||||||
|
scheme = scheme_end = url;
|
||||||
p = strstr(url, "://");
|
p = strstr(url, "://");
|
||||||
if (p == NULL) {
|
if (p == NULL) {
|
||||||
p = url;
|
p = url;
|
||||||
} else { /* p points to end of scheme name */
|
} else {
|
||||||
if (strncmp(url, OSSL_HTTPS_NAME, strlen(OSSL_HTTPS_NAME)) == 0) {
|
scheme_end = p;
|
||||||
if (pssl != NULL)
|
if (scheme_end == scheme)
|
||||||
*pssl = 1;
|
goto parse_err;
|
||||||
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;
|
|
||||||
}
|
|
||||||
p += strlen("://");
|
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 ':' */
|
/* parse optional port specification starting with ':' */
|
||||||
|
port = "0"; /* default */
|
||||||
if (*p == ':')
|
if (*p == ':')
|
||||||
port = ++p;
|
port = ++p;
|
||||||
/* remaining port spec handling is also done for the default values */
|
/* remaining port spec handling is also done for the default values */
|
||||||
/* make sure a decimal port number is given */
|
/* 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);
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_INVALID_PORT_NUMBER);
|
||||||
goto err;
|
goto err;
|
||||||
}
|
}
|
||||||
@ -150,7 +147,8 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
|||||||
frag = tmp + 1;
|
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(pport, port, port_end)
|
||||||
|| !copy_substring(puser, user, user_end)
|
|| !copy_substring(puser, user, user_end)
|
||||||
|| !copy_substring(pquery, query, query_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_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_URL);
|
||||||
|
|
||||||
err:
|
err:
|
||||||
|
free_pstring(pscheme);
|
||||||
|
free_pstring(puser);
|
||||||
free_pstring(phost);
|
free_pstring(phost);
|
||||||
free_pstring(pport);
|
free_pstring(pport);
|
||||||
free_pstring(ppath);
|
free_pstring(ppath);
|
||||||
@ -182,6 +182,63 @@ int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
|||||||
return 0;
|
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)
|
int http_use_proxy(const char *no_proxy, const char *server)
|
||||||
{
|
{
|
||||||
size_t sl;
|
size_t sl;
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
=head1 NAME
|
=head1 NAME
|
||||||
|
|
||||||
|
OSSL_parse_url,
|
||||||
OSSL_HTTP_parse_url,
|
OSSL_HTTP_parse_url,
|
||||||
OCSP_parse_url
|
OCSP_parse_url
|
||||||
- http utility functions
|
- http utility functions
|
||||||
@ -10,6 +11,9 @@ OCSP_parse_url
|
|||||||
|
|
||||||
#include <openssl/http.h>
|
#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 OSSL_HTTP_parse_url(const char *url,
|
||||||
int *pssl, char **puser, char **phost,
|
int *pssl, char **puser, char **phost,
|
||||||
char **pport, int *pport_num,
|
char **pport, int *pport_num,
|
||||||
@ -24,28 +28,34 @@ L<openssl_user_macros(7)>:
|
|||||||
|
|
||||||
=head1 DESCRIPTION
|
=head1 DESCRIPTION
|
||||||
|
|
||||||
OSSL_HTTP_parse_url() parses its input string I<url> as a URL of the form
|
OSSL_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
|
C<[scheme://][userinfo@]host[:port][/path][?query][#fragment]> and splits it up
|
||||||
into userinfo, host, port, path, query, and fragment components
|
into scheme, userinfo, host, port, path, query, and fragment components.
|
||||||
and a flag indicating whether it begins with C<https>.
|
|
||||||
The host component may be a DNS name or an IP address
|
The host component may be a DNS name or an IP address
|
||||||
where IPv6 addresses should be enclosed in square brackets C<[> and C<]>.
|
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
|
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 integer value of the port number is assigned to I<*pport_num> on success.
|
||||||
The path component is also optional and defaults to C</>.
|
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
|
Each non-NULL result pointer argument I<pscheme>, I<puser>, I<phost>, I<pport>,
|
||||||
and the schema part is present and is C<https>, else 0.
|
I<ppath>, I<pquery>, and I<pfrag>, is assigned the respective url component.
|
||||||
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.
|
|
||||||
On success, they are guaranteed to contain non-NULL string pointers, else NULL.
|
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)>.
|
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.
|
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.
|
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
|
OSSL_HTTP_parse_url() is a special form of OSSL_parse_url()
|
||||||
equivalent to OSSL_HTTP_parse_url(url, ssl, NULL, host, port, NULL, path, NULL, NULL).
|
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
|
=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,
|
const char *proxyuser, const char *proxypass,
|
||||||
int timeout, BIO *bio_err, const char *prog);
|
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,
|
int OSSL_HTTP_parse_url(const char *url, int *pssl, char **puser, char **phost,
|
||||||
char **pport, int *pport_num,
|
char **pport, int *pport_num,
|
||||||
char **ppath, char **pquery, char **pfrag);
|
char **ppath, char **pquery, char **pfrag);
|
||||||
|
@ -32,7 +32,7 @@
|
|||||||
# define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120
|
# define HTTP_R_INCONSISTENT_CONTENT_LENGTH 120
|
||||||
# define HTTP_R_INVALID_PORT_NUMBER 123
|
# define HTTP_R_INVALID_PORT_NUMBER 123
|
||||||
# define HTTP_R_INVALID_URL_PATH 125
|
# 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_MAX_RESP_LEN_EXCEEDED 117
|
||||||
# define HTTP_R_MISSING_ASN1_ENCODING 110
|
# define HTTP_R_MISSING_ASN1_ENCODING 110
|
||||||
# define HTTP_R_MISSING_CONTENT_TYPE 121
|
# 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_socket_wait ? 3_0_0 EXIST::FUNCTION:SOCK
|
||||||
BIO_wait ? 3_0_0 EXIST::FUNCTION:
|
BIO_wait ? 3_0_0 EXIST::FUNCTION:
|
||||||
BIO_do_connect_retry ? 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 ? 3_0_0 EXIST::FUNCTION:
|
||||||
OSSL_HTTP_get_asn1 ? 3_0_0 EXIST::FUNCTION:
|
OSSL_HTTP_get_asn1 ? 3_0_0 EXIST::FUNCTION:
|
||||||
OSSL_HTTP_post_asn1 ? 3_0_0 EXIST::FUNCTION:
|
OSSL_HTTP_post_asn1 ? 3_0_0 EXIST::FUNCTION:
|
||||||
|
Loading…
x
Reference in New Issue
Block a user