| =pod |
| |
| =head1 NAME |
| |
| OSSL_HTTP_REQ_CTX, |
| OSSL_HTTP_REQ_CTX_new, |
| OSSL_HTTP_REQ_CTX_free, |
| OSSL_HTTP_REQ_CTX_set_request_line, |
| OSSL_HTTP_REQ_CTX_add1_header, |
| OSSL_HTTP_REQ_CTX_set1_req, |
| OSSL_HTTP_REQ_CTX_nbio, |
| OSSL_HTTP_REQ_CTX_sendreq_d2i, |
| OSSL_HTTP_REQ_CTX_get0_mem_bio, |
| OSSL_HTTP_REQ_CTX_set_max_response_length |
| - HTTP client low-level functions |
| |
| =head1 SYNOPSIS |
| |
| #include <openssl/http.h> |
| |
| typedef struct ossl_http_req_ctx_st OSSL_HTTP_REQ_CTX; |
| |
| OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, |
| int maxline, unsigned long max_resp_len, |
| int timeout, |
| const char *expected_content_type, |
| int expect_asn1); |
| void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx); |
| |
| int OSSL_HTTP_REQ_CTX_set_request_line(OSSL_HTTP_REQ_CTX *rctx, int method_POST, |
| const char *server, const char *port, |
| const char *path); |
| int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx, |
| const char *name, const char *value); |
| |
| int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type, |
| const ASN1_ITEM *it, ASN1_VALUE *req); |
| int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx); |
| ASN1_VALUE *OSSL_HTTP_REQ_CTX_sendreq_d2i(OSSL_HTTP_REQ_CTX *rctx, |
| const ASN1_ITEM *it); |
| |
| BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx); |
| void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx, |
| unsigned long len); |
| |
| =head1 DESCRIPTION |
| |
| B<OSSL_HTTP_REQ_CTX> is a context structure for an HTTP request, used to |
| collect all the necessary data to perform that request. |
| |
| This file documents low-level HTTP functions rarely used directly. High-level |
| HTTP client functions like L<OSSL_HTTP_get(3)> and L<OSSL_HTTP_transfer(3)> |
| should be preferred. |
| |
| OSSL_HTTP_REQ_CTX_new() allocates a new HTTP request context structure, |
| which gets populated with the B<BIO> to send the request to (I<wbio>), |
| the B<BIO> to read the response from (I<rbio>, which may be equal to I<wbio>), |
| the maximum expected response header line length (I<maxline>, where a value <= 0 |
| indicates that the B<HTTP_DEFAULT_MAX_LINE_LENGTH> of 4KiB should be used; |
| this length is also used as the number of content bytes read at a time), |
| the maximum allowed response content length (I<max_resp_len>, where 0 means |
| that the B<HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB), |
| a response timeout measure in seconds (I<timeout>, |
| where 0 indicates no timeout, i.e., waiting indefinitely), |
| the expected MIME content type of the response (I<expected_content_type>, |
| which may be NULL for no expectation), |
| and a flag indicating that the response is expected to be |
| a DER encoded ASN.1 structure (I<expect_asn1>). |
| The allocated context structure is also populated with an internal allocated |
| memory B<BIO>, which collects the HTTP request and additional headers as text. |
| The returned context should only be used for a single HTTP request/response. |
| |
| OSSL_HTTP_REQ_CTX_free() frees up the HTTP request context I<rctx>. |
| The I<wbio> and I<rbio> are not free'd and it is up to the application |
| to do so. |
| |
| OSSL_HTTP_REQ_CTX_set_request_line() adds the HTTP request line to the context. |
| The HTTP method is determined by I<method_POST>, |
| which should be 1 to indicate C<POST> or 0 to indicate C<GET>. |
| I<server> and I<port> may be set to indicate a proxy server and port |
| that the request should go through, otherwise they should be left NULL. |
| I<path> is the HTTP request path; if left NULL, C</> is used. |
| |
| OSSL_HTTP_REQ_CTX_add1_header() adds header I<name> with value I<value> to the |
| context I<rctx>. It can be called more than once to add multiple headers. |
| For example, to add a C<Host> header for C<example.com> you would call: |
| |
| OSSL_HTTP_REQ_CTX_add1_header(ctx, "Host", "example.com"); |
| |
| OSSL_HTTP_REQ_CTX_set1_req() is to be used if and only if the I<method_POST> |
| parameter in the OSSL_HTTP_REQ_CTX_set_request_line() call was 1. |
| It finalizes the HTTP request context by adding the DER encoding of I<req>, |
| using the ASN.1 template I<it> to do the encoding. |
| The HTTP header C<Content-Length> is filled out with the length of the request. |
| If I<content_type> isn't NULL, |
| the HTTP header C<Content-Type> is also added with its content as value. |
| All of this ends up in the internal memory B<BIO>. |
| |
| OSSL_HTTP_REQ_CTX_nbio() attempts to send the request prepared I<rctx> |
| and gathering the response via HTTP, using the I<rbio> and I<wbio> |
| that were given when calling OSSL_HTTP_REQ_CTX_new(). |
| When successful, the contents of the internal memory B<BIO> contains |
| the contents of the HTTP response, without the response headers. |
| It may need to be called again if its result is -1, which indicates |
| L<BIO_should_retry(3)>. In such a case it is advisable to sleep a little in |
| between using L<BIO_wait(3)> on the read BIO to prevent a busy loop. |
| |
| OSSL_HTTP_REQ_CTX_sendreq_d2i() calls OSSL_HTTP_REQ_CTX_nbio(), possibly |
| several times until a timeout is reached, and DER decodes the received |
| response using the ASN.1 template I<it>. |
| |
| OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>. |
| Before sending the request, this could used to modify the HTTP request text. |
| I<Use with caution!> |
| After receiving a response via HTTP, the BIO represents |
| the current state of reading the response headers and contents. |
| |
| OSSL_HTTP_REQ_CTX_set_max_response_length() sets the maximum allowed |
| response content length for I<rctx> to I<len>. If not set or I<len> is 0 |
| then the B<HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB. |
| If the C<Content-Length> header is present and exceeds this value or |
| the content is an ASN.1 encoded structure with a length exceeding this value |
| or both length indications are present but disagree then an error occurs. |
| |
| =head1 WARNINGS |
| |
| The server's response may be unexpected if the hostname that was used to |
| create the I<wbio>, any C<Host> header, and the host specified in the |
| request URL do not match. |
| |
| Many of these functions must be called in a certain order. |
| |
| First, the HTTP request context must be allocated: |
| OSSL_HTTP_REQ_CTX_new(). |
| |
| Then, the HTTP request must be prepared with request data: |
| |
| =over 4 |
| |
| =item 1. |
| |
| Calling OSSL_HTTP_REQ_CTX_set_request_line(). This must be done exactly once. |
| |
| =item 2. |
| |
| Adding extra headers with OSSL_HTTP_REQ_CTX_add1_header(). |
| This is optional and may be done multiple times with different names. |
| |
| =item 3. |
| |
| Add C<POST> data with OSSL_HTTP_REQ_CTX_set1_req(). This may only be done if |
| I<method_POST> was 1 in the OSSL_HTTP_REQ_CTX_set_request_line() call, |
| and must be done exactly once in that case. |
| |
| =back |
| |
| When the request context is fully prepared, the HTTP exchange may be performed |
| with OSSL_HTTP_REQ_CTX_nbio() or OSSL_HTTP_REQ_CTX_sendreq_d2i(). |
| |
| =head1 RETURN VALUES |
| |
| OSSL_HTTP_REQ_CTX_new() returns a pointer to a B<OSSL_HTTP_REQ_CTX>, or NULL |
| on error. |
| |
| OSSL_HTTP_REQ_CTX_free() and OSSL_HTTP_REQ_CTX_set_max_response_length() |
| do not return values. |
| |
| OSSL_HTTP_REQ_CTX_set_request_line(), OSSL_HTTP_REQ_CTX_add1_header(), |
| OSSL_HTTP_REQ_CTX_set1_req() and OSSL_HTTP_REQ_CTX_nbio |
| return 1 for success and 0 for failure. |
| |
| OSSL_HTTP_REQ_CTX_sendreq_d2i() returns a pointer to an B<ASN1_VALUE> for |
| success and NULL for failure. |
| |
| OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>. |
| |
| =head1 SEE ALSO |
| |
| L<BIO_should_retry(3)>, |
| L<BIO_wait(3)>, |
| L<OSSL_HTTP_get(3)>, |
| L<OSSL_HTTP_transfer(3)> |
| |
| =head1 COPYRIGHT |
| |
| Copyright 2015-2021 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 |
| L<https://www.openssl.org/source/license.html>. |
| |
| =cut |