]> git.ipfire.org Git - thirdparty/openssl.git/blobdiff - doc/man3/OSSL_HTTP_REQ_CTX.pod
HTTP client: Minimal changes that include the improved API
[thirdparty/openssl.git] / doc / man3 / OSSL_HTTP_REQ_CTX.pod
index 8e928f19fab62e3e70c4d078c2458c999f704caf..a09b9b81a95662566892b3eb01441fad330fd560 100644 (file)
@@ -7,11 +7,15 @@ 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_set_expected,
 OSSL_HTTP_REQ_CTX_set1_req,
 OSSL_HTTP_REQ_CTX_nbio,
-OSSL_HTTP_REQ_CTX_sendreq_d2i,
+OSSL_HTTP_REQ_CTX_nbio_d2i,
+OSSL_HTTP_REQ_CTX_exchange,
 OSSL_HTTP_REQ_CTX_get0_mem_bio,
-OSSL_HTTP_REQ_CTX_set_max_response_length
+OSSL_HTTP_REQ_CTX_get_resp_len,
+OSSL_HTTP_REQ_CTX_set_max_response_length,
+OSSL_HTTP_is_alive
 - HTTP client low-level functions
 
 =head1 SYNOPSIS
@@ -20,11 +24,7 @@ OSSL_HTTP_REQ_CTX_set_max_response_length
 
  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);
+ OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size);
  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,
@@ -33,42 +33,41 @@ OSSL_HTTP_REQ_CTX_set_max_response_length
  int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
                                    const char *name, const char *value);
 
+ int OSSL_HTTP_REQ_CTX_set_expected(OSSL_HTTP_REQ_CTX *rctx,
+                                    const char *content_type, int asn1,
+                                    int timeout, int keep_alive);
  int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
-                                const ASN1_ITEM *it, ASN1_VALUE *req);
+                                const ASN1_ITEM *it, const 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);
+ int OSSL_HTTP_REQ_CTX_nbio_d2i(OSSL_HTTP_REQ_CTX *rctx,
+                                ASN1_VALUE **pval, const ASN1_ITEM *it);
+ BIO *OSSL_HTTP_REQ_CTX_exchange(OSSL_HTTP_REQ_CTX *rctx);
 
  BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx);
+ size_t OSSL_HTTP_REQ_CTX_get_resp_len(const OSSL_HTTP_REQ_CTX *rctx);
  void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
                                                 unsigned long len);
 
+ int OSSL_HTTP_is_alive(const OSSL_HTTP_REQ_CTX *rctx);
+
 =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.
+B<OSSL_HTTP_REQ_CTX> is a context structure for an HTTP request and response,
+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>).
+which gets populated with the B<BIO> to write/send the request to (I<wbio>),
+the B<BIO> to read/receive the response from (I<rbio>, which may be equal to
+I<wbio>), and the maximum expected response header line length I<buf_size>.
+A value <= 0 indicates that
+the B<HTTP_DEFAULT_MAX_LINE_LENGTH> of 4KiB should be used.
+I<buf_size> is also used as the number of content bytes that are read at a time.
 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
@@ -87,33 +86,71 @@ 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_set_expected() optionally sets in I<rctx> some expectations
+of the HTTP client on the response.
+Due to the structure of an HTTP request, if the I<keep_alive> argument is
+nonzero the function must be used before calling OSSL_HTTP_REQ_CTX_set1_req().
+If the I<content_type> parameter
+is not NULL then the client will check that the given content type string
+is included in the HTTP header of the response and return an error if not.
+If the I<asn1> parameter is nonzero a structure in ASN.1 encoding will be
+expected as the response content and input streaming is disabled.  This means
+that an ASN.1 sequence header is required, its length field is checked, and
+OSSL_HTTP_REQ_CTX_get0_mem_bio() should be used to get the buffered response.
+Else any form of input is allowed without length checks, which is the default.
+In this case the BIO given as I<rbio> argument to OSSL_HTTP_REQ_CTX_new() should
+be used directly to read the response contents, which may support streaming.
+If the I<timeout> parameter is > 0 this indicates the maximum number of seconds
+the subsequent HTTP transfer (sending the request and receiving a response)
+is allowed to take.
+A value <= 0 enables waiting indefinitely, i.e., no timeout can occur.
+This is the default.
+If the I<keep_alive> parameter is 0, which is the default, the connection is not
+kept open after receiving a response. This 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_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.
+parameter in the OSSL_HTTP_REQ_CTX_set_request_line() call was 1
+and an ASN.1-encoded request should be sent, which does not support streaming.
 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.
