xref: /freebsd/crypto/openssl/doc/man3/OSSL_HTTP_REQ_CTX.pod (revision a7148ab39c03abd4d1a84997c70bf96f15dd2a09)
1b077aed3SPierre Pronchery=pod
2b077aed3SPierre Pronchery
3b077aed3SPierre Pronchery=head1 NAME
4b077aed3SPierre Pronchery
5b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX,
6b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_new,
7b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_free,
8b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_request_line,
9b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_add1_header,
10b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_expected,
11b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set1_req,
12b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_nbio,
13b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_nbio_d2i,
14b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_exchange,
15b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_get0_mem_bio,
16b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_get_resp_len,
17b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_max_response_length,
18b077aed3SPierre ProncheryOSSL_HTTP_is_alive
19b077aed3SPierre Pronchery- HTTP client low-level functions
20b077aed3SPierre Pronchery
21b077aed3SPierre Pronchery=head1 SYNOPSIS
22b077aed3SPierre Pronchery
23b077aed3SPierre Pronchery #include <openssl/http.h>
24b077aed3SPierre Pronchery
25b077aed3SPierre Pronchery typedef struct ossl_http_req_ctx_st OSSL_HTTP_REQ_CTX;
26b077aed3SPierre Pronchery
27b077aed3SPierre Pronchery OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size);
28b077aed3SPierre Pronchery void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx);
29b077aed3SPierre Pronchery
30b077aed3SPierre Pronchery int OSSL_HTTP_REQ_CTX_set_request_line(OSSL_HTTP_REQ_CTX *rctx, int method_POST,
31b077aed3SPierre Pronchery                                        const char *server, const char *port,
32b077aed3SPierre Pronchery                                        const char *path);
33b077aed3SPierre Pronchery int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
34b077aed3SPierre Pronchery                                   const char *name, const char *value);
35b077aed3SPierre Pronchery
36b077aed3SPierre Pronchery int OSSL_HTTP_REQ_CTX_set_expected(OSSL_HTTP_REQ_CTX *rctx,
37b077aed3SPierre Pronchery                                    const char *content_type, int asn1,
38b077aed3SPierre Pronchery                                    int timeout, int keep_alive);
39b077aed3SPierre Pronchery int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
40b077aed3SPierre Pronchery                                const ASN1_ITEM *it, const ASN1_VALUE *req);
41b077aed3SPierre Pronchery int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx);
42b077aed3SPierre Pronchery int OSSL_HTTP_REQ_CTX_nbio_d2i(OSSL_HTTP_REQ_CTX *rctx,
43b077aed3SPierre Pronchery                                ASN1_VALUE **pval, const ASN1_ITEM *it);
44b077aed3SPierre Pronchery BIO *OSSL_HTTP_REQ_CTX_exchange(OSSL_HTTP_REQ_CTX *rctx);
45b077aed3SPierre Pronchery
46b077aed3SPierre Pronchery BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx);
47b077aed3SPierre Pronchery size_t OSSL_HTTP_REQ_CTX_get_resp_len(const OSSL_HTTP_REQ_CTX *rctx);
48b077aed3SPierre Pronchery void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
49b077aed3SPierre Pronchery                                                unsigned long len);
50b077aed3SPierre Pronchery
51b077aed3SPierre Pronchery int OSSL_HTTP_is_alive(const OSSL_HTTP_REQ_CTX *rctx);
52b077aed3SPierre Pronchery
53b077aed3SPierre Pronchery=head1 DESCRIPTION
54b077aed3SPierre Pronchery
55b077aed3SPierre ProncheryB<OSSL_HTTP_REQ_CTX> is a context structure for an HTTP request and response,
56b077aed3SPierre Proncheryused to collect all the necessary data to perform that request.
57b077aed3SPierre Pronchery
58b077aed3SPierre ProncheryThis file documents low-level HTTP functions rarely used directly.  High-level
59b077aed3SPierre ProncheryHTTP client functions like L<OSSL_HTTP_get(3)> and L<OSSL_HTTP_transfer(3)>
60b077aed3SPierre Proncheryshould be preferred.
61b077aed3SPierre Pronchery
62b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_new() allocates a new HTTP request context structure,
63b077aed3SPierre Proncherywhich gets populated with the B<BIO> to write/send the request to (I<wbio>),
64b077aed3SPierre Proncherythe B<BIO> to read/receive the response from (I<rbio>, which may be equal to
65b077aed3SPierre ProncheryI<wbio>), and the maximum expected response header line length I<buf_size>.
66b077aed3SPierre ProncheryA value <= 0 indicates that
67b077aed3SPierre Proncherythe B<OSSL_HTTP_DEFAULT_MAX_LINE_LEN> of 4KiB should be used.
68b077aed3SPierre ProncheryI<buf_size> is also used as the number of content bytes that are read at a time.
69b077aed3SPierre ProncheryThe allocated context structure includes an internal memory B<BIO>,
70b077aed3SPierre Proncherywhich collects the HTTP request header lines.
71b077aed3SPierre Pronchery
72b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_free() frees up the HTTP request context I<rctx>.
73b077aed3SPierre ProncheryThe I<rbio> is not free'd, I<wbio> will be free'd if I<free_wbio> is set.
74*a7148ab3SEnji CooperIf the argument is NULL, nothing is done.
75b077aed3SPierre Pronchery
766f1af0d7SPierre ProncheryOSSL_HTTP_REQ_CTX_set_request_line() adds the 1st HTTP request line to I<rctx>.
77b077aed3SPierre ProncheryThe HTTP method is determined by I<method_POST>,
78b077aed3SPierre Proncherywhich should be 1 to indicate C<POST> or 0 to indicate C<GET>.
796f1af0d7SPierre ProncheryI<server> and I<port> may be set to give the server and the optional port that
806f1af0d7SPierre Proncheryan HTTP proxy shall forward the request to, otherwise they must be left NULL.
816f1af0d7SPierre ProncheryI<path> provides the HTTP request path; if left NULL, C</> is used.
826f1af0d7SPierre ProncheryFor backward compatibility, I<path> may begin with C<http://> and thus convey
836f1af0d7SPierre Proncheryan absoluteURI. In this case it indicates HTTP proxy use and provides also the
846f1af0d7SPierre Proncheryserver (and optionally the port) that the proxy shall forward the request to.
856f1af0d7SPierre ProncheryIn this case the I<server> and I<port> arguments must be NULL.
86b077aed3SPierre Pronchery
87b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_add1_header() adds header I<name> with value I<value> to the
88b077aed3SPierre Proncherycontext I<rctx>. It can be called more than once to add multiple header lines.
89b077aed3SPierre ProncheryFor example, to add a C<Host> header for C<example.com> you would call:
90b077aed3SPierre Pronchery
91b077aed3SPierre Pronchery OSSL_HTTP_REQ_CTX_add1_header(ctx, "Host", "example.com");
92b077aed3SPierre Pronchery
93b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_expected() optionally sets in I<rctx> some expectations
94b077aed3SPierre Proncheryof the HTTP client on the response.
95b077aed3SPierre ProncheryDue to the structure of an HTTP request, if the I<keep_alive> argument is
96b077aed3SPierre Proncherynonzero the function must be used before calling OSSL_HTTP_REQ_CTX_set1_req().
97b077aed3SPierre ProncheryIf the I<content_type> parameter
98b077aed3SPierre Proncheryis not NULL then the client will check that the given content type string
99b077aed3SPierre Proncheryis included in the HTTP header of the response and return an error if not.
100b077aed3SPierre ProncheryIf the I<asn1> parameter is nonzero a structure in ASN.1 encoding will be
101b077aed3SPierre Proncheryexpected as the response content and input streaming is disabled.  This means
102b077aed3SPierre Proncherythat an ASN.1 sequence header is required, its length field is checked, and
103b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_get0_mem_bio() should be used to get the buffered response.
104b077aed3SPierre ProncheryOtherwise (by default) any input format is allowed without length checks.
105b077aed3SPierre ProncheryIn this case the BIO given as I<rbio> argument to OSSL_HTTP_REQ_CTX_new() should
106b077aed3SPierre Proncherybe used directly to read the response contents, which may support streaming.
107b077aed3SPierre ProncheryIf the I<timeout> parameter is > 0 this indicates the maximum number of seconds
108b077aed3SPierre Proncherythe subsequent HTTP transfer (sending the request and receiving a response)
109b077aed3SPierre Proncheryis allowed to take.
110b077aed3SPierre ProncheryI<timeout> == 0 enables waiting indefinitely, i.e., no timeout can occur.
111b077aed3SPierre ProncheryThis is the default.
112b077aed3SPierre ProncheryI<timeout> < 0 takes over any value set via the I<overall_timeout> argument of
113b077aed3SPierre ProncheryL<OSSL_HTTP_open(3)> with the default being 0, which means no timeout.
114b077aed3SPierre ProncheryIf the I<keep_alive> parameter is 0, which is the default, the connection is not
115b077aed3SPierre Proncherykept open after receiving a response. This is the default behavior for HTTP 1.0.
116b077aed3SPierre ProncheryIf the value is 1 or 2 then a persistent connection is requested.
117b077aed3SPierre ProncheryIf the value is 2 then a persistent connection is required,
118b077aed3SPierre Proncheryi.e., an error occurs in case the server does not grant it.
119b077aed3SPierre Pronchery
120b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set1_req() finalizes the HTTP request context.
121b077aed3SPierre ProncheryIt is needed if the I<method_POST> parameter in the
122b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_request_line() call was 1
123b077aed3SPierre Proncheryand an ASN.1-encoded request should be sent.
124b077aed3SPierre ProncheryIt must also be used when requesting "keep-alive",
125b077aed3SPierre Proncheryeven if a GET request is going to be sent, in which case I<req> must be NULL.
126b077aed3SPierre ProncheryUnless I<req> is NULL, the function adds the DER encoding of I<req> using
127b077aed3SPierre Proncherythe ASN.1 template I<it> to do the encoding (which does not support streaming).
128b077aed3SPierre ProncheryThe HTTP header C<Content-Length> is filled out with the length of the request.
129b077aed3SPierre ProncheryI<content_type> must be NULL if I<req> is NULL.
130b077aed3SPierre ProncheryIf I<content_type> isn't NULL,
131b077aed3SPierre Proncherythe HTTP header C<Content-Type> is also added with the given string value.
132b077aed3SPierre ProncheryThe header lines are added to the internal memory B<BIO> for the request header.
133b077aed3SPierre Pronchery
134b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_nbio() attempts to send the request prepared in I<rctx>
135b077aed3SPierre Proncheryand to gather the response via HTTP, using the I<wbio> and I<rbio>
136b077aed3SPierre Proncherythat were given when calling OSSL_HTTP_REQ_CTX_new().
137b077aed3SPierre ProncheryThe function may need to be called again if its result is -1, which indicates
138b077aed3SPierre ProncheryL<BIO_should_retry(3)>.  In such a case it is advisable to sleep a little in
139b077aed3SPierre Proncherybetween, using L<BIO_wait(3)> on the read BIO to prevent a busy loop.
140b077aed3SPierre Pronchery
141aa795734SPierre ProncheryOSSL_HTTP_REQ_CTX_nbio_d2i() is like OSSL_HTTP_REQ_CTX_nbio() but on success
142b077aed3SPierre Proncheryin addition parses the response, which must be a DER-encoded ASN.1 structure,
143b077aed3SPierre Proncheryusing the ASN.1 template I<it> and places the result in I<*pval>.
144b077aed3SPierre Pronchery
145b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_exchange() calls OSSL_HTTP_REQ_CTX_nbio() as often as needed
146b077aed3SPierre Proncheryin order to exchange a request and response or until a timeout is reached.
147b077aed3SPierre ProncheryOn success it returns a pointer to the BIO that can be used to read the result.
148b077aed3SPierre ProncheryIf an ASN.1-encoded response was expected, this is the BIO
149b077aed3SPierre Proncheryreturned by OSSL_HTTP_REQ_CTX_get0_mem_bio() when called after the exchange.
150b077aed3SPierre ProncheryThis memory BIO does not support streaming.
151b077aed3SPierre ProncheryOtherwise the returned BIO is the I<rbio> given to OSSL_HTTP_REQ_CTX_new(),
152b077aed3SPierre Proncherywhich may support streaming.
153b077aed3SPierre ProncheryWhen this BIO is returned, it has been read past the end of the response header,
154b077aed3SPierre Proncherysuch that the actual response body can be read from it.
155b077aed3SPierre ProncheryThe returned BIO pointer MUST NOT be freed by the caller.
156b077aed3SPierre Pronchery
157b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>.
158b077aed3SPierre ProncheryBefore the HTTP request is sent, this could be used to adapt its header lines.
159b077aed3SPierre ProncheryI<Use with caution!>
160b077aed3SPierre ProncheryAfter receiving a response via HTTP, the BIO represents the current state of
161b077aed3SPierre Proncheryreading the response header. If the response was expected to be ASN.1 encoded,
162b077aed3SPierre Proncheryits contents can be read via this BIO, which does not support streaming.
163b077aed3SPierre ProncheryThe returned BIO pointer must not be freed by the caller.
164b077aed3SPierre Pronchery
165b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_get_resp_len() returns the size of the response contents
166b077aed3SPierre Proncheryin I<rctx> if provided by the server as <Content-Length> header field, else 0.
167b077aed3SPierre Pronchery
168b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_max_response_length() sets the maximum allowed
169b077aed3SPierre Proncheryresponse content length for I<rctx> to I<len>. If not set or I<len> is 0
170b077aed3SPierre Proncherythen the B<OSSL_HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB.
171b077aed3SPierre ProncheryIf the C<Content-Length> header is present and exceeds this value or
172b077aed3SPierre Proncherythe content is an ASN.1 encoded structure with a length exceeding this value
173b077aed3SPierre Proncheryor both length indications are present but disagree then an error occurs.
174b077aed3SPierre Pronchery
175b077aed3SPierre ProncheryOSSL_HTTP_is_alive() can be used to query if the HTTP connection
176b077aed3SPierre Proncherygiven by I<rctx> is still alive, i.e., has not been closed.
177b077aed3SPierre ProncheryIt returns 0 if I<rctx> is NULL.
178b077aed3SPierre Pronchery
179b077aed3SPierre ProncheryIf the client application requested or required a persistent connection
180b077aed3SPierre Proncheryand this was granted by the server, it can keep I<rctx> as long as it wants
181b077aed3SPierre Proncheryto send further requests and OSSL_HTTP_is_alive() returns nonzero,
182b077aed3SPierre Proncheryelse it should call I<OSSL_HTTP_REQ_CTX_free(rctx)> or L<OSSL_HTTP_close(3)>.
183b077aed3SPierre ProncheryIn case the client application keeps I<rctx> but the connection then dies
184b077aed3SPierre Proncheryfor any reason at the server side, it will notice this obtaining an
185b077aed3SPierre ProncheryI/O error when trying to send the next request via I<rctx>.
186b077aed3SPierre Pronchery
187b077aed3SPierre Pronchery=head1 WARNINGS
188b077aed3SPierre Pronchery
189b077aed3SPierre ProncheryThe server's response may be unexpected if the hostname that was used to
190b077aed3SPierre Proncherycreate the I<wbio>, any C<Host> header, and the host specified in the
191b077aed3SPierre Proncheryrequest URL do not match.
192b077aed3SPierre Pronchery
193b077aed3SPierre ProncheryMany of these functions must be called in a certain order.
194b077aed3SPierre Pronchery
195b077aed3SPierre ProncheryFirst, the HTTP request context must be allocated:
196b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_new().
197b077aed3SPierre Pronchery
198b077aed3SPierre ProncheryThen, the HTTP request must be prepared with request data:
199b077aed3SPierre Pronchery
200b077aed3SPierre Pronchery=over 4
201b077aed3SPierre Pronchery
202b077aed3SPierre Pronchery=item 1.
203b077aed3SPierre Pronchery
204b077aed3SPierre ProncheryCalling OSSL_HTTP_REQ_CTX_set_request_line().
205b077aed3SPierre Pronchery
206b077aed3SPierre Pronchery=item 2.
207b077aed3SPierre Pronchery
208b077aed3SPierre ProncheryAdding extra header lines with OSSL_HTTP_REQ_CTX_add1_header().
209b077aed3SPierre ProncheryThis is optional and may be done multiple times with different names.
210b077aed3SPierre Pronchery
211b077aed3SPierre Pronchery=item 3.
212b077aed3SPierre Pronchery
213b077aed3SPierre ProncheryFinalize the request using OSSL_HTTP_REQ_CTX_set1_req().
214b077aed3SPierre ProncheryThis may be omitted if the GET method is used and "keep-alive" is not requested.
215b077aed3SPierre Pronchery
216b077aed3SPierre Pronchery=back
217b077aed3SPierre Pronchery
218b077aed3SPierre ProncheryWhen the request context is fully prepared, the HTTP exchange may be performed
219b077aed3SPierre Proncherywith OSSL_HTTP_REQ_CTX_nbio() or OSSL_HTTP_REQ_CTX_exchange().
220b077aed3SPierre Pronchery
221b077aed3SPierre Pronchery=head1 RETURN VALUES
222b077aed3SPierre Pronchery
223b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_new() returns a pointer to a B<OSSL_HTTP_REQ_CTX>, or NULL
224b077aed3SPierre Proncheryon error.
225b077aed3SPierre Pronchery
226b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_free() and OSSL_HTTP_REQ_CTX_set_max_response_length()
227b077aed3SPierre Proncherydo not return values.
228b077aed3SPierre Pronchery
229b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set_request_line(), OSSL_HTTP_REQ_CTX_add1_header(),
230b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_set1_req(), and OSSL_HTTP_REQ_CTX_set_expected()
231b077aed3SPierre Proncheryreturn 1 for success and 0 for failure.
232b077aed3SPierre Pronchery
233b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_nbio() and OSSL_HTTP_REQ_CTX_nbio_d2i()
234b077aed3SPierre Proncheryreturn 1 for success, 0 on error or redirection, -1 if retry is needed.
235b077aed3SPierre Pronchery
236b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_exchange() and OSSL_HTTP_REQ_CTX_get0_mem_bio()
237b077aed3SPierre Proncheryreturn a pointer to a B<BIO> on success as described above or NULL on failure.
238b077aed3SPierre ProncheryThe returned BIO must not be freed by the caller.
239b077aed3SPierre Pronchery
240b077aed3SPierre ProncheryOSSL_HTTP_REQ_CTX_get_resp_len() returns the size of the response contents
241b077aed3SPierre Proncheryor 0 if not available or an error occurred.
242b077aed3SPierre Pronchery
243b077aed3SPierre ProncheryOSSL_HTTP_is_alive() returns 1 if its argument is non-NULL
244b077aed3SPierre Proncheryand the client requested a persistent connection
245b077aed3SPierre Proncheryand the server did not disagree on keeping the connection open, else 0.
246b077aed3SPierre Pronchery
247b077aed3SPierre Pronchery=head1 SEE ALSO
248b077aed3SPierre Pronchery
249b077aed3SPierre ProncheryL<BIO_should_retry(3)>,
250b077aed3SPierre ProncheryL<BIO_wait(3)>,
251b077aed3SPierre ProncheryL<ASN1_item_d2i_bio(3)>,
252b077aed3SPierre ProncheryL<ASN1_item_i2d_mem_bio(3)>,
253b077aed3SPierre ProncheryL<OSSL_HTTP_open(3)>,
254b077aed3SPierre ProncheryL<OSSL_HTTP_get(3)>,
255b077aed3SPierre ProncheryL<OSSL_HTTP_transfer(3)>,
256b077aed3SPierre ProncheryL<OSSL_HTTP_close(3)>
257b077aed3SPierre Pronchery
258b077aed3SPierre Pronchery=head1 HISTORY
259b077aed3SPierre Pronchery
260b077aed3SPierre ProncheryThe functions described here were added in OpenSSL 3.0.
261b077aed3SPierre Pronchery
262b077aed3SPierre Pronchery=head1 COPYRIGHT
263b077aed3SPierre Pronchery
264*a7148ab3SEnji CooperCopyright 2015-2024 The OpenSSL Project Authors. All Rights Reserved.
265b077aed3SPierre Pronchery
266b077aed3SPierre ProncheryLicensed under the Apache License 2.0 (the "License").  You may not use
267b077aed3SPierre Proncherythis file except in compliance with the License.  You can obtain a copy
268b077aed3SPierre Proncheryin the file LICENSE in the source distribution or at
269b077aed3SPierre ProncheryL<https://www.openssl.org/source/license.html>.
270b077aed3SPierre Pronchery
271b077aed3SPierre Pronchery=cut
272