| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292 | =pod=head1 NAMEOSSL_HTTP_open,OSSL_HTTP_bio_cb_t,OSSL_HTTP_proxy_connect,OSSL_HTTP_set1_request,OSSL_HTTP_exchange,OSSL_HTTP_get,OSSL_HTTP_transfer,OSSL_HTTP_close-  HTTP client high-level functions=head1 SYNOPSIS #include <openssl/http.h> typedef BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg,                                    int connect, int detail); OSSL_HTTP_REQ_CTX *OSSL_HTTP_open(const char *server, const char *port,                                   const char *proxy, const char *no_proxy,                                   int use_ssl, BIO *bio, BIO *rbio,                                   OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,                                   int buf_size, int overall_timeout); 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_HTTP_set1_request(OSSL_HTTP_REQ_CTX *rctx, const char *path,                            const STACK_OF(CONF_VALUE) *headers,                            const char *content_type, BIO *req,                            const char *expected_content_type, int expect_asn1,                            size_t max_resp_len, int timeout, int keep_alive); BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url); BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,                    BIO *bio, BIO *rbio,                    OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,                    int buf_size, const STACK_OF(CONF_VALUE) *headers,                    const char *expected_content_type, int expect_asn1,                    size_t max_resp_len, int timeout); BIO *OSSL_HTTP_transfer(OSSL_HTTP_REQ_CTX **prctx,                         const char *server, const char *port,                         const char *path, int use_ssl,                         const char *proxy, const char *no_proxy,                         BIO *bio, BIO *rbio,                         OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,                         int buf_size, const STACK_OF(CONF_VALUE) *headers,                         const char *content_type, BIO *req,                         const char *expected_content_type, int expect_asn1,                         size_t max_resp_len, int timeout, int keep_alive); int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok);=head1 DESCRIPTIONOSSL_HTTP_open() initiates an HTTP session using the I<bio> argument if notNULL, else by connecting to a given I<server> optionally via a I<proxy>.Typically the OpenSSL build supports sockets and the I<bio> parameter is NULL.In this case I<rbio> must be NULL as well and the I<server> must be non-NULL.The function creates a network BIO internally using L<BIO_new_connect(3)>for connecting to the given server and the optionally given I<port>,defaulting to 80 for HTTP or 443 for HTTPS.Then this internal BIO is used for setting up a connectionand for exchanging one or more request and response.If I<bio> is given and I<rbio> is NULL then this I<bio> is used instead.If both I<bio> and I<rbio> are given (which may be memory BIOs for instance)then no explicit connection is set up, butI<bio> is used for writing requests and I<rbio> for reading responses.As soon as the client has flushed I<bio> the server must be ready to providea response or indicate a waiting condition via I<rbio>.If I<bio> is given, it is an error to provide I<proxy> or I<no_proxy> arguments,while I<server> and I<port> arguments may be given to support diagnostic output.If I<bio> is NULL the optional I<proxy> parameter can be used to set anHTTP(S) proxy to use (unless overridden by "no_proxy" settings).If TLS is not used this defaults to the environment variable C<http_proxy>if set, else C<HTTP_PROXY>.If I<use_ssl> != 0 it defaults to C<https_proxy> if set, else C<HTTPS_PROXY>.An empty proxy string C<""> forbids using a proxy.Else the format isC<[http[s]://][userinfo@]host[:port][/path][?query][#fragment]>,where any userinfo, path, query, and fragment given is ignored.The default proxy port number is 80, or 443 in case "https:" is given.The HTTP client functions connect via the given proxy unless the I<server>is found in the optional list I<no_proxy> of proxy hostnames (if not NULL;default is the environment variable C<no_proxy> if set, else C<NO_PROXY>).Proxying plain HTTP is supported directly,while using a proxy for HTTPS connections requires a suitable callback functionsuch as OSSL_HTTP_proxy_connect(), described below.If I<use_ssl> is nonzero a TLS connection is requestedand the I<bio_update_fn> parameter must be provided.The parameter I<bio_update_fn>, which is optional if I<use_ssl> is 0,may be used to modify the connection BIO used by the HTTP client,but cannot be used when both I<bio> and I<rbio> are given.I<bio_update_fn> is a BIO connect/disconnect callback function with prototype BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, int connect, int detail)The callback function may modify the BIO provided in the I<bio> argument,whereby it may make use of a custom defined argument I<arg>,which may for instance point to an B<SSL_CTX> structure.During connection establishment, just after calling BIO_do_connect_retry(), thecallback function is invoked with the I<connect> argument being 1 andI<detail> being 1 if I<use_ssl> is nonzero (i.e., HTTPS is requested), else 0.On disconnect I<connect> is 0 and I<detail> is 1 if no error occurred, else 0.For instance, on connect the callback may push an SSL BIO to implement HTTPS;after disconnect it may do some diagnostic output and pop and free the SSL BIO.The callback function must return either the potentially modified BIO I<bio>.or NULL to indicate failure, in which case it should not modify the BIO.Here is a simple example that supports TLS connections (but not via a proxy): BIO *http_tls_cb(BIO *bio, void *arg, int connect, int detail) {     if (connect && detail) { /* connecting with TLS */         SSL_CTX *ctx = (SSL_CTX *)arg;         BIO *sbio = BIO_new_ssl(ctx, 1);         bio = sbio != NULL ? BIO_push(sbio, bio) : NULL;     } else if (!connect) { /* disconnecting */         BIO *hbio;         if (!detail) { /* an error has occurred */             /* optionally add diagnostics here */         }         BIO_ssl_shutdown(bio);         hbio = BIO_pop(bio);         BIO_free(bio); /* SSL BIO */         bio = hbio;     }     return bio; }After disconnect the modified BIO will be deallocated using BIO_free_all().The I<buf_size> parameter specifies the response header maximum line length.A value <= 0 means that the B<OSSL_HTTP_DEFAULT_MAX_LINE_LEN> (4KiB) is used.I<buf_size> is also used as the number of content bytes that are read at a time.If the I<overall_timeout> parameter is > 0 this indicates the maximum number ofseconds the overall HTTP transfer (i.e., connection setup if needed,sending requests, and receiving responses) is allowed to take until completion.A value <= 0 enables waiting indefinitely, i.e., no timeout.OSSL_HTTP_proxy_connect() may be used by an above BIO connect callback functionto set up an SSL/TLS connection via an HTTPS proxy.It promotes the given BIO I<bio> representing a connectionpre-established with a TLS proxy using the HTTP CONNECT method,optionally using proxy client credentials I<proxyuser> and I<proxypass>,to connect with TLS protection ultimately to I<server> and I<port>.If the I<port> argument is NULL or the empty string it defaults to "443".If the I<timeout> parameter is > 0 this indicates the maximum number ofseconds the connection setup is allowed to take.A value <= 0 enables waiting indefinitely, i.e., no timeout.Since this function is typically called by applications such asL<openssl-s_client(1)> it uses the I<bio_err> and I<prog> parameters (unlessNULL) to print additional diagnostic information in a user-oriented way.OSSL_HTTP_set1_request() sets up in I<rctx> the request header and content dataand expectations on the response using the following parameters.If <rctx> indicates using a proxy for HTTP (but not HTTPS), the server host(and optionally port) needs to be placed in the header; thus it must be presentin I<rctx>.For backward compatibility, the server (and optional port) may also be given inthe I<path> argument beginning with C<http://> (thus giving an absoluteURI).If I<path> is NULL it defaults to "/".If I<req> is NULL the HTTP GET method will be used to send the requestelse HTTP POST with the contents of I<req> and optional I<content_type>, wherethe length of the data in I<req> does not need to be determined in advance: theBIO will be read on-the-fly while sending the request, which supports streaming.The optional list I<headers> may contain additional custom HTTP header lines.If the parameter I<expected_content_type>is not NULL then the client will check that the given content type stringis included in the HTTP header of the response and return an error if not.If the I<expect_asn1> parameter is nonzero,a structure in ASN.1 encoding will be expected as response content.The I<max_resp_len> parameter specifies the maximum allowedresponse content length, where the value 0 indicates no limit.If the I<timeout> parameter is > 0 this indicates the maximum number of secondsthe subsequent HTTP transfer (sending the request and receiving a response)is allowed to take.A value of 0 enables waiting indefinitely, i.e., no timeout.A value < 0 indicates that the I<overall_timeout> parameter value givenwhen opening the HTTP transfer will be used instead.If I<keep_alive> is 0 the connection is not kept openafter receiving a response, which is the default behavior for HTTP 1.0.If the value is 1 or 2 then a persistent connection is requested.If the value is 2 then a persistent connection is required,i.e., an error occurs in case the server does not grant it.OSSL_HTTP_exchange() exchanges any form of HTTP request and responseas specified by I<rctx>, which must include both connection and request data,typically set up using OSSL_HTTP_open() and OSSL_HTTP_set1_request().It implements the core of the functions described below.If the HTTP method is GET and I<redirection_url>is not NULL the latter pointer is used to provide any new location thatthe server may return with HTTP code 301 (MOVED_PERMANENTLY) or 302 (FOUND).In this case the function returns NULL and the caller isresponsible for deallocating the URL with L<OPENSSL_free(3)>.If the response header contains one or more "Content-Length" header lines and/oran ASN.1-encoded response is expected, which should include a total length,the length indications received are checked for consistencyand for not exceeding any given maximum response length.If an ASN.1-encoded response is expected, the function returns on successthe contents buffered in a memory BIO, which does not support streaming.Otherwise it returns directly the read BIO that holds the response contents,which allows a response of indefinite length and may support streaming.The caller is responsible for freeing the BIO pointer obtained.OSSL_HTTP_get() uses HTTP GET to obtain data from I<bio> if non-NULL,else from the server contained in the I<url>, and returns it as a BIO.It supports redirection via HTTP status code 301 or 302.  It is meant fortransfers with a single round trip, so does not support persistent connections.If I<bio> is non-NULL, any host and port components in the I<url> are not usedfor connecting but the hostname is used, as usual, for the C<Host> header.Any userinfo and fragment components in the I<url> are ignored.Any query component is handled as part of the path component.If the scheme component of the I<url> is C<https> a TLS connection is requestedand the I<bio_update_fn>, as described for OSSL_HTTP_open(), must be provided.Also the remaining parameters are interpreted as described for OSSL_HTTP_open()and OSSL_HTTP_set1_request(), respectively.The caller is responsible for freeing the BIO pointer obtained.OSSL_HTTP_transfer() exchanges an HTTP request and responseover a connection managed via I<prctx> without supporting redirection.It combines OSSL_HTTP_open(), OSSL_HTTP_set1_request(), OSSL_HTTP_exchange(),and OSSL_HTTP_close().If I<prctx> is not NULL it reuses any open connection represented by a non-NULLI<*prctx>.  It keeps the connection open if a persistent connection is requestedor required and this was granted by the server, else it closes the connectionand assigns NULL to I<*prctx>.The remaining parameters are interpreted as described for OSSL_HTTP_open()and OSSL_HTTP_set1_request(), respectively.The caller is responsible for freeing the BIO pointer obtained.OSSL_HTTP_close() closes the connection and releases I<rctx>.The I<ok> parameter is passed to any BIO update functiongiven during setup as described above for OSSL_HTTP_open().It must be 1 if no error occurred during the HTTP transfer and 0 otherwise.=head1 NOTESThe names of the environment variables used by this implementation:C<http_proxy>, C<HTTP_PROXY>, C<https_proxy>, C<HTTPS_PROXY>, C<no_proxy>, andC<NO_PROXY>, have been chosen for maximal compatibility withother HTTP client implementations such as wget, curl, and git.When built with tracing enabled, OSSL_HTTP_transfer() and all functions using itmay be traced using B<OSSL_TRACE_CATEGORY_HTTP>.See also L<OSSL_trace_enabled(3)> and L<openssl(1)/ENVIRONMENT>.=head1 RETURN VALUESOSSL_HTTP_open() returns on success a B<OSSL_HTTP_REQ_CTX>, else NULL.OSSL_HTTP_proxy_connect() and OSSL_HTTP_set1_request()return 1 on success, 0 on error.On success, OSSL_HTTP_exchange(), OSSL_HTTP_get(), and OSSL_HTTP_transfer()return a memory BIO that buffers all the data received if an ASN.1-encodedresponse is expected, otherwise a BIO that may support streaming.The BIO must be freed by the caller.On failure, they return NULL.Failure conditions include connection/transfer timeout, parse errors, etc.The caller is responsible for freeing the BIO pointer obtained.OSSL_HTTP_close() returns 0 if anything went wrong while disconnecting, else 1.=head1 SEE ALSOL<OSSL_HTTP_parse_url(3)>, L<BIO_new_connect(3)>,L<ASN1_item_i2d_mem_bio(3)>, L<ASN1_item_d2i_bio(3)>,L<OSSL_HTTP_is_alive(3)>,L<OSSL_trace_enabled(3)>=head1 HISTORYAll the functions described here were added in OpenSSL 3.0.=head1 COPYRIGHTCopyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved.Licensed under the Apache License 2.0 (the "License").  You may not usethis file except in compliance with the License.  You can obtain a copyin the file LICENSE in the source distribution or atL<https://www.openssl.org/source/license.html>.=cut
 |