+the HTTP header C<Content-Type> is also added with the given string 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>
+OSSL_HTTP_REQ_CTX_nbio() attempts to send the request prepared in I<rctx>
+and to gather the response via HTTP, using the I<wbio> and I<rbio>
 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
+The function 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>.
+between, using L<BIO_wait(3)> on the read BIO to prevent a busy loop.
+
+OSSL_HTTP_REQ_CTX_nbio_d2i() is like OSSL_HTTP_REQ_CTX_nbio() but on successs
+in addition parses the response, which must be a DER-encoded ASN.1 structure,
+using the ASN.1 template I<it> and places the result in I<*pval>.
+
+OSSL_HTTP_REQ_CTX_exchange() calls OSSL_HTTP_REQ_CTX_nbio() as often as needed
+in order to exchange a request and response or until a timeout is reached.
+If successful and an ASN.1-encoded response was expected, the response contents
+should be read via the BIO returned by OSSL_HTTP_REQ_CTX_get0_mem_bio().
+Else the I<rbio> that was given when calling OSSL_HTTP_REQ_CTX_new()
+represents the current state of reading the response.
+If OSSL_HTTP_REQ_CTX_exchange() was successful, this BIO has been read past the
+end of the response headers, such that the actual response contents can be read
+via this BIO, which may support streaming.
 
 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.
+After receiving a response via HTTP, the BIO represents the current state of
+reading the response headers. If the response was expected to be ASN.1 encoded,
+its contents can be read via this BIO, which does not support streaming.
+
+OSSL_HTTP_REQ_CTX_get_resp_len() returns the size of the response contents
+in I<rctx> if provided by the server as <Content-Length> header field, else 0.
 
 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
@@ -122,6 +159,18 @@ 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.
 
+OSSL_HTTP_is_alive() can be used to query if the HTTP connection
+given by I<rctx> is still alive, i.e., has not been closed.
+It returns 0 if I<rctx> is NULL.
+
+If the client application requested or required a persistent connection
+and this was granted by the server, it can keep I<rctx> as long as it wants
+to send further requests and OSSL_HTTP_is_alive() returns nonzero,
+else it should call I<OSSL_HTTP_REQ_CTX_free(rctx)> or L<OSSL_HTTP_close(3)>.
+In case the client application keeps I<rctx> but the connection then dies
+for any reason at the server side, it will notice this obtaining an
+I/O error when trying to send the next request via I<rctx>.
+
 =head1 WARNINGS
 
 The server's response may be unexpected if the hostname that was used to
@@ -155,7 +204,7 @@ 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().
+with OSSL_HTTP_REQ_CTX_nbio() or OSSL_HTTP_REQ_CTX_exchange().
 
 =head1 RETURN VALUES
 
@@ -166,20 +215,36 @@ 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
+OSSL_HTTP_REQ_CTX_set1_req(), and OSSL_HTTP_REQ_CTX_set_expected()
 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_nbio() and OSSL_HTTP_REQ_CTX_nbio_d2i()
+return 1 for success, 0 on error or redirection, -1 if retry is needed.
 
-OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>.
+OSSL_HTTP_REQ_CTX_exchange() and OSSL_HTTP_REQ_CTX_get0_mem_bio()
+returns a pointer to a B<BIO> on success and NULL on failure.
+
+OSSL_HTTP_REQ_CTX_get_resp_len() returns the size of the response contents
+or 0 if not available or an error occurred.
+
+OSSL_HTTP_is_alive() returns 1 if its argument is non-NULL
+and the client requested a persistent connection
+and the server did not disagree on keeping the connection open, else 0.
 
 =head1 SEE ALSO
 
 L<BIO_should_retry(3)>,
 L<BIO_wait(3)>,
+L<ASN1_item_d2i_bio(3)>,
+L<ASN1_item_i2d_mem_bio(3)>,
+L<OSSL_HTTP_open(3)>,
 L<OSSL_HTTP_get(3)>,
-L<OSSL_HTTP_transfer(3)>
+L<OSSL_HTTP_transfer(3)>,
+L<OSSL_HTTP_close(3)>
+
+=head1 HISTORY
+
+The functions described here were added in OpenSSL 3.0.
 
 =head1 COPYRIGHT