2019-10-31 06:39:35 +08:00
|
|
|
/*
|
2022-05-03 18:52:38 +08:00
|
|
|
* Copyright 2001-2022 The OpenSSL Project Authors. All Rights Reserved.
|
2019-10-31 06:39:35 +08:00
|
|
|
* Copyright Siemens AG 2018-2020
|
|
|
|
*
|
|
|
|
* 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
|
|
|
|
* https://www.openssl.org/source/license.html
|
|
|
|
*/
|
|
|
|
|
2022-02-04 22:13:01 +08:00
|
|
|
#include "internal/e_os.h"
|
2019-10-31 06:39:35 +08:00
|
|
|
#include <stdio.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include "crypto/ctype.h"
|
|
|
|
#include <string.h>
|
|
|
|
#include <openssl/asn1.h>
|
|
|
|
#include <openssl/evp.h>
|
|
|
|
#include <openssl/err.h>
|
|
|
|
#include <openssl/httperr.h>
|
|
|
|
#include <openssl/cmperr.h>
|
|
|
|
#include <openssl/buffer.h>
|
|
|
|
#include <openssl/http.h>
|
2022-05-24 01:43:56 +08:00
|
|
|
#include <openssl/trace.h>
|
2019-10-31 06:39:35 +08:00
|
|
|
#include "internal/sockets.h"
|
2021-06-24 17:13:51 +08:00
|
|
|
#include "internal/common.h" /* for ossl_assert() */
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
#define HTTP_PREFIX "HTTP/"
|
|
|
|
#define HTTP_VERSION_PATT "1." /* allow 1.x */
|
2021-06-17 19:29:06 +08:00
|
|
|
#define HTTP_VERSION_STR_LEN sizeof(HTTP_VERSION_PATT) /* == strlen("1.0") */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
|
|
|
|
#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */
|
2021-06-17 19:26:32 +08:00
|
|
|
#define HTTP_LINE1_MINLEN (sizeof(HTTP_PREFIX_VERSION "x 200\n") - 1)
|
2019-10-31 06:39:35 +08:00
|
|
|
#define HTTP_VERSION_MAX_REDIRECTIONS 50
|
|
|
|
|
|
|
|
#define HTTP_STATUS_CODE_OK 200
|
|
|
|
#define HTTP_STATUS_CODE_MOVED_PERMANENTLY 301
|
|
|
|
#define HTTP_STATUS_CODE_FOUND 302
|
|
|
|
|
|
|
|
/* Stateful HTTP request code, supporting blocking and non-blocking I/O */
|
|
|
|
|
|
|
|
/* Opaque HTTP request status structure */
|
|
|
|
|
|
|
|
struct ossl_http_req_ctx_st {
|
|
|
|
int state; /* Current I/O state */
|
2021-05-04 22:58:59 +08:00
|
|
|
unsigned char *buf; /* Buffer to write request or read response */
|
|
|
|
int buf_size; /* Buffer size */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
int free_wbio; /* wbio allocated internally, free with ctx */
|
|
|
|
BIO *wbio; /* BIO to write/send request to */
|
|
|
|
BIO *rbio; /* BIO to read/receive response from */
|
|
|
|
OSSL_HTTP_bio_cb_t upd_fn; /* Optional BIO update callback used for TLS */
|
|
|
|
void *upd_arg; /* Optional arg for update callback function */
|
|
|
|
int use_ssl; /* Use HTTPS */
|
|
|
|
char *proxy; /* Optional proxy name or URI */
|
2022-08-24 02:37:03 +08:00
|
|
|
char *server; /* Optional server hostname */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
char *port; /* Optional server port */
|
2022-06-28 18:06:52 +08:00
|
|
|
BIO *mem; /* Mem BIO holding request header or response */
|
2021-05-04 17:15:36 +08:00
|
|
|
BIO *req; /* BIO holding the request provided by caller */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
int method_POST; /* HTTP method is POST (else GET) */
|
2022-07-02 04:12:08 +08:00
|
|
|
int text; /* Request content type is (likely) text */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
char *expected_ct; /* Optional expected Content-Type */
|
|
|
|
int expect_asn1; /* Response must be ASN.1-encoded */
|
2021-05-04 17:15:36 +08:00
|
|
|
unsigned char *pos; /* Current position sending data */
|
|
|
|
long len_to_send; /* Number of bytes still to send */
|
2021-05-04 22:33:19 +08:00
|
|
|
size_t resp_len; /* Length of response */
|
|
|
|
size_t max_resp_len; /* Maximum length of response, or 0 */
|
2021-05-05 06:09:43 +08:00
|
|
|
int keep_alive; /* Persistent conn. 0=no, 1=prefer, 2=require */
|
|
|
|
time_t max_time; /* Maximum end time of current transfer, or 0 */
|
|
|
|
time_t max_total_time; /* Maximum end time of total transfer, or 0 */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
char *redirection_url; /* Location obtained from HTTP status 301/302 */
|
2019-10-31 06:39:35 +08:00
|
|
|
};
|
|
|
|
|
|
|
|
/* HTTP states */
|
|
|
|
|
2021-05-04 22:33:19 +08:00
|
|
|
#define OHS_NOREAD 0x1000 /* If set no reading should be performed */
|
|
|
|
#define OHS_ERROR (0 | OHS_NOREAD) /* Error condition */
|
2021-05-04 17:15:36 +08:00
|
|
|
#define OHS_ADD_HEADERS (1 | OHS_NOREAD) /* Adding header lines to request */
|
|
|
|
#define OHS_WRITE_INIT (2 | OHS_NOREAD) /* 1st call: ready to start send */
|
2022-07-02 04:12:08 +08:00
|
|
|
#define OHS_WRITE_HDR1 (3 | OHS_NOREAD) /* Request header to be sent */
|
|
|
|
#define OHS_WRITE_HDR (4 | OHS_NOREAD) /* Request header being sent */
|
|
|
|
#define OHS_WRITE_REQ (5 | OHS_NOREAD) /* Request content being sent */
|
|
|
|
#define OHS_FLUSH (6 | OHS_NOREAD) /* Request being flushed */
|
2021-05-04 22:33:19 +08:00
|
|
|
#define OHS_FIRSTLINE 1 /* First line of response being read */
|
|
|
|
#define OHS_HEADERS 2 /* MIME headers of response being read */
|
2022-07-02 04:12:08 +08:00
|
|
|
#define OHS_HEADERS_ERROR 3 /* MIME headers of resp. being read after error */
|
|
|
|
#define OHS_REDIRECT 4 /* MIME headers being read, expecting Location */
|
|
|
|
#define OHS_ASN1_HEADER 5 /* ASN1 sequence header (tag+length) being read */
|
|
|
|
#define OHS_ASN1_CONTENT 6 /* ASN1 content octets being read */
|
|
|
|
#define OHS_ASN1_DONE (7 | OHS_NOREAD) /* ASN1 content read completed */
|
|
|
|
#define OHS_STREAM (8 | OHS_NOREAD) /* HTTP content stream to be read */
|
2019-10-31 06:39:35 +08:00
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
/* Low-level HTTP API implementation */
|
|
|
|
|
2021-05-12 14:37:54 +08:00
|
|
|
OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
|
|
|
OSSL_HTTP_REQ_CTX *rctx;
|
|
|
|
|
|
|
|
if (wbio == NULL || rbio == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL)
|
|
|
|
return NULL;
|
|
|
|
rctx->state = OHS_ERROR;
|
2021-05-11 21:45:22 +08:00
|
|
|
rctx->buf_size = buf_size > 0 ? buf_size : OSSL_HTTP_DEFAULT_MAX_LINE_LEN;
|
2021-05-04 22:58:59 +08:00
|
|
|
rctx->buf = OPENSSL_malloc(rctx->buf_size);
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->wbio = wbio;
|
|
|
|
rctx->rbio = rbio;
|
2021-05-04 22:58:59 +08:00
|
|
|
if (rctx->buf == NULL) {
|
2021-01-26 05:54:17 +08:00
|
|
|
OPENSSL_free(rctx);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
2021-05-11 21:45:22 +08:00
|
|
|
rctx->max_resp_len = OSSL_HTTP_DEFAULT_MAX_RESP_LEN;
|
2021-01-26 05:54:17 +08:00
|
|
|
/* everything else is 0, e.g. rctx->len_to_send, or NULL, e.g. rctx->mem */
|
2019-10-31 06:39:35 +08:00
|
|
|
return rctx;
|
|
|
|
}
|
|
|
|
|
|
|
|
void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx)
|
|
|
|
{
|
|
|
|
if (rctx == NULL)
|
|
|
|
return;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
/*
|
|
|
|
* Use BIO_free_all() because bio_update_fn may prepend or append to cbio.
|
|
|
|
* This also frees any (e.g., SSL/TLS) BIOs linked with bio and,
|
|
|
|
* like BIO_reset(bio), calls SSL_shutdown() to notify/alert the peer.
|
|
|
|
*/
|
|
|
|
if (rctx->free_wbio)
|
|
|
|
BIO_free_all(rctx->wbio);
|
|
|
|
/* do not free rctx->rbio */
|
2021-06-07 22:56:20 +08:00
|
|
|
BIO_free(rctx->mem);
|
|
|
|
BIO_free(rctx->req);
|
2021-05-04 22:58:59 +08:00
|
|
|
OPENSSL_free(rctx->buf);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
OPENSSL_free(rctx->proxy);
|
|
|
|
OPENSSL_free(rctx->server);
|
|
|
|
OPENSSL_free(rctx->port);
|
2021-05-05 06:09:43 +08:00
|
|
|
OPENSSL_free(rctx->expected_ct);
|
2019-10-31 06:39:35 +08:00
|
|
|
OPENSSL_free(rctx);
|
|
|
|
}
|
|
|
|
|
2021-01-30 02:08:45 +08:00
|
|
|
BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
|
|
|
if (rctx == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return rctx->mem;
|
|
|
|
}
|
|
|
|
|
2021-05-05 06:09:43 +08:00
|
|
|
size_t OSSL_HTTP_REQ_CTX_get_resp_len(const OSSL_HTTP_REQ_CTX *rctx)
|
|
|
|
{
|
|
|
|
if (rctx == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return rctx->resp_len;
|
|
|
|
}
|
|
|
|
|
2019-10-31 06:39:35 +08:00
|
|
|
void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
|
|
|
|
unsigned long len)
|
|
|
|
{
|
|
|
|
if (rctx == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return;
|
|
|
|
}
|
2021-05-11 21:45:22 +08:00
|
|
|
rctx->max_resp_len = len != 0 ? (size_t)len : OSSL_HTTP_DEFAULT_MAX_RESP_LEN;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2021-03-21 05:04:58 +08:00
|
|
|
* Create request line using |rctx| and |path| (or "/" in case |path| is NULL).
|
2019-10-31 06:39:35 +08:00
|
|
|
* Server name (and port) must be given if and only if plain HTTP proxy is used.
|
|
|
|
*/
|
2021-03-21 05:04:58 +08:00
|
|
|
int OSSL_HTTP_REQ_CTX_set_request_line(OSSL_HTTP_REQ_CTX *rctx, int method_POST,
|
2021-01-18 19:17:31 +08:00
|
|
|
const char *server, const char *port,
|
|
|
|
const char *path)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
|
|
|
if (rctx == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-26 05:54:17 +08:00
|
|
|
BIO_free(rctx->mem);
|
|
|
|
if ((rctx->mem = BIO_new(BIO_s_mem())) == NULL)
|
|
|
|
return 0;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2021-03-21 05:04:58 +08:00
|
|
|
rctx->method_POST = method_POST != 0;
|
2021-01-18 19:37:47 +08:00
|
|
|
if (BIO_printf(rctx->mem, "%s ", rctx->method_POST ? "POST" : "GET") <= 0)
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (server != NULL) { /* HTTP (but not HTTPS) proxy is used */
|
|
|
|
/*
|
|
|
|
* Section 5.1.2 of RFC 1945 states that the absoluteURI form is only
|
|
|
|
* allowed when using a proxy
|
|
|
|
*/
|
2020-03-25 20:46:02 +08:00
|
|
|
if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0)
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
if (port != NULL && BIO_printf(rctx->mem, ":%s", port) <= 0)
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Make sure path includes a forward slash */
|
|
|
|
if (path == NULL)
|
|
|
|
path = "/";
|
|
|
|
if (path[0] != '/' && BIO_printf(rctx->mem, "/") <= 0)
|
|
|
|
return 0;
|
2021-06-09 15:35:32 +08:00
|
|
|
/*
|
|
|
|
* Add (the rest of) the path and the HTTP version,
|
|
|
|
* which is fixed to 1.0 for straightforward implementation of keep-alive
|
|
|
|
*/
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (BIO_printf(rctx->mem, "%s "HTTP_1_0"\r\n", path) <= 0)
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
2021-06-09 15:35:32 +08:00
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
rctx->resp_len = 0;
|
2021-05-04 17:15:36 +08:00
|
|
|
rctx->state = OHS_ADD_HEADERS;
|
2019-10-31 06:39:35 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
int OSSL_HTTP_REQ_CTX_add1_header(OSSL_HTTP_REQ_CTX *rctx,
|
|
|
|
const char *name, const char *value)
|
|
|
|
{
|
|
|
|
if (rctx == NULL || name == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-26 05:54:17 +08:00
|
|
|
if (rctx->mem == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
if (BIO_puts(rctx->mem, name) <= 0)
|
|
|
|
return 0;
|
|
|
|
if (value != NULL) {
|
|
|
|
if (BIO_write(rctx->mem, ": ", 2) != 2)
|
|
|
|
return 0;
|
|
|
|
if (BIO_puts(rctx->mem, value) <= 0)
|
|
|
|
return 0;
|
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
return BIO_write(rctx->mem, "\r\n", 2) == 2;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
2021-05-05 06:09:43 +08:00
|
|
|
int OSSL_HTTP_REQ_CTX_set_expected(OSSL_HTTP_REQ_CTX *rctx,
|
|
|
|
const char *content_type, int asn1,
|
|
|
|
int timeout, int keep_alive)
|
|
|
|
{
|
|
|
|
if (rctx == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (keep_alive != 0
|
2021-05-04 17:15:36 +08:00
|
|
|
&& rctx->state != OHS_ERROR && rctx->state != OHS_ADD_HEADERS) {
|
2021-05-05 06:09:43 +08:00
|
|
|
/* Cannot anymore set keep-alive in request header */
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
OPENSSL_free(rctx->expected_ct);
|
|
|
|
rctx->expected_ct = NULL;
|
|
|
|
if (content_type != NULL
|
|
|
|
&& (rctx->expected_ct = OPENSSL_strdup(content_type)) == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
rctx->expect_asn1 = asn1;
|
|
|
|
if (timeout >= 0)
|
|
|
|
rctx->max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
2021-07-09 01:45:35 +08:00
|
|
|
else /* take over any |overall_timeout| arg of OSSL_HTTP_open(), else 0 */
|
2021-05-05 06:09:43 +08:00
|
|
|
rctx->max_time = rctx->max_total_time;
|
|
|
|
rctx->keep_alive = keep_alive;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-06-07 22:56:20 +08:00
|
|
|
static int set1_content(OSSL_HTTP_REQ_CTX *rctx,
|
|
|
|
const char *content_type, BIO *req)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2022-07-11 19:52:01 +08:00
|
|
|
long req_len = 0;
|
|
|
|
#ifndef OPENSSL_NO_STDIO
|
2022-07-01 23:46:36 +08:00
|
|
|
FILE *fp = NULL;
|
2022-07-11 19:52:01 +08:00
|
|
|
#endif
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2021-05-04 17:15:36 +08:00
|
|
|
if (rctx == NULL || (req == NULL && content_type != NULL)) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
|
|
|
if (rctx->keep_alive != 0
|
|
|
|
&& !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Connection", "keep-alive"))
|
|
|
|
return 0;
|
|
|
|
|
2021-06-09 15:35:32 +08:00
|
|
|
BIO_free(rctx->req);
|
|
|
|
rctx->req = NULL;
|
2021-05-04 17:15:36 +08:00
|
|
|
if (req == NULL)
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
return 1;
|
|
|
|
if (!rctx->method_POST) {
|
2021-01-18 19:05:11 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2022-07-02 04:12:08 +08:00
|
|
|
if (content_type == NULL) {
|
|
|
|
rctx->text = 1; /* assuming text by default, used just for tracing */
|
|
|
|
} else {
|
|
|
|
if (OPENSSL_strncasecmp(content_type, "text/", 5) == 0)
|
|
|
|
rctx->text = 1;
|
|
|
|
if (BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0)
|
|
|
|
return 0;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2022-07-01 23:46:36 +08:00
|
|
|
/*
|
|
|
|
* BIO_CTRL_INFO yields the data length at least for memory BIOs, but for
|
|
|
|
* file-based BIOs it gives the current position, which is not what we need.
|
|
|
|
*/
|
2022-07-11 19:52:01 +08:00
|
|
|
if (BIO_method_type(req) == BIO_TYPE_FILE) {
|
|
|
|
#ifndef OPENSSL_NO_STDIO
|
|
|
|
if (BIO_get_fp(req, &fp) == 1 && fseek(fp, 0, SEEK_END) == 0) {
|
|
|
|
req_len = ftell(fp);
|
|
|
|
(void)fseek(fp, 0, SEEK_SET);
|
|
|
|
} else {
|
|
|
|
fp = NULL;
|
|
|
|
}
|
|
|
|
#endif
|
2022-07-01 23:46:36 +08:00
|
|
|
} else {
|
|
|
|
req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL);
|
|
|
|
/*
|
|
|
|
* Streaming BIOs likely will not support querying the size at all,
|
|
|
|
* and we assume we got a correct value if req_len > 0.
|
|
|
|
*/
|
2021-06-07 22:56:20 +08:00
|
|
|
}
|
2022-07-11 19:52:01 +08:00
|
|
|
if ((
|
|
|
|
#ifndef OPENSSL_NO_STDIO
|
|
|
|
fp != NULL /* definitely correct req_len */ ||
|
|
|
|
#endif
|
|
|
|
req_len > 0)
|
2022-07-01 23:46:36 +08:00
|
|
|
&& BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) < 0)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
if (!BIO_up_ref(req))
|
|
|
|
return 0;
|
|
|
|
rctx->req = req;
|
|
|
|
return 1;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
2021-03-21 05:17:46 +08:00
|
|
|
int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
|
2021-05-05 06:09:43 +08:00
|
|
|
const ASN1_ITEM *it, const ASN1_VALUE *req)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2021-06-09 15:35:32 +08:00
|
|
|
BIO *mem = NULL;
|
|
|
|
int res = 1;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2021-06-09 15:35:32 +08:00
|
|
|
if (req != NULL)
|
|
|
|
res = (mem = ASN1_item_i2d_mem_bio(it, req)) != NULL;
|
|
|
|
res = res && set1_content(rctx, content_type, mem);
|
2019-10-31 06:39:35 +08:00
|
|
|
BIO_free(mem);
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
2021-05-04 22:58:59 +08:00
|
|
|
static int add1_headers(OSSL_HTTP_REQ_CTX *rctx,
|
|
|
|
const STACK_OF(CONF_VALUE) *headers, const char *host)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
|
|
|
int i;
|
2021-05-02 01:26:53 +08:00
|
|
|
int add_host = host != NULL && *host != '\0';
|
2019-10-31 06:39:35 +08:00
|
|
|
CONF_VALUE *hdr;
|
|
|
|
|
|
|
|
for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
|
|
|
|
hdr = sk_CONF_VALUE_value(headers, i);
|
2022-04-12 18:30:08 +08:00
|
|
|
if (add_host && OPENSSL_strcasecmp("host", hdr->name) == 0)
|
2019-10-31 06:39:35 +08:00
|
|
|
add_host = 0;
|
|
|
|
if (!OSSL_HTTP_REQ_CTX_add1_header(rctx, hdr->name, hdr->value))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (add_host && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Host", host))
|
|
|
|
return 0;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
/* Create OSSL_HTTP_REQ_CTX structure using the values provided. */
|
|
|
|
static OSSL_HTTP_REQ_CTX *http_req_ctx_new(int free_wbio, BIO *wbio, BIO *rbio,
|
|
|
|
OSSL_HTTP_bio_cb_t bio_update_fn,
|
|
|
|
void *arg, int use_ssl,
|
|
|
|
const char *proxy,
|
|
|
|
const char *server, const char *port,
|
2021-05-04 22:33:19 +08:00
|
|
|
int buf_size, int overall_timeout)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
OSSL_HTTP_REQ_CTX *rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, buf_size);
|
2019-10-31 06:39:35 +08:00
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (rctx == NULL)
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
rctx->free_wbio = free_wbio;
|
|
|
|
rctx->upd_fn = bio_update_fn;
|
|
|
|
rctx->upd_arg = arg;
|
|
|
|
rctx->use_ssl = use_ssl;
|
|
|
|
if (proxy != NULL
|
|
|
|
&& (rctx->proxy = OPENSSL_strdup(proxy)) == NULL)
|
|
|
|
goto err;
|
|
|
|
if (server != NULL
|
|
|
|
&& (rctx->server = OPENSSL_strdup(server)) == NULL)
|
|
|
|
goto err;
|
|
|
|
if (port != NULL
|
|
|
|
&& (rctx->port = OPENSSL_strdup(port)) == NULL)
|
|
|
|
goto err;
|
|
|
|
rctx->max_total_time =
|
|
|
|
overall_timeout > 0 ? time(NULL) + overall_timeout : 0;
|
|
|
|
return rctx;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
err:
|
2019-10-31 06:39:35 +08:00
|
|
|
OSSL_HTTP_REQ_CTX_free(rctx);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Parse first HTTP response line. This should be like this: "HTTP/1.0 200 OK".
|
2021-11-30 23:20:26 +08:00
|
|
|
* We need to obtain the status code and (optional) informational message.
|
|
|
|
* Return any received HTTP response status code, or 0 on fatal error.
|
2019-10-31 06:39:35 +08:00
|
|
|
*/
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
static int parse_http_line1(char *line, int *found_keep_alive)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2021-11-30 23:20:26 +08:00
|
|
|
int i, retcode, err;
|
2019-10-31 06:39:35 +08:00
|
|
|
char *code, *reason, *end;
|
|
|
|
|
2021-06-21 14:55:50 +08:00
|
|
|
if (!CHECK_AND_SKIP_PREFIX(line, HTTP_PREFIX_VERSION))
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
goto err;
|
|
|
|
/* above HTTP 1.0, connection persistence is the default */
|
2021-06-21 14:55:50 +08:00
|
|
|
*found_keep_alive = *line > '0';
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
2019-10-31 06:39:35 +08:00
|
|
|
/* Skip to first whitespace (past protocol info) */
|
|
|
|
for (code = line; *code != '\0' && !ossl_isspace(*code); code++)
|
|
|
|
continue;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (*code == '\0')
|
|
|
|
goto err;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
/* Skip past whitespace to start of response code */
|
|
|
|
while (*code != '\0' && ossl_isspace(*code))
|
|
|
|
code++;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (*code == '\0')
|
|
|
|
goto err;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
/* Find end of response code: first whitespace after start of code */
|
|
|
|
for (reason = code; *reason != '\0' && !ossl_isspace(*reason); reason++)
|
|
|
|
continue;
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (*reason == '\0')
|
|
|
|
goto err;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
/* Set end of response code and start of message */
|
|
|
|
*reason++ = '\0';
|
|
|
|
|
|
|
|
/* Attempt to parse numeric code */
|
|
|
|
retcode = strtoul(code, &end, 10);
|
|
|
|
if (*end != '\0')
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
goto err;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
/* Skip over any leading whitespace in message */
|
|
|
|
while (*reason != '\0' && ossl_isspace(*reason))
|
|
|
|
reason++;
|
|
|
|
|
|
|
|
if (*reason != '\0') {
|
|
|
|
/*
|
|
|
|
* Finally zap any trailing whitespace in message (include CRLF)
|
|
|
|
*/
|
|
|
|
|
|
|
|
/* chop any trailing whitespace from reason */
|
|
|
|
/* We know reason has a non-whitespace character so this is OK */
|
|
|
|
for (end = reason + strlen(reason) - 1; ossl_isspace(*end); end--)
|
|
|
|
*end = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (retcode) {
|
|
|
|
case HTTP_STATUS_CODE_OK:
|
|
|
|
case HTTP_STATUS_CODE_MOVED_PERMANENTLY:
|
|
|
|
case HTTP_STATUS_CODE_FOUND:
|
|
|
|
return retcode;
|
|
|
|
default:
|
2021-11-30 23:20:26 +08:00
|
|
|
err = HTTP_R_RECEIVED_ERROR;
|
2019-10-31 06:39:35 +08:00
|
|
|
if (retcode < 400)
|
2021-11-30 23:20:26 +08:00
|
|
|
err = HTTP_R_STATUS_CODE_UNSUPPORTED;
|
2019-10-31 06:39:35 +08:00
|
|
|
if (*reason == '\0')
|
2021-11-30 23:20:26 +08:00
|
|
|
ERR_raise_data(ERR_LIB_HTTP, err, "code=%s", code);
|
2019-10-31 06:39:35 +08:00
|
|
|
else
|
2021-11-30 23:20:26 +08:00
|
|
|
ERR_raise_data(ERR_LIB_HTTP, err, "code=%s, reason=%s", code,
|
|
|
|
reason);
|
|
|
|
return retcode;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
|
|
|
err:
|
2021-11-30 23:20:26 +08:00
|
|
|
for (i = 0; i < 60 && line[i] != '\0'; i++)
|
|
|
|
if (!ossl_isprint(line[i]))
|
|
|
|
line[i] = ' ';
|
2021-05-04 22:33:19 +08:00
|
|
|
line[i] = '\0';
|
|
|
|
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR, "content=%s", line);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
return 0;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
2021-05-04 22:33:19 +08:00
|
|
|
static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, size_t len)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2021-05-04 22:33:19 +08:00
|
|
|
if (rctx->max_resp_len != 0 && len > rctx->max_resp_len)
|
2020-11-04 23:14:00 +08:00
|
|
|
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED,
|
2021-05-04 22:33:19 +08:00
|
|
|
"length=%zu, max=%zu", len, rctx->max_resp_len);
|
2020-11-04 23:14:00 +08:00
|
|
|
if (rctx->resp_len != 0 && rctx->resp_len != len)
|
|
|
|
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH,
|
2021-05-04 22:33:19 +08:00
|
|
|
"ASN.1 length=%zu, Content-Length=%zu",
|
2021-01-26 02:49:58 +08:00
|
|
|
len, rctx->resp_len);
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->resp_len = len;
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2021-11-29 17:07:08 +08:00
|
|
|
static int may_still_retry(time_t max_time, int *ptimeout)
|
|
|
|
{
|
|
|
|
time_t time_diff, now = time(NULL);
|
|
|
|
|
|
|
|
if (max_time != 0) {
|
|
|
|
if (max_time < now) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_RETRY_TIMEOUT);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
time_diff = max_time - now;
|
|
|
|
*ptimeout = time_diff > INT_MAX ? INT_MAX : (int)time_diff;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
2019-10-31 06:39:35 +08:00
|
|
|
/*
|
|
|
|
* Try exchanging request and response via HTTP on (non-)blocking BIO in rctx.
|
|
|
|
* Returns 1 on success, 0 on error or redirection, -1 on BIO_should_retry.
|
|
|
|
*/
|
|
|
|
int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
|
|
|
{
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
int i, found_expected_ct = 0, found_keep_alive = 0;
|
2022-07-02 04:12:08 +08:00
|
|
|
int got_text = 1;
|
2021-01-25 23:18:40 +08:00
|
|
|
long n;
|
2021-05-04 22:33:19 +08:00
|
|
|
size_t resp_len;
|
2019-10-31 06:39:35 +08:00
|
|
|
const unsigned char *p;
|
2021-11-19 03:43:06 +08:00
|
|
|
char *buf, *key, *value, *line_end = NULL;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
if (rctx == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
2021-01-26 05:54:17 +08:00
|
|
|
if (rctx->mem == NULL || rctx->wbio == NULL || rctx->rbio == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
rctx->redirection_url = NULL;
|
|
|
|
next_io:
|
2021-11-19 03:43:06 +08:00
|
|
|
buf = (char *)rctx->buf;
|
2019-10-31 06:39:35 +08:00
|
|
|
if ((rctx->state & OHS_NOREAD) == 0) {
|
2021-11-19 03:43:06 +08:00
|
|
|
if (rctx->expect_asn1) {
|
2021-05-04 22:58:59 +08:00
|
|
|
n = BIO_read(rctx->rbio, rctx->buf, rctx->buf_size);
|
2021-11-19 03:43:06 +08:00
|
|
|
} else {
|
|
|
|
(void)ERR_set_mark();
|
|
|
|
n = BIO_gets(rctx->rbio, buf, rctx->buf_size);
|
|
|
|
if (n == -2) { /* some BIOs, such as SSL, do not support "gets" */
|
|
|
|
(void)ERR_pop_to_mark();
|
|
|
|
n = BIO_get_line(rctx->rbio, buf, rctx->buf_size);
|
|
|
|
} else {
|
|
|
|
(void)ERR_clear_last_mark();
|
|
|
|
}
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
if (n <= 0) {
|
|
|
|
if (BIO_should_retry(rctx->rbio))
|
|
|
|
return -1;
|
2021-01-26 05:54:17 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Write data to memory BIO */
|
2021-05-04 22:58:59 +08:00
|
|
|
if (BIO_write(rctx->mem, rctx->buf, n) != n)
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
switch (rctx->state) {
|
2021-05-04 17:15:36 +08:00
|
|
|
case OHS_ADD_HEADERS:
|
2019-10-31 06:39:35 +08:00
|
|
|
/* Last operation was adding headers: need a final \r\n */
|
|
|
|
if (BIO_write(rctx->mem, "\r\n", 2) != 2) {
|
|
|
|
rctx->state = OHS_ERROR;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
rctx->state = OHS_WRITE_INIT;
|
|
|
|
|
2022-08-24 02:37:03 +08:00
|
|
|
/* fall through */
|
2019-10-31 06:39:35 +08:00
|
|
|
case OHS_WRITE_INIT:
|
2021-05-04 17:15:36 +08:00
|
|
|
rctx->len_to_send = BIO_get_mem_data(rctx->mem, &rctx->pos);
|
2022-07-02 04:12:08 +08:00
|
|
|
rctx->state = OHS_WRITE_HDR1;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2022-08-24 02:37:03 +08:00
|
|
|
/* fall through */
|
2022-07-02 04:12:08 +08:00
|
|
|
case OHS_WRITE_HDR1:
|
2021-05-04 17:15:36 +08:00
|
|
|
case OHS_WRITE_HDR:
|
|
|
|
/* Copy some chunk of data from rctx->mem to rctx->wbio */
|
|
|
|
case OHS_WRITE_REQ:
|
|
|
|
/* Copy some chunk of data from rctx->req to rctx->wbio */
|
|
|
|
|
|
|
|
if (rctx->len_to_send > 0) {
|
2022-07-02 04:12:08 +08:00
|
|
|
size_t sz;
|
2022-05-24 01:43:56 +08:00
|
|
|
|
2022-07-02 04:12:08 +08:00
|
|
|
if (!BIO_write_ex(rctx->wbio, rctx->pos, rctx->len_to_send, &sz)) {
|
2021-05-04 17:15:36 +08:00
|
|
|
if (BIO_should_retry(rctx->wbio))
|
|
|
|
return -1;
|
|
|
|
rctx->state = OHS_ERROR;
|
|
|
|
return 0;
|
|
|
|
}
|
2022-07-02 04:12:08 +08:00
|
|
|
if (OSSL_TRACE_ENABLED(HTTP) && rctx->state == OHS_WRITE_HDR1)
|
|
|
|
OSSL_TRACE(HTTP, "Sending request: [\n");
|
|
|
|
OSSL_TRACE_STRING(HTTP, rctx->state != OHS_WRITE_REQ || rctx->text,
|
|
|
|
rctx->state != OHS_WRITE_REQ, rctx->pos, sz);
|
|
|
|
if (rctx->state == OHS_WRITE_HDR1)
|
|
|
|
rctx->state = OHS_WRITE_HDR;
|
|
|
|
rctx->pos += sz;
|
|
|
|
rctx->len_to_send -= sz;
|
2021-05-04 17:15:36 +08:00
|
|
|
goto next_io;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
2021-05-04 17:15:36 +08:00
|
|
|
if (rctx->state == OHS_WRITE_HDR) {
|
|
|
|
(void)BIO_reset(rctx->mem);
|
|
|
|
rctx->state = OHS_WRITE_REQ;
|
|
|
|
}
|
|
|
|
if (rctx->req != NULL && !BIO_eof(rctx->req)) {
|
2021-05-04 22:58:59 +08:00
|
|
|
n = BIO_read(rctx->req, rctx->buf, rctx->buf_size);
|
2021-05-04 17:15:36 +08:00
|
|
|
if (n <= 0) {
|
2022-06-28 17:51:32 +08:00
|
|
|
if (BIO_should_retry(rctx->req))
|
2021-05-04 17:15:36 +08:00
|
|
|
return -1;
|
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA);
|
|
|
|
return 0;
|
|
|
|
}
|
2021-05-04 22:58:59 +08:00
|
|
|
rctx->pos = rctx->buf;
|
2021-05-04 17:15:36 +08:00
|
|
|
rctx->len_to_send = n;
|
2019-10-31 06:39:35 +08:00
|
|
|
goto next_io;
|
2021-05-04 17:15:36 +08:00
|
|
|
}
|
2022-07-02 04:12:08 +08:00
|
|
|
if (OSSL_TRACE_ENABLED(HTTP))
|
|
|
|
OSSL_TRACE(HTTP, "]\n");
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->state = OHS_FLUSH;
|
|
|
|
|
2022-08-24 02:37:03 +08:00
|
|
|
/* fall through */
|
2019-10-31 06:39:35 +08:00
|
|
|
case OHS_FLUSH:
|
|
|
|
|
|
|
|
i = BIO_flush(rctx->wbio);
|
|
|
|
|
|
|
|
if (i > 0) {
|
|
|
|
rctx->state = OHS_FIRSTLINE;
|
|
|
|
goto next_io;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (BIO_should_retry(rctx->wbio))
|
|
|
|
return -1;
|
|
|
|
|
|
|
|
rctx->state = OHS_ERROR;
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case OHS_ERROR:
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
case OHS_FIRSTLINE:
|
|
|
|
case OHS_HEADERS:
|
|
|
|
case OHS_REDIRECT:
|
|
|
|
|
|
|
|
/* Attempt to read a line in */
|
|
|
|
next_line:
|
|
|
|
/*
|
|
|
|
* Due to strange memory BIO behavior with BIO_gets we have to check
|
|
|
|
* there's a complete line in there before calling BIO_gets or we'll
|
|
|
|
* just get a partial read.
|
|
|
|
*/
|
|
|
|
n = BIO_get_mem_data(rctx->mem, &p);
|
|
|
|
if (n <= 0 || memchr(p, '\n', n) == 0) {
|
2021-05-04 22:58:59 +08:00
|
|
|
if (n >= rctx->buf_size) {
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->state = OHS_ERROR;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
goto next_io;
|
|
|
|
}
|
2021-11-19 03:43:06 +08:00
|
|
|
n = BIO_gets(rctx->mem, buf, rctx->buf_size);
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
if (n <= 0) {
|
|
|
|
if (BIO_should_retry(rctx->mem))
|
|
|
|
goto next_io;
|
|
|
|
rctx->state = OHS_ERROR;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Don't allow excessive lines */
|
2021-05-04 22:58:59 +08:00
|
|
|
if (n == rctx->buf_size) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG);
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->state = OHS_ERROR;
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2022-05-24 01:43:56 +08:00
|
|
|
/* dump all response header lines */
|
|
|
|
if (OSSL_TRACE_ENABLED(HTTP)) {
|
|
|
|
if (rctx->state == OHS_FIRSTLINE)
|
2022-07-02 04:12:08 +08:00
|
|
|
OSSL_TRACE(HTTP, "Received response header: [\n");
|
2022-05-24 01:43:56 +08:00
|
|
|
OSSL_TRACE1(HTTP, "%s", buf);
|
|
|
|
}
|
|
|
|
|
2019-10-31 06:39:35 +08:00
|
|
|
/* First line */
|
|
|
|
if (rctx->state == OHS_FIRSTLINE) {
|
2021-11-19 03:43:06 +08:00
|
|
|
switch (parse_http_line1(buf, &found_keep_alive)) {
|
2019-10-31 06:39:35 +08:00
|
|
|
case HTTP_STATUS_CODE_OK:
|
|
|
|
rctx->state = OHS_HEADERS;
|
|
|
|
goto next_line;
|
|
|
|
case HTTP_STATUS_CODE_MOVED_PERMANENTLY:
|
|
|
|
case HTTP_STATUS_CODE_FOUND: /* i.e., moved temporarily */
|
2021-01-18 19:37:47 +08:00
|
|
|
if (!rctx->method_POST) { /* method is GET */
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->state = OHS_REDIRECT;
|
|
|
|
goto next_line;
|
|
|
|
}
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED);
|
2019-10-31 06:39:35 +08:00
|
|
|
/* redirection is not supported/recommended for POST */
|
|
|
|
/* fall through */
|
|
|
|
default:
|
2022-07-02 04:12:08 +08:00
|
|
|
rctx->state = OHS_HEADERS_ERROR;
|
|
|
|
goto next_line; /* continue parsing and reporting header */
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
}
|
2021-11-19 03:43:06 +08:00
|
|
|
key = buf;
|
2019-10-31 06:39:35 +08:00
|
|
|
value = strchr(key, ':');
|
|
|
|
if (value != NULL) {
|
|
|
|
*(value++) = '\0';
|
|
|
|
while (ossl_isspace(*value))
|
|
|
|
value++;
|
|
|
|
line_end = strchr(value, '\r');
|
|
|
|
if (line_end == NULL)
|
|
|
|
line_end = strchr(value, '\n');
|
|
|
|
if (line_end != NULL)
|
|
|
|
*line_end = '\0';
|
|
|
|
}
|
|
|
|
if (value != NULL && line_end != NULL) {
|
2020-02-20 01:00:26 +08:00
|
|
|
if (rctx->state == OHS_REDIRECT
|
2022-04-12 18:30:08 +08:00
|
|
|
&& OPENSSL_strcasecmp(key, "Location") == 0) {
|
2019-10-31 06:39:35 +08:00
|
|
|
rctx->redirection_url = value;
|
|
|
|
return 0;
|
|
|
|
}
|
2022-05-24 01:43:56 +08:00
|
|
|
if (OPENSSL_strcasecmp(key, "Content-Type") == 0) {
|
2022-07-02 04:12:08 +08:00
|
|
|
got_text = OPENSSL_strncasecmp(value, "text/", 5) == 0;
|
2022-05-24 01:43:56 +08:00
|
|
|
if (rctx->state == OHS_HEADERS
|
|
|
|
&& rctx->expected_ct != NULL) {
|
2022-06-28 23:23:45 +08:00
|
|
|
const char *semicolon;
|
|
|
|
|
|
|
|
if (OPENSSL_strcasecmp(rctx->expected_ct, value) != 0
|
|
|
|
/* ignore past ';' unless expected_ct contains ';' */
|
|
|
|
&& (strchr(rctx->expected_ct, ';') != NULL
|
|
|
|
|| (semicolon = strchr(value, ';')) == NULL
|
|
|
|
|| (size_t)(semicolon - value) != strlen(rctx->expected_ct)
|
|
|
|
|| OPENSSL_strncasecmp(rctx->expected_ct, value,
|
|
|
|
semicolon - value) != 0)) {
|
2022-05-24 01:43:56 +08:00
|
|
|
ERR_raise_data(ERR_LIB_HTTP,
|
|
|
|
HTTP_R_UNEXPECTED_CONTENT_TYPE,
|
|
|
|
"expected=%s, actual=%s",
|
|
|
|
rctx->expected_ct, value);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
found_expected_ct = 1;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
|
2022-04-12 18:30:08 +08:00
|
|
|
if (OPENSSL_strcasecmp(key, "Connection") == 0) {
|
|
|
|
if (OPENSSL_strcasecmp(value, "keep-alive") == 0)
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
found_keep_alive = 1;
|
2022-04-12 18:30:08 +08:00
|
|
|
else if (OPENSSL_strcasecmp(value, "close") == 0)
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
found_keep_alive = 0;
|
2022-04-12 18:30:08 +08:00
|
|
|
} else if (OPENSSL_strcasecmp(key, "Content-Length") == 0) {
|
2021-05-04 22:33:19 +08:00
|
|
|
resp_len = (size_t)strtoul(value, &line_end, 10);
|
2019-10-31 06:39:35 +08:00
|
|
|
if (line_end == value || *line_end != '\0') {
|
2020-11-04 23:14:00 +08:00
|
|
|
ERR_raise_data(ERR_LIB_HTTP,
|
|
|
|
HTTP_R_ERROR_PARSING_CONTENT_LENGTH,
|
|
|
|
"input=%s", value);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (!check_set_resp_len(rctx, resp_len))
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-01-26 02:49:58 +08:00
|
|
|
/* Look for blank line indicating end of headers */
|
2021-05-04 22:58:59 +08:00
|
|
|
for (p = rctx->buf; *p != '\0'; p++) {
|
2019-10-31 06:39:35 +08:00
|
|
|
if (*p != '\r' && *p != '\n')
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (*p != '\0') /* not end of headers */
|
|
|
|
goto next_line;
|
2022-07-02 04:12:08 +08:00
|
|
|
if (OSSL_TRACE_ENABLED(HTTP))
|
|
|
|
OSSL_TRACE(HTTP, "]\n");
|
2019-10-31 06:39:35 +08:00
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (rctx->keep_alive != 0 /* do not let server initiate keep_alive */
|
|
|
|
&& !found_keep_alive /* otherwise there is no change */) {
|
|
|
|
if (rctx->keep_alive == 2) {
|
|
|
|
rctx->keep_alive = 0;
|
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_SERVER_CANCELED_CONNECTION);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
rctx->keep_alive = 0;
|
|
|
|
}
|
|
|
|
|
2022-07-02 04:12:08 +08:00
|
|
|
if (rctx->state == OHS_HEADERS_ERROR) {
|
|
|
|
if (OSSL_TRACE_ENABLED(HTTP)) {
|
|
|
|
int printed_final_nl = 0;
|
|
|
|
|
|
|
|
OSSL_TRACE(HTTP, "Received error response body: [\n");
|
|
|
|
while ((n = BIO_read(rctx->rbio, rctx->buf, rctx->buf_size)) > 0
|
|
|
|
|| (OSSL_sleep(100), BIO_should_retry(rctx->rbio))) {
|
|
|
|
OSSL_TRACE_STRING(HTTP, got_text, 1, rctx->buf, n);
|
|
|
|
if (n > 0)
|
|
|
|
printed_final_nl = rctx->buf[n - 1] == '\n';
|
|
|
|
}
|
|
|
|
OSSL_TRACE1(HTTP, "%s]\n", printed_final_nl ? "" : "\n");
|
|
|
|
(void)printed_final_nl; /* avoid warning unless enable-trace */
|
|
|
|
}
|
2021-11-30 23:44:59 +08:00
|
|
|
return 0;
|
2022-05-24 01:43:56 +08:00
|
|
|
}
|
2021-11-30 23:44:59 +08:00
|
|
|
|
|
|
|
if (rctx->expected_ct != NULL && !found_expected_ct) {
|
|
|
|
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MISSING_CONTENT_TYPE,
|
|
|
|
"expected=%s", rctx->expected_ct);
|
|
|
|
return 0;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
if (rctx->state == OHS_REDIRECT) {
|
|
|
|
/* http status code indicated redirect but there was no Location */
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_MISSING_REDIRECT_LOCATION);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!rctx->expect_asn1) {
|
2021-05-04 22:33:19 +08:00
|
|
|
rctx->state = OHS_STREAM;
|
|
|
|
return 1;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
rctx->state = OHS_ASN1_HEADER;
|
|
|
|
|
|
|
|
/* Fall thru */
|
|
|
|
case OHS_ASN1_HEADER:
|
|
|
|
/*
|
|
|
|
* Now reading ASN1 header: can read at least 2 bytes which is enough
|
|
|
|
* for ASN1 SEQUENCE header and either length field or at least the
|
|
|
|
* length of the length field.
|
|
|
|
*/
|
|
|
|
n = BIO_get_mem_data(rctx->mem, &p);
|
|
|
|
if (n < 2)
|
|
|
|
goto next_io;
|
|
|
|
|
|
|
|
/* Check it is an ASN1 SEQUENCE */
|
|
|
|
if (*p++ != (V_ASN1_SEQUENCE | V_ASN1_CONSTRUCTED)) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_MISSING_ASN1_ENCODING);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Check out length field */
|
|
|
|
if ((*p & 0x80) != 0) {
|
|
|
|
/*
|
|
|
|
* If MSB set on initial length octet we can now always read 6
|
|
|
|
* octets: make sure we have them.
|
|
|
|
*/
|
|
|
|
if (n < 6)
|
|
|
|
goto next_io;
|
|
|
|
n = *p & 0x7F;
|
|
|
|
/* Not NDEF or excessive length */
|
|
|
|
if (n == 0 || (n > 4)) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_ASN1_LENGTH);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
p++;
|
|
|
|
resp_len = 0;
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
resp_len <<= 8;
|
|
|
|
resp_len |= *p++;
|
|
|
|
}
|
|
|
|
resp_len += n + 2;
|
|
|
|
} else {
|
|
|
|
resp_len = *p + 2;
|
|
|
|
}
|
|
|
|
if (!check_set_resp_len(rctx, resp_len))
|
|
|
|
return 0;
|
|
|
|
|
2021-05-04 22:33:19 +08:00
|
|
|
rctx->state = OHS_ASN1_CONTENT;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
/* Fall thru */
|
2021-05-04 22:33:19 +08:00
|
|
|
case OHS_ASN1_CONTENT:
|
2019-10-31 06:39:35 +08:00
|
|
|
default:
|
|
|
|
n = BIO_get_mem_data(rctx->mem, NULL);
|
2021-05-04 22:33:19 +08:00
|
|
|
if (n < 0 || (size_t)n < rctx->resp_len)
|
2019-10-31 06:39:35 +08:00
|
|
|
goto next_io;
|
|
|
|
|
2021-05-04 22:33:19 +08:00
|
|
|
rctx->state = OHS_ASN1_DONE;
|
2019-10-31 06:39:35 +08:00
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2021-05-05 06:09:43 +08:00
|
|
|
int OSSL_HTTP_REQ_CTX_nbio_d2i(OSSL_HTTP_REQ_CTX *rctx,
|
|
|
|
ASN1_VALUE **pval, const ASN1_ITEM *it)
|
|
|
|
{
|
|
|
|
const unsigned char *p;
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
*pval = NULL;
|
|
|
|
if ((rv = OSSL_HTTP_REQ_CTX_nbio(rctx)) != 1)
|
|
|
|
return rv;
|
|
|
|
*pval = ASN1_item_d2i(NULL, &p, BIO_get_mem_data(rctx->mem, &p), it);
|
|
|
|
return *pval != NULL;
|
|
|
|
|
|
|
|
}
|
|
|
|
|
2019-10-31 06:39:35 +08:00
|
|
|
#ifndef OPENSSL_NO_SOCK
|
|
|
|
|
|
|
|
/* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */
|
2021-05-04 22:58:59 +08:00
|
|
|
static BIO *http_new_bio(const char *server /* optionally includes ":port" */,
|
2020-02-20 01:00:26 +08:00
|
|
|
const char *server_port /* explicit server port */,
|
2021-05-01 00:36:00 +08:00
|
|
|
int use_ssl,
|
|
|
|
const char *proxy /* optionally includes ":port" */,
|
|
|
|
const char *proxy_port /* explicit proxy port */)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2021-05-01 00:36:00 +08:00
|
|
|
const char *host = server;
|
2019-10-31 06:39:35 +08:00
|
|
|
const char *port = server_port;
|
|
|
|
BIO *cbio;
|
|
|
|
|
2020-03-25 20:46:02 +08:00
|
|
|
if (!ossl_assert(server != NULL))
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
|
|
|
|
if (proxy != NULL) {
|
|
|
|
host = proxy;
|
2021-05-01 00:36:00 +08:00
|
|
|
port = proxy_port;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
2020-02-20 01:00:26 +08:00
|
|
|
|
2021-05-01 00:36:00 +08:00
|
|
|
if (port == NULL && strchr(host, ':') == NULL)
|
|
|
|
port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
|
2020-02-20 01:00:26 +08:00
|
|
|
|
|
|
|
cbio = BIO_new_connect(host /* optionally includes ":port" */);
|
2019-10-31 06:39:35 +08:00
|
|
|
if (cbio == NULL)
|
|
|
|
goto end;
|
|
|
|
if (port != NULL)
|
|
|
|
(void)BIO_set_conn_port(cbio, port);
|
|
|
|
|
|
|
|
end:
|
|
|
|
return cbio;
|
|
|
|
}
|
2020-02-22 04:41:56 +08:00
|
|
|
#endif /* OPENSSL_NO_SOCK */
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2021-05-03 22:33:10 +08:00
|
|
|
/* Exchange request and response via HTTP on (non-)blocking BIO */
|
2021-05-05 06:09:43 +08:00
|
|
|
BIO *OSSL_HTTP_REQ_CTX_exchange(OSSL_HTTP_REQ_CTX *rctx)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
|
|
|
int rv;
|
|
|
|
|
|
|
|
if (rctx == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
rv = OSSL_HTTP_REQ_CTX_nbio(rctx);
|
|
|
|
if (rv != -1)
|
|
|
|
break;
|
|
|
|
/* BIO_should_retry was true */
|
|
|
|
/* will not actually wait if rctx->max_time == 0 */
|
2020-02-22 04:41:56 +08:00
|
|
|
if (BIO_wait(rctx->rbio, rctx->max_time, 100 /* milliseconds */) <= 0)
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (rv == 0) {
|
|
|
|
if (rctx->redirection_url == NULL) { /* an error occurred */
|
2021-03-08 20:47:33 +08:00
|
|
|
if (rctx->len_to_send > 0)
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_SENDING);
|
2019-10-31 06:39:35 +08:00
|
|
|
else
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_RECEIVING);
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
2021-05-04 22:33:19 +08:00
|
|
|
return rctx->state == OHS_STREAM ? rctx->rbio : rctx->mem;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
int OSSL_HTTP_is_alive(const OSSL_HTTP_REQ_CTX *rctx)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
return rctx != NULL && rctx->keep_alive != 0;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
/* High-level HTTP API implementation */
|
|
|
|
|
|
|
|
/* Initiate an HTTP session using bio, else use given server, proxy, etc. */
|
2021-05-05 06:09:43 +08:00
|
|
|
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,
|
2021-05-04 22:33:19 +08:00
|
|
|
int buf_size, int overall_timeout)
|
2021-05-05 06:09:43 +08:00
|
|
|
{
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
BIO *cbio; /* == bio if supplied, used as connection BIO if rbio is NULL */
|
|
|
|
OSSL_HTTP_REQ_CTX *rctx = NULL;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
if (use_ssl && bio_update_fn == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_TLS_NOT_ENABLED);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if (rbio != NULL && (bio == NULL || bio_update_fn != NULL)) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2020-03-25 20:46:02 +08:00
|
|
|
if (bio != NULL) {
|
2019-10-31 06:39:35 +08:00
|
|
|
cbio = bio;
|
2021-05-03 22:33:10 +08:00
|
|
|
if (proxy != NULL || no_proxy != NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT);
|
|
|
|
return NULL;
|
|
|
|
}
|
2020-03-25 20:46:02 +08:00
|
|
|
} else {
|
2020-02-22 04:41:56 +08:00
|
|
|
#ifndef OPENSSL_NO_SOCK
|
2021-05-01 00:36:00 +08:00
|
|
|
char *proxy_host = NULL, *proxy_port = NULL;
|
|
|
|
|
2020-03-25 20:46:02 +08:00
|
|
|
if (server == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2020-03-25 20:46:02 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (port != NULL && *port == '\0')
|
2020-03-25 20:46:02 +08:00
|
|
|
port = NULL;
|
|
|
|
if (port == NULL && strchr(server, ':') == NULL)
|
|
|
|
port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
|
2021-06-12 23:43:15 +08:00
|
|
|
proxy = OSSL_HTTP_adapt_proxy(proxy, no_proxy, server, use_ssl);
|
2021-05-01 00:36:00 +08:00
|
|
|
if (proxy != NULL
|
|
|
|
&& !OSSL_HTTP_parse_url(proxy, NULL /* use_ssl */, NULL /* user */,
|
|
|
|
&proxy_host, &proxy_port, NULL /* num */,
|
|
|
|
NULL /* path */, NULL, NULL))
|
|
|
|
return NULL;
|
2021-05-04 22:58:59 +08:00
|
|
|
cbio = http_new_bio(server, port, use_ssl, proxy_host, proxy_port);
|
2021-05-01 00:36:00 +08:00
|
|
|
OPENSSL_free(proxy_host);
|
|
|
|
OPENSSL_free(proxy_port);
|
|
|
|
if (cbio == NULL)
|
2020-02-22 04:41:56 +08:00
|
|
|
return NULL;
|
|
|
|
#else
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
2020-02-22 04:41:56 +08:00
|
|
|
#endif
|
2020-03-25 20:46:02 +08:00
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
(void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (rbio == NULL && BIO_do_connect_retry(cbio, overall_timeout, -1) <= 0) {
|
|
|
|
if (bio == NULL) /* cbio was not provided by caller */
|
|
|
|
BIO_free_all(cbio);
|
2019-10-31 06:39:35 +08:00
|
|
|
goto end;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
}
|
|
|
|
/* now overall_timeout is guaranteed to be >= 0 */
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2021-11-26 23:46:13 +08:00
|
|
|
/* adapt in order to fix callback design flaw, see #17088 */
|
2019-10-31 06:39:35 +08:00
|
|
|
/* callback can be used to wrap or prepend TLS session */
|
|
|
|
if (bio_update_fn != NULL) {
|
|
|
|
BIO *orig_bio = cbio;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
2022-06-28 23:47:40 +08:00
|
|
|
cbio = (*bio_update_fn)(cbio, arg, 1 /* connect */, use_ssl != 0);
|
2019-10-31 06:39:35 +08:00
|
|
|
if (cbio == NULL) {
|
2021-07-20 17:19:39 +08:00
|
|
|
if (bio == NULL) /* cbio was not provided by caller */
|
|
|
|
BIO_free_all(orig_bio);
|
2019-10-31 06:39:35 +08:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
rctx = http_req_ctx_new(bio == NULL, cbio, rbio != NULL ? rbio : cbio,
|
|
|
|
bio_update_fn, arg, use_ssl, proxy, server, port,
|
2021-05-04 22:33:19 +08:00
|
|
|
buf_size, overall_timeout);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
|
|
|
end:
|
|
|
|
if (rctx != NULL)
|
|
|
|
/* remove any spurious error queue entries by ssl_add_cert_chain() */
|
|
|
|
(void)ERR_pop_to_mark();
|
|
|
|
else
|
|
|
|
(void)ERR_clear_last_mark();
|
|
|
|
|
|
|
|
return rctx;
|
|
|
|
}
|
|
|
|
|
2021-06-09 15:40:48 +08:00
|
|
|
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)
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
{
|
|
|
|
int use_http_proxy;
|
|
|
|
|
|
|
|
if (rctx == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
use_http_proxy = rctx->proxy != NULL && !rctx->use_ssl;
|
2021-12-01 03:06:09 +08:00
|
|
|
if (use_http_proxy && rctx->server == NULL) {
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT);
|
|
|
|
return 0;
|
|
|
|
}
|
2021-05-04 22:33:19 +08:00
|
|
|
rctx->max_resp_len = max_resp_len; /* allows for 0: indefinite */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
2021-05-04 17:15:36 +08:00
|
|
|
return OSSL_HTTP_REQ_CTX_set_request_line(rctx, req != NULL,
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
use_http_proxy ? rctx->server
|
|
|
|
: NULL, rctx->port, path)
|
2021-05-04 22:58:59 +08:00
|
|
|
&& add1_headers(rctx, headers, rctx->server)
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
&& OSSL_HTTP_REQ_CTX_set_expected(rctx, expected_content_type,
|
|
|
|
expect_asn1, timeout, keep_alive)
|
2021-06-07 22:56:20 +08:00
|
|
|
&& set1_content(rctx, content_type, req);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/*-
|
|
|
|
* Exchange single HTTP request and response according to rctx.
|
|
|
|
* If rctx->method_POST then use POST, else use GET and ignore content_type.
|
|
|
|
* The redirection_url output (freed by caller) parameter is used only for GET.
|
|
|
|
*/
|
|
|
|
BIO *OSSL_HTTP_exchange(OSSL_HTTP_REQ_CTX *rctx, char **redirection_url)
|
|
|
|
{
|
|
|
|
BIO *resp;
|
|
|
|
|
|
|
|
if (rctx == NULL) {
|
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (redirection_url != NULL)
|
|
|
|
*redirection_url = NULL; /* do this beforehand to prevent dbl free */
|
2019-10-31 06:39:35 +08:00
|
|
|
|
2021-05-05 06:09:43 +08:00
|
|
|
resp = OSSL_HTTP_REQ_CTX_exchange(rctx);
|
2019-10-31 06:39:35 +08:00
|
|
|
if (resp == NULL) {
|
|
|
|
if (rctx->redirection_url != NULL) {
|
|
|
|
if (redirection_url == NULL)
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED);
|
2019-10-31 06:39:35 +08:00
|
|
|
else
|
|
|
|
/* may be NULL if out of memory: */
|
|
|
|
*redirection_url = OPENSSL_strdup(rctx->redirection_url);
|
|
|
|
} else {
|
|
|
|
char buf[200];
|
|
|
|
unsigned long err = ERR_peek_error();
|
|
|
|
int lib = ERR_GET_LIB(err);
|
|
|
|
int reason = ERR_GET_REASON(err);
|
|
|
|
|
|
|
|
if (lib == ERR_LIB_SSL || lib == ERR_LIB_HTTP
|
|
|
|
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_TIMEOUT)
|
|
|
|
|| (lib == ERR_LIB_BIO && reason == BIO_R_CONNECT_ERROR)
|
2020-03-25 20:46:02 +08:00
|
|
|
#ifndef OPENSSL_NO_CMP
|
2019-10-31 06:39:35 +08:00
|
|
|
|| (lib == ERR_LIB_CMP
|
2020-02-11 23:07:00 +08:00
|
|
|
&& reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
|
2020-03-25 20:46:02 +08:00
|
|
|
#endif
|
2020-02-11 23:07:00 +08:00
|
|
|
) {
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (rctx->server != NULL) {
|
2021-05-02 04:04:17 +08:00
|
|
|
BIO_snprintf(buf, sizeof(buf), "server=http%s://%s%s%s",
|
|
|
|
rctx->use_ssl ? "s" : "", rctx->server,
|
|
|
|
rctx->port != NULL ? ":" : "",
|
|
|
|
rctx->port != NULL ? rctx->port : "");
|
|
|
|
ERR_add_error_data(1, buf);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
}
|
|
|
|
if (rctx->proxy != NULL)
|
|
|
|
ERR_add_error_data(2, " proxy=", rctx->proxy);
|
2019-10-31 06:39:35 +08:00
|
|
|
if (err == 0) {
|
2021-05-02 04:04:17 +08:00
|
|
|
BIO_snprintf(buf, sizeof(buf), " peer has disconnected%s",
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
rctx->use_ssl ? " violating the protocol" :
|
2019-10-31 06:39:35 +08:00
|
|
|
", likely because it requires the use of TLS");
|
|
|
|
ERR_add_error_data(1, buf);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2021-03-21 05:49:27 +08:00
|
|
|
|
|
|
|
if (resp != NULL && !BIO_up_ref(resp))
|
|
|
|
resp = NULL;
|
2019-10-31 06:39:35 +08:00
|
|
|
return resp;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
|
|
|
|
{
|
|
|
|
if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (*new_url == '/') /* redirection to same server => same protocol */
|
|
|
|
return 1;
|
2021-06-17 18:55:14 +08:00
|
|
|
if (HAS_PREFIX(old_url, OSSL_HTTPS_NAME":") &&
|
|
|
|
!HAS_PREFIX(new_url, OSSL_HTTPS_NAME":")) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
|
2019-10-31 06:39:35 +08:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
return 1;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Get data via HTTP from server at given URL, potentially with redirection */
|
2020-02-20 01:00:26 +08:00
|
|
|
BIO *OSSL_HTTP_get(const char *url, const char *proxy, const char *no_proxy,
|
2019-10-31 06:39:35 +08:00
|
|
|
BIO *bio, BIO *rbio,
|
|
|
|
OSSL_HTTP_bio_cb_t bio_update_fn, void *arg,
|
2021-05-12 14:37:54 +08:00
|
|
|
int buf_size, const STACK_OF(CONF_VALUE) *headers,
|
2021-05-05 06:09:43 +08:00
|
|
|
const char *expected_ct, int expect_asn1,
|
2021-05-13 00:19:07 +08:00
|
|
|
size_t max_resp_len, int timeout)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2021-05-05 06:09:43 +08:00
|
|
|
char *current_url, *redirection_url = NULL;
|
2019-10-31 06:39:35 +08:00
|
|
|
int n_redirs = 0;
|
|
|
|
char *host;
|
|
|
|
char *port;
|
|
|
|
char *path;
|
|
|
|
int use_ssl;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
OSSL_HTTP_REQ_CTX *rctx;
|
2019-10-31 06:39:35 +08:00
|
|
|
BIO *resp = NULL;
|
2021-11-29 17:07:08 +08:00
|
|
|
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
if (url == NULL) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
if ((current_url = OPENSSL_strdup(url)) == NULL)
|
|
|
|
return NULL;
|
|
|
|
|
|
|
|
for (;;) {
|
2021-01-29 05:10:47 +08:00
|
|
|
if (!OSSL_HTTP_parse_url(current_url, &use_ssl, NULL /* user */, &host,
|
|
|
|
&port, NULL /* port_num */, &path, NULL, NULL))
|
2019-10-31 06:39:35 +08:00
|
|
|
break;
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
rctx = OSSL_HTTP_open(host, port, proxy, no_proxy,
|
|
|
|
use_ssl, bio, rbio, bio_update_fn, arg,
|
2021-05-04 22:33:19 +08:00
|
|
|
buf_size, timeout);
|
2021-05-02 01:47:38 +08:00
|
|
|
new_rpath:
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
if (rctx != NULL) {
|
2021-06-09 15:40:48 +08:00
|
|
|
if (!OSSL_HTTP_set1_request(rctx, path, headers,
|
|
|
|
NULL /* content_type */,
|
|
|
|
NULL /* req */,
|
|
|
|
expected_ct, expect_asn1, max_resp_len,
|
|
|
|
-1 /* use same max time (timeout) */,
|
|
|
|
0 /* no keep_alive */))
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
OSSL_HTTP_REQ_CTX_free(rctx);
|
2021-05-02 01:47:38 +08:00
|
|
|
else
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
resp = OSSL_HTTP_exchange(rctx, &redirection_url);
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
OPENSSL_free(path);
|
|
|
|
if (resp == NULL && redirection_url != NULL) {
|
2021-11-29 17:07:08 +08:00
|
|
|
if (redirection_ok(++n_redirs, current_url, redirection_url)
|
|
|
|
&& may_still_retry(max_time, &timeout)) {
|
2019-10-31 06:39:35 +08:00
|
|
|
(void)BIO_reset(bio);
|
|
|
|
OPENSSL_free(current_url);
|
|
|
|
current_url = redirection_url;
|
|
|
|
if (*redirection_url == '/') { /* redirection to same server */
|
|
|
|
path = OPENSSL_strdup(redirection_url);
|
2022-06-22 16:41:12 +08:00
|
|
|
if (path == NULL) {
|
|
|
|
OPENSSL_free(host);
|
|
|
|
OPENSSL_free(port);
|
|
|
|
(void)OSSL_HTTP_close(rctx, 1);
|
|
|
|
BIO_free(resp);
|
|
|
|
OPENSSL_free(current_url);
|
|
|
|
return NULL;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
goto new_rpath;
|
|
|
|
}
|
|
|
|
OPENSSL_free(host);
|
|
|
|
OPENSSL_free(port);
|
2021-05-02 01:47:38 +08:00
|
|
|
(void)OSSL_HTTP_close(rctx, 1);
|
2019-10-31 06:39:35 +08:00
|
|
|
continue;
|
|
|
|
}
|
2021-05-02 01:47:38 +08:00
|
|
|
/* if redirection not allowed, ignore it */
|
2019-10-31 06:39:35 +08:00
|
|
|
OPENSSL_free(redirection_url);
|
|
|
|
}
|
|
|
|
OPENSSL_free(host);
|
|
|
|
OPENSSL_free(port);
|
2021-05-02 01:47:38 +08:00
|
|
|
if (!OSSL_HTTP_close(rctx, resp != NULL)) {
|
|
|
|
BIO_free(resp);
|
|
|
|
resp = NULL;
|
|
|
|
}
|
2019-10-31 06:39:35 +08:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
OPENSSL_free(current_url);
|
|
|
|
return resp;
|
|
|
|
}
|
|
|
|
|
2021-05-03 22:33:10 +08:00
|
|
|
/* Exchange request and response over a connection managed via |prctx| */
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
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_ct, int expect_asn1,
|
2021-05-04 22:33:19 +08:00
|
|
|
size_t max_resp_len, int timeout, int keep_alive)
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
{
|
|
|
|
OSSL_HTTP_REQ_CTX *rctx = prctx == NULL ? NULL : *prctx;
|
|
|
|
BIO *resp = NULL;
|
|
|
|
|
|
|
|
if (rctx == NULL) {
|
|
|
|
rctx = OSSL_HTTP_open(server, port, proxy, no_proxy,
|
|
|
|
use_ssl, bio, rbio, bio_update_fn, arg,
|
2021-05-04 22:33:19 +08:00
|
|
|
buf_size, timeout);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
timeout = -1; /* Already set during opening the connection */
|
|
|
|
}
|
|
|
|
if (rctx != NULL) {
|
2021-06-09 15:40:48 +08:00
|
|
|
if (OSSL_HTTP_set1_request(rctx, path, headers, content_type, req,
|
|
|
|
expected_ct, expect_asn1,
|
|
|
|
max_resp_len, timeout, keep_alive))
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
resp = OSSL_HTTP_exchange(rctx, NULL);
|
|
|
|
if (resp == NULL || !OSSL_HTTP_is_alive(rctx)) {
|
2021-05-03 22:33:10 +08:00
|
|
|
if (!OSSL_HTTP_close(rctx, resp != NULL)) {
|
|
|
|
BIO_free(resp);
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
resp = NULL;
|
2021-05-03 22:33:10 +08:00
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
rctx = NULL;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (prctx != NULL)
|
|
|
|
*prctx = rctx;
|
|
|
|
return resp;
|
|
|
|
}
|
|
|
|
|
2021-05-05 06:09:43 +08:00
|
|
|
int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok)
|
2019-10-31 06:39:35 +08:00
|
|
|
{
|
2021-11-22 03:55:35 +08:00
|
|
|
BIO *wbio;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
int ret = 1;
|
|
|
|
|
2021-11-22 03:55:35 +08:00
|
|
|
/* callback can be used to finish TLS session and free its BIO */
|
|
|
|
if (rctx != NULL && rctx->upd_fn != NULL) {
|
|
|
|
wbio = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg,
|
|
|
|
0 /* disconnect */, ok);
|
|
|
|
ret = wbio != NULL;
|
|
|
|
if (ret)
|
|
|
|
rctx->wbio = wbio;
|
|
|
|
}
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
OSSL_HTTP_REQ_CTX_free(rctx);
|
|
|
|
return ret;
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
/* BASE64 encoder used for encoding basic proxy authentication credentials */
|
|
|
|
static char *base64encode(const void *buf, size_t len)
|
|
|
|
{
|
|
|
|
int i;
|
|
|
|
size_t outl;
|
|
|
|
char *out;
|
|
|
|
|
|
|
|
/* Calculate size of encoded data */
|
|
|
|
outl = (len / 3);
|
|
|
|
if (len % 3 > 0)
|
|
|
|
outl++;
|
|
|
|
outl <<= 2;
|
|
|
|
out = OPENSSL_malloc(outl + 1);
|
|
|
|
if (out == NULL)
|
|
|
|
return 0;
|
|
|
|
|
|
|
|
i = EVP_EncodeBlock((unsigned char *)out, buf, len);
|
|
|
|
if (!ossl_assert(0 <= i && (size_t)i <= outl)) {
|
|
|
|
OPENSSL_free(out);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
return out;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
|
|
|
* Promote the given connection BIO using the CONNECT method for a TLS proxy.
|
|
|
|
* This is typically called by an app, so bio_err and prog are used unless NULL
|
|
|
|
* to print additional diagnostic information in a user-oriented way.
|
|
|
|
*/
|
|
|
|
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)
|
|
|
|
{
|
2020-03-25 20:46:02 +08:00
|
|
|
#undef BUF_SIZE
|
|
|
|
#define BUF_SIZE (8 * 1024)
|
2019-10-31 06:39:35 +08:00
|
|
|
char *mbuf = OPENSSL_malloc(BUF_SIZE);
|
|
|
|
char *mbufp;
|
|
|
|
int read_len = 0;
|
|
|
|
int ret = 0;
|
|
|
|
BIO *fbio = BIO_new(BIO_f_buffer());
|
2020-02-22 04:41:56 +08:00
|
|
|
int rv;
|
2019-10-31 06:39:35 +08:00
|
|
|
time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;
|
|
|
|
|
2020-03-25 20:46:02 +08:00
|
|
|
if (bio == NULL || server == NULL
|
2019-10-31 06:39:35 +08:00
|
|
|
|| (bio_err != NULL && prog == NULL)) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
|
2019-10-31 06:39:35 +08:00
|
|
|
goto end;
|
|
|
|
}
|
2020-03-25 20:46:02 +08:00
|
|
|
if (port == NULL || *port == '\0')
|
|
|
|
port = OSSL_HTTPS_PORT;
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
if (mbuf == NULL || fbio == NULL) {
|
|
|
|
BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog);
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
BIO_push(fbio, bio);
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
BIO_printf(fbio, "CONNECT %s:%s "HTTP_1_0"\r\n", server, port);
|
2019-10-31 06:39:35 +08:00
|
|
|
|
|
|
|
/*
|
|
|
|
* Workaround for broken proxies which would otherwise close
|
|
|
|
* the connection when entering tunnel mode (e.g., Squid 2.6)
|
|
|
|
*/
|
|
|
|
BIO_printf(fbio, "Proxy-Connection: Keep-Alive\r\n");
|
|
|
|
|
|
|
|
/* Support for basic (base64) proxy authentication */
|
|
|
|
if (proxyuser != NULL) {
|
|
|
|
size_t len = strlen(proxyuser) + 1;
|
|
|
|
char *proxyauth, *proxyauthenc = NULL;
|
|
|
|
|
|
|
|
if (proxypass != NULL)
|
|
|
|
len += strlen(proxypass);
|
|
|
|
proxyauth = OPENSSL_malloc(len + 1);
|
|
|
|
if (proxyauth == NULL)
|
|
|
|
goto end;
|
|
|
|
if (BIO_snprintf(proxyauth, len + 1, "%s:%s", proxyuser,
|
|
|
|
proxypass != NULL ? proxypass : "") != (int)len)
|
|
|
|
goto proxy_end;
|
|
|
|
proxyauthenc = base64encode(proxyauth, len);
|
|
|
|
if (proxyauthenc != NULL) {
|
|
|
|
BIO_printf(fbio, "Proxy-Authorization: Basic %s\r\n", proxyauthenc);
|
|
|
|
OPENSSL_clear_free(proxyauthenc, strlen(proxyauthenc));
|
|
|
|
}
|
2021-01-26 05:54:17 +08:00
|
|
|
proxy_end:
|
2019-10-31 06:39:35 +08:00
|
|
|
OPENSSL_clear_free(proxyauth, len);
|
|
|
|
if (proxyauthenc == NULL)
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Terminate the HTTP CONNECT request */
|
|
|
|
BIO_printf(fbio, "\r\n");
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
if (BIO_flush(fbio) != 0)
|
|
|
|
break;
|
|
|
|
/* potentially needs to be retried if BIO is non-blocking */
|
|
|
|
if (!BIO_should_retry(fbio))
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (;;) {
|
|
|
|
/* will not actually wait if timeout == 0 */
|
2020-02-22 04:41:56 +08:00
|
|
|
rv = BIO_wait(fbio, max_time, 100 /* milliseconds */);
|
2019-10-31 06:39:35 +08:00
|
|
|
if (rv <= 0) {
|
|
|
|
BIO_printf(bio_err, "%s: HTTP CONNECT %s\n", prog,
|
|
|
|
rv == 0 ? "timed out" : "failed waiting for data");
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
|
|
|
|
/*-
|
|
|
|
* The first line is the HTTP response.
|
|
|
|
* According to RFC 7230, it is formatted exactly like this:
|
2021-06-17 15:31:50 +08:00
|
|
|
* HTTP/d.d ddd reason text\r\n
|
2019-10-31 06:39:35 +08:00
|
|
|
*/
|
|
|
|
read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
|
|
|
|
/* the BIO may not block, so we must wait for the 1st line to come in */
|
2021-06-17 19:26:32 +08:00
|
|
|
if (read_len < (int)HTTP_LINE1_MINLEN)
|
2019-10-31 06:39:35 +08:00
|
|
|
continue;
|
|
|
|
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
/* Check for HTTP/1.x */
|
2021-06-21 14:55:50 +08:00
|
|
|
mbufp = mbuf;
|
2021-11-21 18:51:09 +08:00
|
|
|
if (!CHECK_AND_SKIP_PREFIX(mbufp, HTTP_PREFIX)) {
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR);
|
2019-10-31 06:39:35 +08:00
|
|
|
BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n",
|
|
|
|
prog);
|
|
|
|
/* Wrong protocol, not even HTTP, so stop reading headers */
|
|
|
|
goto end;
|
|
|
|
}
|
2021-06-21 14:55:50 +08:00
|
|
|
if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT)) {
|
2020-11-04 19:23:19 +08:00
|
|
|
ERR_raise(ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION);
|
2019-10-31 06:39:35 +08:00
|
|
|
BIO_printf(bio_err,
|
|
|
|
"%s: HTTP CONNECT failed, bad HTTP version %.*s\n",
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
prog, (int)HTTP_VERSION_STR_LEN, mbufp);
|
2019-10-31 06:39:35 +08:00
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
mbufp += HTTP_VERSION_STR_LEN;
|
HTTP: Implement persistent connections (keep-alive)
Both at API and at CLI level (for the CMP app only, so far)
there is a new parameter/option: keep_alive.
* 0 means HTTP connections are not kept open after
receiving a response, which is the default behavior for HTTP 1.0.
* 1 means that persistent connections are requested.
* 2 means that persistent connections are required, i.e.,
in case the server does not grant them an error occurs.
For the CMP app the default value is 1, which means preferring to keep
the connection open. For all other internal uses of the HTTP client
(fetching an OCSP response, a cert, or a CRL) it does not matter
because these operations just take one round trip.
If the client application requested or required a persistent connection
and this was granted by the server, it can keep the OSSL_HTTP_REQ_CTX *
as long as it wants to send further requests and OSSL_HTTP_is_alive()
returns nonzero,
else it should call OSSL_HTTP_REQ_CTX_free() or OSSL_HTTP_close().
In case the client application keeps the OSSL_HTTP_REQ_CTX *
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.
This requires extending the HTTP header parsing and
rearranging the high-level HTTP client API. In particular:
* Split the monolithic OSSL_HTTP_transfer() into OSSL_HTTP_open(),
OSSL_HTTP_set_request(), a lean OSSL_HTTP_transfer(), and OSSL_HTTP_close().
* Split the timeout functionality accordingly and improve default behavior.
* Extract part of OSSL_HTTP_REQ_CTX_new() to OSSL_HTTP_REQ_CTX_set_expected().
* Extend struct ossl_http_req_ctx_st accordingly.
Use the new feature for the CMP client, which requires extending
related transaction management of CMP client and test server.
Update the documentation and extend the tests accordingly.
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/15053)
2021-04-28 06:26:14 +08:00
|
|
|
|
|
|
|
/* RFC 7231 4.3.6: any 2xx status code is valid */
|
2021-06-17 18:55:14 +08:00
|
|
|
if (!HAS_PREFIX(mbufp, " 2")) {
|
2021-11-21 18:51:09 +08:00
|
|
|
if (ossl_isspace(*mbufp))
|
|
|
|
mbufp++;
|
2019-10-31 06:39:35 +08:00
|
|
|
/* chop any trailing whitespace */
|
|
|
|
while (read_len > 0 && ossl_isspace(mbuf[read_len - 1]))
|
|
|
|
read_len--;
|
|
|
|
mbuf[read_len] = '\0';
|
2020-11-04 23:14:00 +08:00
|
|
|
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_CONNECT_FAILURE,
|
2021-06-17 15:31:50 +08:00
|
|
|
"reason=%s", mbufp);
|
|
|
|
BIO_printf(bio_err, "%s: HTTP CONNECT failed, reason=%s\n",
|
2019-10-31 06:39:35 +08:00
|
|
|
prog, mbufp);
|
|
|
|
goto end;
|
|
|
|
}
|
|
|
|
ret = 1;
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* Read past all following headers */
|
|
|
|
do {
|
|
|
|
/*
|
2021-05-31 12:29:55 +08:00
|
|
|
* This does not necessarily catch the case when the full
|
2019-10-31 06:39:35 +08:00
|
|
|
* HTTP response came in in more than a single TCP message.
|
|
|
|
*/
|
|
|
|
read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
|
|
|
|
} while (read_len > 2);
|
|
|
|
|
|
|
|
end:
|
|
|
|
if (fbio != NULL) {
|
|
|
|
(void)BIO_flush(fbio);
|
|
|
|
BIO_pop(fbio);
|
|
|
|
BIO_free(fbio);
|
|
|
|
}
|
|
|
|
OPENSSL_free(mbuf);
|
|
|
|
return ret;
|
2020-03-25 20:46:02 +08:00
|
|
|
#undef BUF_SIZE
|
2019-10-31 06:39:35 +08:00
|
|
|
}
|