diff options
author | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2019-10-30 23:39:35 +0100 |
---|---|---|
committer | Dr. David von Oheimb <David.von.Oheimb@siemens.com> | 2020-02-10 16:49:37 +0100 |
commit | 29f178bddfdbd11218fbcba0b8060297696968e3 (patch) | |
tree | a44efcd919c122d9c6ff38c61b14676b002aa010 /crypto/http/http_lib.c | |
parent | bcbb30afe2ef51c7affaaa7ce4db67e26e7ff6b7 (diff) |
Generalize the HTTP client so far implemented mostly in crypto/ocsp/ocsp_ht.c
The new client has become an independent libcrpyto module in crypto/http/ and
* can handle any types of requests and responses (ASN.1-encoded and plain)
* does not include potentially busy loops when waiting for responses but
* makes use of a new timeout mechanism integrated with socket-based BIO
* supports the use of HTTP proxies and TLS, including HTTPS over proxies
* supports HTTP redirection via codes 301 and 302 for GET requests
* returns more useful diagnostics in various error situations
Also adapts - and strongly simplifies - hitherto uses of HTTP in crypto/ocsp/,
crypto/x509/x_all.c, apps/lib/apps.c, and apps/{ocsp,s_client,s_server}.c
Reviewed-by: Matt Caswell <matt@openssl.org>
Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com>
(Merged from https://github.com/openssl/openssl/pull/10667)
Diffstat (limited to 'crypto/http/http_lib.c')
-rw-r--r-- | crypto/http/http_lib.c | 116 |
1 files changed, 116 insertions, 0 deletions
diff --git a/crypto/http/http_lib.c b/crypto/http/http_lib.c new file mode 100644 index 0000000000..1d7ad0422a --- /dev/null +++ b/crypto/http/http_lib.c @@ -0,0 +1,116 @@ +/* + * Copyright 2001-2020 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include <openssl/http.h> +#include <openssl/httperr.h> +#include <openssl/err.h> +#include <string.h> + +/* + * Parse a URL and split it up into host, port and path components and + * whether it indicates SSL/TLS. Return 1 on success, 0 on error. + */ + +int OSSL_HTTP_parse_url(const char *url, char **phost, char **pport, + char **ppath, int *pssl) +{ + char *p, *buf; + char *host; + char *port = "80"; + + if (url == NULL) { + HTTPerr(0, ERR_R_PASSED_NULL_PARAMETER); + return 0; + } + + if (phost != NULL) + *phost = NULL; + if (pport != NULL) + *pport = NULL; + if (ppath != NULL) + *ppath = NULL; + if (pssl != NULL) + *pssl = 0; + + /* dup the buffer since we are going to mess with it */ + if ((buf = OPENSSL_strdup(url)) == NULL) + goto err; + + /* Check for initial colon */ + p = strchr(buf, ':'); + if (p == NULL || p - buf > 5 /* strlen("https") */) { + p = buf; + } else { + *(p++) = '\0'; + + if (strcmp(buf, "https") == 0) { + if (pssl != NULL) + *pssl = 1; + port = "443"; + } else if (strcmp(buf, "http") != 0) { + goto parse_err; + } + + /* Check for double slash */ + if ((p[0] != '/') || (p[1] != '/')) + goto parse_err; + p += 2; + } + host = p; + + /* Check for trailing part of path */ + p = strchr(p, '/'); + if (ppath != NULL && (*ppath = OPENSSL_strdup(p == NULL ? "/" : p)) == NULL) + goto err; + if (p != NULL) + *p = '\0'; /* Set start of path to 0 so hostname[:port] is valid */ + + p = host; + if (host[0] == '[') { + /* ipv6 literal */ + host++; + p = strchr(host, ']'); + if (p == NULL) + goto parse_err; + *p = '\0'; + p++; + } + + /* Look for optional ':' for port number */ + if ((p = strchr(p, ':'))) { + *p = '\0'; + port = p + 1; + } + if (phost != NULL && (*phost = OPENSSL_strdup(host)) == NULL) + goto err; + if (pport != NULL && (*pport = OPENSSL_strdup(port)) == NULL) + goto err; + + OPENSSL_free(buf); + return 1; + + parse_err: + HTTPerr(0, HTTP_R_ERROR_PARSING_URL); + + err: + if (ppath != NULL) { + OPENSSL_free(*ppath); + *ppath = NULL; + } + if (pport != NULL) { + OPENSSL_free(*pport); + *pport = NULL; + } + if (phost != NULL) { + OPENSSL_free(*phost); + *phost = NULL; + } + OPENSSL_free(buf); + return 0; +} |