1b077aed3SPierre Pronchery=pod 2b077aed3SPierre Pronchery 3b077aed3SPierre Pronchery=head1 NAME 4b077aed3SPierre Pronchery 5b077aed3SPierre ProncheryOSSL_HTTP_open, 6b077aed3SPierre ProncheryOSSL_HTTP_bio_cb_t, 7b077aed3SPierre ProncheryOSSL_HTTP_proxy_connect, 8b077aed3SPierre ProncheryOSSL_HTTP_set1_request, 9b077aed3SPierre ProncheryOSSL_HTTP_exchange, 10b077aed3SPierre ProncheryOSSL_HTTP_get, 11b077aed3SPierre ProncheryOSSL_HTTP_transfer, 12b077aed3SPierre ProncheryOSSL_HTTP_close 13b077aed3SPierre Pronchery- HTTP client high-level functions 14b077aed3SPierre Pronchery 15b077aed3SPierre Pronchery=head1 SYNOPSIS 16b077aed3SPierre Pronchery 17b077aed3SPierre Pronchery #include <openssl/http.h> 18b077aed3SPierre Pronchery 19b077aed3SPierre Pronchery typedef BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, 20b077aed3SPierre Pronchery int connect, int detail); 21b077aed3SPierre Pronchery OSSL_HTTP_REQ_CTX *OSSL_HTTP_open(const char *server, const char *port, 22b077aed3SPierre Pronchery const char *proxy, const char *no_proxy, 23b077aed3SPierre Pronchery int use_ssl, BIO *bio, BIO *rbio, 24b077aed3SPierre Pronchery OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, 25b077aed3SPierre Pronchery int buf_size, int overall_timeout); 26b077aed3SPierre Pronchery int OSSL_HTTP_proxy_connect(BIO *bio, const char *server, const char *port, 27b077aed3SPierre Pronchery const char *proxyuser, const char *proxypass, 28b077aed3SPierre Pronchery int timeout, BIO *bio_err, const char *prog); 29b077aed3SPierre Pronchery int OSSL_HTTP_set1_request(OSSL_HTTP_REQ_CTX *rctx, const char *path, 30b077aed3SPierre Pronchery const STACK_OF(CONF_VALUE) *headers, 31b077aed3SPierre Pronchery const char *content_type, BIO *req, 32b077aed3SPierre Pronchery const char *expected_content_type, int expect_asn1, 33b077aed3SPierre Pronchery size_t max_resp_len, int timeout, int keep_alive); 34b077aed3SPierre Pronchery BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url); 35b077aed3SPierre Pronchery BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy, 36b077aed3SPierre Pronchery BIO *bio, BIO *rbio, 37b077aed3SPierre Pronchery OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, 38b077aed3SPierre Pronchery int buf_size, const STACK_OF(CONF_VALUE) *headers, 39b077aed3SPierre Pronchery const char *expected_content_type, int expect_asn1, 40b077aed3SPierre Pronchery size_t max_resp_len, int timeout); 41b077aed3SPierre Pronchery BIO *OSSL_HTTP_transfer(OSSL_HTTP_REQ_CTX **prctx, 42b077aed3SPierre Pronchery const char *server, const char *port, 43b077aed3SPierre Pronchery const char *path, int use_ssl, 44b077aed3SPierre Pronchery const char *proxy, const char *no_proxy, 45b077aed3SPierre Pronchery BIO *bio, BIO *rbio, 46b077aed3SPierre Pronchery OSSL_HTTP_bio_cb_t bio_update_fn, void *arg, 47b077aed3SPierre Pronchery int buf_size, const STACK_OF(CONF_VALUE) *headers, 48b077aed3SPierre Pronchery const char *content_type, BIO *req, 49b077aed3SPierre Pronchery const char *expected_content_type, int expect_asn1, 50b077aed3SPierre Pronchery size_t max_resp_len, int timeout, int keep_alive); 51b077aed3SPierre Pronchery int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok); 52b077aed3SPierre Pronchery 53b077aed3SPierre Pronchery=head1 DESCRIPTION 54b077aed3SPierre Pronchery 55b077aed3SPierre ProncheryOSSL_HTTP_open() initiates an HTTP session using the I<bio> argument if not 56b077aed3SPierre ProncheryNULL, else by connecting to a given I<server> optionally via a I<proxy>. 57b077aed3SPierre Pronchery 58b077aed3SPierre ProncheryTypically the OpenSSL build supports sockets and the I<bio> parameter is NULL. 59b077aed3SPierre ProncheryIn this case I<rbio> must be NULL as well and the I<server> must be non-NULL. 60b077aed3SPierre ProncheryThe function creates a network BIO internally using L<BIO_new_connect(3)> 61b077aed3SPierre Proncheryfor connecting to the given server and the optionally given I<port>, 62b077aed3SPierre Proncherydefaulting to 80 for HTTP or 443 for HTTPS. 63b077aed3SPierre ProncheryThen this internal BIO is used for setting up a connection 64b077aed3SPierre Proncheryand for exchanging one or more request and response. 65*e7be843bSPierre Pronchery 66b077aed3SPierre ProncheryIf I<bio> is given and I<rbio> is NULL then this I<bio> is used instead. 67b077aed3SPierre ProncheryIf both I<bio> and I<rbio> are given (which may be memory BIOs for instance) 68b077aed3SPierre Proncherythen no explicit connection is set up, but 69b077aed3SPierre ProncheryI<bio> is used for writing requests and I<rbio> for reading responses. 70b077aed3SPierre ProncheryAs soon as the client has flushed I<bio> the server must be ready to provide 71b077aed3SPierre Proncherya response or indicate a waiting condition via I<rbio>. 72b077aed3SPierre Pronchery 73*e7be843bSPierre ProncheryIf I<bio> is given, 74*e7be843bSPierre Proncheryit is an error to provide non-NULL I<proxy> or I<no_proxy> arguments, 75b077aed3SPierre Proncherywhile I<server> and I<port> arguments may be given to support diagnostic output. 76b077aed3SPierre ProncheryIf I<bio> is NULL the optional I<proxy> parameter can be used to set an 77b077aed3SPierre ProncheryHTTP(S) proxy to use (unless overridden by "no_proxy" settings). 78b077aed3SPierre ProncheryIf TLS is not used this defaults to the environment variable C<http_proxy> 79b077aed3SPierre Proncheryif set, else C<HTTP_PROXY>. 80b077aed3SPierre ProncheryIf I<use_ssl> != 0 it defaults to C<https_proxy> if set, else C<HTTPS_PROXY>. 81b077aed3SPierre ProncheryAn empty proxy string C<""> forbids using a proxy. 820d0c8621SEnji CooperOtherwise, the format is 83b077aed3SPierre ProncheryC<[http[s]://][userinfo@]host[:port][/path][?query][#fragment]>, 84b077aed3SPierre Proncherywhere any userinfo, path, query, and fragment given is ignored. 850d0c8621SEnji CooperIf the host string is an IPv6 address, it must be enclosed in C<[> and C<]>. 86b077aed3SPierre ProncheryThe default proxy port number is 80, or 443 in case "https:" is given. 87b077aed3SPierre ProncheryThe HTTP client functions connect via the given proxy unless the I<server> 880d0c8621SEnji Cooperis found in the optional list I<no_proxy> of proxy hostnames or IP addresses 890d0c8621SEnji Cooperseparated by C<,> and/or whitespace (if not NULL; 90b077aed3SPierre Proncherydefault is the environment variable C<no_proxy> if set, else C<NO_PROXY>). 91b077aed3SPierre ProncheryProxying plain HTTP is supported directly, 92b077aed3SPierre Proncherywhile using a proxy for HTTPS connections requires a suitable callback function 93b077aed3SPierre Proncherysuch as OSSL_HTTP_proxy_connect(), described below. 94b077aed3SPierre Pronchery 95b077aed3SPierre ProncheryIf I<use_ssl> is nonzero a TLS connection is requested 96b077aed3SPierre Proncheryand the I<bio_update_fn> parameter must be provided. 97b077aed3SPierre Pronchery 98b077aed3SPierre ProncheryThe parameter I<bio_update_fn>, which is optional if I<use_ssl> is 0, 99b077aed3SPierre Proncherymay be used to modify the connection BIO used by the HTTP client, 100b077aed3SPierre Proncherybut cannot be used when both I<bio> and I<rbio> are given. 101b077aed3SPierre ProncheryI<bio_update_fn> is a BIO connect/disconnect callback function with prototype 102b077aed3SPierre Pronchery 103b077aed3SPierre Pronchery BIO *(*OSSL_HTTP_bio_cb_t)(BIO *bio, void *arg, int connect, int detail) 104b077aed3SPierre Pronchery 105b077aed3SPierre ProncheryThe callback function may modify the BIO provided in the I<bio> argument, 106*e7be843bSPierre Proncherywhereby it may use an optional custom defined argument I<arg>, 107*e7be843bSPierre Proncherywhich can for instance point to an B<SSL_CTX> structure. 108b077aed3SPierre ProncheryDuring connection establishment, just after calling BIO_do_connect_retry(), the 109b077aed3SPierre Proncherycallback function is invoked with the I<connect> argument being 1 and 110b077aed3SPierre ProncheryI<detail> being 1 if I<use_ssl> is nonzero (i.e., HTTPS is requested), else 0. 111b077aed3SPierre ProncheryOn disconnect I<connect> is 0 and I<detail> is 1 if no error occurred, else 0. 112b077aed3SPierre ProncheryFor instance, on connect the callback may push an SSL BIO to implement HTTPS; 113b077aed3SPierre Proncheryafter disconnect it may do some diagnostic output and pop and free the SSL BIO. 114b077aed3SPierre Pronchery 115*e7be843bSPierre ProncheryThe callback function must return either the potentially modified BIO I<bio> 116b077aed3SPierre Proncheryor NULL to indicate failure, in which case it should not modify the BIO. 117b077aed3SPierre Pronchery 118b077aed3SPierre ProncheryHere is a simple example that supports TLS connections (but not via a proxy): 119b077aed3SPierre Pronchery 120b077aed3SPierre Pronchery BIO *http_tls_cb(BIO *bio, void *arg, int connect, int detail) 121b077aed3SPierre Pronchery { 122b077aed3SPierre Pronchery if (connect && detail) { /* connecting with TLS */ 123b077aed3SPierre Pronchery SSL_CTX *ctx = (SSL_CTX *)arg; 124b077aed3SPierre Pronchery BIO *sbio = BIO_new_ssl(ctx, 1); 125b077aed3SPierre Pronchery 126b077aed3SPierre Pronchery bio = sbio != NULL ? BIO_push(sbio, bio) : NULL; 127b077aed3SPierre Pronchery } else if (!connect) { /* disconnecting */ 128b077aed3SPierre Pronchery BIO *hbio; 129b077aed3SPierre Pronchery 130b077aed3SPierre Pronchery if (!detail) { /* an error has occurred */ 131b077aed3SPierre Pronchery /* optionally add diagnostics here */ 132b077aed3SPierre Pronchery } 133b077aed3SPierre Pronchery BIO_ssl_shutdown(bio); 134b077aed3SPierre Pronchery hbio = BIO_pop(bio); 135b077aed3SPierre Pronchery BIO_free(bio); /* SSL BIO */ 136b077aed3SPierre Pronchery bio = hbio; 137b077aed3SPierre Pronchery } 138b077aed3SPierre Pronchery return bio; 139b077aed3SPierre Pronchery } 140b077aed3SPierre Pronchery 141b077aed3SPierre ProncheryAfter disconnect the modified BIO will be deallocated using BIO_free_all(). 142*e7be843bSPierre ProncheryThe optional callback function argument I<arg> is not consumed, 143*e7be843bSPierre Proncheryso must be freed by the caller when not needed any more. 144b077aed3SPierre Pronchery 145b077aed3SPierre ProncheryThe I<buf_size> parameter specifies the response header maximum line length. 146b077aed3SPierre ProncheryA value <= 0 means that the B<OSSL_HTTP_DEFAULT_MAX_LINE_LEN> (4KiB) is used. 147b077aed3SPierre ProncheryI<buf_size> is also used as the number of content bytes that are read at a time. 148b077aed3SPierre Pronchery 149b077aed3SPierre ProncheryIf the I<overall_timeout> parameter is > 0 this indicates the maximum number of 150b077aed3SPierre Proncheryseconds the overall HTTP transfer (i.e., connection setup if needed, 151b077aed3SPierre Proncherysending requests, and receiving responses) is allowed to take until completion. 152b077aed3SPierre ProncheryA value <= 0 enables waiting indefinitely, i.e., no timeout. 153b077aed3SPierre Pronchery 154b077aed3SPierre ProncheryOSSL_HTTP_proxy_connect() may be used by an above BIO connect callback function 155b077aed3SPierre Proncheryto set up an SSL/TLS connection via an HTTPS proxy. 156b077aed3SPierre ProncheryIt promotes the given BIO I<bio> representing a connection 157b077aed3SPierre Proncherypre-established with a TLS proxy using the HTTP CONNECT method, 158b077aed3SPierre Proncheryoptionally using proxy client credentials I<proxyuser> and I<proxypass>, 159b077aed3SPierre Proncheryto connect with TLS protection ultimately to I<server> and I<port>. 160b077aed3SPierre ProncheryIf the I<port> argument is NULL or the empty string it defaults to "443". 161b077aed3SPierre ProncheryIf the I<timeout> parameter is > 0 this indicates the maximum number of 162b077aed3SPierre Proncheryseconds the connection setup is allowed to take. 163b077aed3SPierre ProncheryA value <= 0 enables waiting indefinitely, i.e., no timeout. 164b077aed3SPierre ProncherySince this function is typically called by applications such as 165b077aed3SPierre ProncheryL<openssl-s_client(1)> it uses the I<bio_err> and I<prog> parameters (unless 166b077aed3SPierre ProncheryNULL) to print additional diagnostic information in a user-oriented way. 167b077aed3SPierre Pronchery 168b077aed3SPierre ProncheryOSSL_HTTP_set1_request() sets up in I<rctx> the request header and content data 169b077aed3SPierre Proncheryand expectations on the response using the following parameters. 1706f1af0d7SPierre ProncheryIf <rctx> indicates using a proxy for HTTP (but not HTTPS), the server host 1716f1af0d7SPierre Pronchery(and optionally port) needs to be placed in the header; thus it must be present 1726f1af0d7SPierre Proncheryin I<rctx>. 1736f1af0d7SPierre ProncheryFor backward compatibility, the server (and optional port) may also be given in 1746f1af0d7SPierre Proncherythe I<path> argument beginning with C<http://> (thus giving an absoluteURI). 175b077aed3SPierre ProncheryIf I<path> is NULL it defaults to "/". 176b077aed3SPierre ProncheryIf I<req> is NULL the HTTP GET method will be used to send the request 177b077aed3SPierre Proncheryelse HTTP POST with the contents of I<req> and optional I<content_type>, where 178b077aed3SPierre Proncherythe length of the data in I<req> does not need to be determined in advance: the 179b077aed3SPierre ProncheryBIO will be read on-the-fly while sending the request, which supports streaming. 180b077aed3SPierre ProncheryThe optional list I<headers> may contain additional custom HTTP header lines. 181b077aed3SPierre ProncheryThe I<max_resp_len> parameter specifies the maximum allowed 182b077aed3SPierre Proncheryresponse content length, where the value 0 indicates no limit. 183*e7be843bSPierre ProncheryFor the meaning of the I<expected_content_type>, I<expect_asn1>, I<timeout>, 184*e7be843bSPierre Proncheryand I<keep_alive> parameters, see L<OSSL_HTTP_REQ_CTX_set_expected(3)>. 185b077aed3SPierre Pronchery 186b077aed3SPierre ProncheryOSSL_HTTP_exchange() exchanges any form of HTTP request and response 187b077aed3SPierre Proncheryas specified by I<rctx>, which must include both connection and request data, 188b077aed3SPierre Proncherytypically set up using OSSL_HTTP_open() and OSSL_HTTP_set1_request(). 189b077aed3SPierre ProncheryIt implements the core of the functions described below. 190b077aed3SPierre ProncheryIf the HTTP method is GET and I<redirection_url> 191b077aed3SPierre Proncheryis not NULL the latter pointer is used to provide any new location that 192b077aed3SPierre Proncherythe server may return with HTTP code 301 (MOVED_PERMANENTLY) or 302 (FOUND). 193b077aed3SPierre ProncheryIn this case the function returns NULL and the caller is 194b077aed3SPierre Proncheryresponsible for deallocating the URL with L<OPENSSL_free(3)>. 195*e7be843bSPierre ProncheryIf the response header contains one or more C<Content-Length> lines and/or 196b077aed3SPierre Proncheryan ASN.1-encoded response is expected, which should include a total length, 197b077aed3SPierre Proncherythe length indications received are checked for consistency 198b077aed3SPierre Proncheryand for not exceeding any given maximum response length. 199b077aed3SPierre ProncheryIf an ASN.1-encoded response is expected, the function returns on success 200b077aed3SPierre Proncherythe contents buffered in a memory BIO, which does not support streaming. 201b077aed3SPierre ProncheryOtherwise it returns directly the read BIO that holds the response contents, 202b077aed3SPierre Proncherywhich allows a response of indefinite length and may support streaming. 203b077aed3SPierre ProncheryThe caller is responsible for freeing the BIO pointer obtained. 204b077aed3SPierre Pronchery 205b077aed3SPierre ProncheryOSSL_HTTP_get() uses HTTP GET to obtain data from I<bio> if non-NULL, 206b077aed3SPierre Proncheryelse from the server contained in the I<url>, and returns it as a BIO. 207b077aed3SPierre ProncheryIt supports redirection via HTTP status code 301 or 302. It is meant for 208b077aed3SPierre Proncherytransfers with a single round trip, so does not support persistent connections. 209b077aed3SPierre ProncheryIf I<bio> is non-NULL, any host and port components in the I<url> are not used 210b077aed3SPierre Proncheryfor connecting but the hostname is used, as usual, for the C<Host> header. 211b077aed3SPierre ProncheryAny userinfo and fragment components in the I<url> are ignored. 212b077aed3SPierre ProncheryAny query component is handled as part of the path component. 213b077aed3SPierre ProncheryIf the scheme component of the I<url> is C<https> a TLS connection is requested 214b077aed3SPierre Proncheryand the I<bio_update_fn>, as described for OSSL_HTTP_open(), must be provided. 215b077aed3SPierre ProncheryAlso the remaining parameters are interpreted as described for OSSL_HTTP_open() 216b077aed3SPierre Proncheryand OSSL_HTTP_set1_request(), respectively. 217b077aed3SPierre ProncheryThe caller is responsible for freeing the BIO pointer obtained. 218b077aed3SPierre Pronchery 219b077aed3SPierre ProncheryOSSL_HTTP_transfer() exchanges an HTTP request and response 220b077aed3SPierre Proncheryover a connection managed via I<prctx> without supporting redirection. 221b077aed3SPierre ProncheryIt combines OSSL_HTTP_open(), OSSL_HTTP_set1_request(), OSSL_HTTP_exchange(), 222b077aed3SPierre Proncheryand OSSL_HTTP_close(). 223b077aed3SPierre ProncheryIf I<prctx> is not NULL it reuses any open connection represented by a non-NULL 224b077aed3SPierre ProncheryI<*prctx>. It keeps the connection open if a persistent connection is requested 225b077aed3SPierre Proncheryor required and this was granted by the server, else it closes the connection 226b077aed3SPierre Proncheryand assigns NULL to I<*prctx>. 227b077aed3SPierre ProncheryThe remaining parameters are interpreted as described for OSSL_HTTP_open() 228b077aed3SPierre Proncheryand OSSL_HTTP_set1_request(), respectively. 229b077aed3SPierre ProncheryThe caller is responsible for freeing the BIO pointer obtained. 230b077aed3SPierre Pronchery 231b077aed3SPierre ProncheryOSSL_HTTP_close() closes the connection and releases I<rctx>. 232b077aed3SPierre ProncheryThe I<ok> parameter is passed to any BIO update function 233b077aed3SPierre Proncherygiven during setup as described above for OSSL_HTTP_open(). 234b077aed3SPierre ProncheryIt must be 1 if no error occurred during the HTTP transfer and 0 otherwise. 235b077aed3SPierre Pronchery 236b077aed3SPierre Pronchery=head1 NOTES 237b077aed3SPierre Pronchery 238b077aed3SPierre ProncheryThe names of the environment variables used by this implementation: 239b077aed3SPierre ProncheryC<http_proxy>, C<HTTP_PROXY>, C<https_proxy>, C<HTTPS_PROXY>, C<no_proxy>, and 240b077aed3SPierre ProncheryC<NO_PROXY>, have been chosen for maximal compatibility with 241b077aed3SPierre Proncheryother HTTP client implementations such as wget, curl, and git. 242b077aed3SPierre Pronchery 243*e7be843bSPierre ProncheryWhen built with tracing enabled, OSSL_HTTP_transfer() and all functions using it 244*e7be843bSPierre Proncherymay be traced using B<OSSL_TRACE_CATEGORY_HTTP>. 245*e7be843bSPierre ProncherySee also L<OSSL_trace_enabled(3)> and L<openssl-env(7)>. 246*e7be843bSPierre Pronchery 247b077aed3SPierre Pronchery=head1 RETURN VALUES 248b077aed3SPierre Pronchery 249b077aed3SPierre ProncheryOSSL_HTTP_open() returns on success a B<OSSL_HTTP_REQ_CTX>, else NULL. 250b077aed3SPierre Pronchery 251b077aed3SPierre ProncheryOSSL_HTTP_proxy_connect() and OSSL_HTTP_set1_request() 252b077aed3SPierre Proncheryreturn 1 on success, 0 on error. 253b077aed3SPierre Pronchery 254b077aed3SPierre ProncheryOn success, OSSL_HTTP_exchange(), OSSL_HTTP_get(), and OSSL_HTTP_transfer() 255b077aed3SPierre Proncheryreturn a memory BIO that buffers all the data received if an ASN.1-encoded 256b077aed3SPierre Proncheryresponse is expected, otherwise a BIO that may support streaming. 257b077aed3SPierre ProncheryThe BIO must be freed by the caller. 258b077aed3SPierre ProncheryOn failure, they return NULL. 259b077aed3SPierre ProncheryFailure conditions include connection/transfer timeout, parse errors, etc. 260b077aed3SPierre ProncheryThe caller is responsible for freeing the BIO pointer obtained. 261b077aed3SPierre Pronchery 262b077aed3SPierre ProncheryOSSL_HTTP_close() returns 0 if anything went wrong while disconnecting, else 1. 263b077aed3SPierre Pronchery 264b077aed3SPierre Pronchery=head1 SEE ALSO 265b077aed3SPierre Pronchery 266b077aed3SPierre ProncheryL<OSSL_HTTP_parse_url(3)>, L<BIO_new_connect(3)>, 267b077aed3SPierre ProncheryL<ASN1_item_i2d_mem_bio(3)>, L<ASN1_item_d2i_bio(3)>, 268*e7be843bSPierre ProncheryL<OSSL_HTTP_REQ_CTX_set_expected(3)>, 269*e7be843bSPierre ProncheryL<OSSL_HTTP_is_alive(3)>, 270*e7be843bSPierre ProncheryL<OSSL_trace_enabled(3)>, and L<openssl-env(7)>. 271b077aed3SPierre Pronchery 272b077aed3SPierre Pronchery=head1 HISTORY 273b077aed3SPierre Pronchery 274b077aed3SPierre ProncheryAll the functions described here were added in OpenSSL 3.0. 275b077aed3SPierre Pronchery 276b077aed3SPierre Pronchery=head1 COPYRIGHT 277b077aed3SPierre Pronchery 278*e7be843bSPierre ProncheryCopyright 2019-2025 The OpenSSL Project Authors. All Rights Reserved. 279b077aed3SPierre Pronchery 280b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License"). You may not use 281b077aed3SPierre Proncherythis file except in compliance with the License. You can obtain a copy 282b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at 283b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>. 284b077aed3SPierre Pronchery 285b077aed3SPierre Pronchery=cut 286