A local copy of OpenSSL from GitHub
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

533 lines
16 KiB

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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
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)
1 year ago
  1. /*
  2. * Copyright 1995-2020 The OpenSSL Project Authors. All Rights Reserved.
  3. *
  4. * Licensed under the Apache License 2.0 (the "License"). You may not use
  5. * this file except in compliance with the License. You can obtain a copy
  6. * in the file LICENSE in the source distribution or at
  7. * https://www.openssl.org/source/license.html
  8. */
  9. /* Very basic HTTP server */
  10. #if !defined(_POSIX_C_SOURCE) && defined(OPENSSL_SYS_VMS)
  11. /*
  12. * On VMS, you need to define this to get the declaration of fileno(). The
  13. * value 2 is to make sure no function defined in POSIX-2 is left undefined.
  14. */
  15. # define _POSIX_C_SOURCE 2
  16. #endif
  17. #include <string.h>
  18. #include <ctype.h>
  19. #include "http_server.h"
  20. #include "internal/sockets.h"
  21. #include <openssl/err.h>
  22. #include <openssl/rand.h>
  23. #include "s_apps.h"
  24. #if defined(__TANDEM)
  25. # if defined(OPENSSL_TANDEM_FLOSS)
  26. # include <floss.h(floss_fork)>
  27. # endif
  28. #endif
  29. static int verbosity = LOG_INFO;
  30. #define HTTP_PREFIX "HTTP/"
  31. #define HTTP_VERSION_PATT "1." /* allow 1.x */
  32. #define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
  33. #define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */
  34. #ifdef HTTP_DAEMON
  35. int multi = 0; /* run multiple responder processes */
  36. int acfd = (int) INVALID_SOCKET;
  37. static int print_syslog(const char *str, size_t len, void *levPtr)
  38. {
  39. int level = *(int *)levPtr;
  40. int ilen = len > MAXERRLEN ? MAXERRLEN : len;
  41. syslog(level, "%.*s", ilen, str);
  42. return ilen;
  43. }
  44. #endif
  45. void log_message(const char *prog, int level, const char *fmt, ...)
  46. {
  47. va_list ap;
  48. if (verbosity < level)
  49. return;
  50. va_start(ap, fmt);
  51. #ifdef HTTP_DAEMON
  52. if (multi) {
  53. char buf[1024];
  54. if (vsnprintf(buf, sizeof(buf), fmt, ap) > 0)
  55. syslog(level, "%s", buf);
  56. if (level <= LOG_ERR)
  57. ERR_print_errors_cb(print_syslog, &level);
  58. } else
  59. #endif
  60. {
  61. BIO_printf(bio_err, "%s: ", prog);
  62. BIO_vprintf(bio_err, fmt, ap);
  63. BIO_printf(bio_err, "\n");
  64. (void)BIO_flush(bio_err);
  65. }
  66. va_end(ap);
  67. }
  68. #ifdef HTTP_DAEMON
  69. void socket_timeout(int signum)
  70. {
  71. if (acfd != (int)INVALID_SOCKET)
  72. (void)shutdown(acfd, SHUT_RD);
  73. }
  74. static void killall(int ret, pid_t *kidpids)
  75. {
  76. int i;
  77. for (i = 0; i < multi; ++i)
  78. if (kidpids[i] != 0)
  79. (void)kill(kidpids[i], SIGTERM);
  80. OPENSSL_free(kidpids);
  81. ossl_sleep(1000);
  82. exit(ret);
  83. }
  84. static int termsig = 0;
  85. static void noteterm(int sig)
  86. {
  87. termsig = sig;
  88. }
  89. /*
  90. * Loop spawning up to `multi` child processes, only child processes return
  91. * from this function. The parent process loops until receiving a termination
  92. * signal, kills extant children and exits without returning.
  93. */
  94. void spawn_loop(const char *prog)
  95. {
  96. pid_t *kidpids = NULL;
  97. int status;
  98. int procs = 0;
  99. int i;
  100. openlog(prog, LOG_PID, LOG_DAEMON);
  101. if (setpgid(0, 0)) {
  102. syslog(LOG_ERR, "fatal: error detaching from parent process group: %s",
  103. strerror(errno));
  104. exit(1);
  105. }
  106. kidpids = app_malloc(multi * sizeof(*kidpids), "child PID array");
  107. for (i = 0; i < multi; ++i)
  108. kidpids[i] = 0;
  109. signal(SIGINT, noteterm);
  110. signal(SIGTERM, noteterm);
  111. while (termsig == 0) {
  112. pid_t fpid;
  113. /*
  114. * Wait for a child to replace when we're at the limit.
  115. * Slow down if a child exited abnormally or waitpid() < 0
  116. */
  117. while (termsig == 0 && procs >= multi) {
  118. if ((fpid = waitpid(-1, &status, 0)) > 0) {
  119. for (i = 0; i < procs; ++i) {
  120. if (kidpids[i] == fpid) {
  121. kidpids[i] = 0;
  122. --procs;
  123. break;
  124. }
  125. }
  126. if (i >= multi) {
  127. syslog(LOG_ERR, "fatal: internal error: "
  128. "no matching child slot for pid: %ld",
  129. (long) fpid);
  130. killall(1, kidpids);
  131. }
  132. if (status != 0) {
  133. if (WIFEXITED(status))
  134. syslog(LOG_WARNING, "child process: %ld, exit status: %d",
  135. (long)fpid, WEXITSTATUS(status));
  136. else if (WIFSIGNALED(status))
  137. syslog(LOG_WARNING, "child process: %ld, term signal %d%s",
  138. (long)fpid, WTERMSIG(status),
  139. # ifdef WCOREDUMP
  140. WCOREDUMP(status) ? " (core dumped)" :
  141. # endif
  142. "");
  143. ossl_sleep(1000);
  144. }
  145. break;
  146. } else if (errno != EINTR) {
  147. syslog(LOG_ERR, "fatal: waitpid(): %s", strerror(errno));
  148. killall(1, kidpids);
  149. }
  150. }
  151. if (termsig)
  152. break;
  153. switch (fpid = fork()) {
  154. case -1: /* error */
  155. /* System critically low on memory, pause and try again later */
  156. ossl_sleep(30000);
  157. break;
  158. case 0: /* child */
  159. OPENSSL_free(kidpids);
  160. signal(SIGINT, SIG_DFL);
  161. signal(SIGTERM, SIG_DFL);
  162. if (termsig)
  163. _exit(0);
  164. if (RAND_poll() <= 0) {
  165. syslog(LOG_ERR, "fatal: RAND_poll() failed");
  166. _exit(1);
  167. }
  168. return;
  169. default: /* parent */
  170. for (i = 0; i < multi; ++i) {
  171. if (kidpids[i] == 0) {
  172. kidpids[i] = fpid;
  173. procs++;
  174. break;
  175. }
  176. }
  177. if (i >= multi) {
  178. syslog(LOG_ERR, "fatal: internal error: no free child slots");
  179. killall(1, kidpids);
  180. }
  181. break;
  182. }
  183. }
  184. /* The loop above can only break on termsig */
  185. syslog(LOG_INFO, "terminating on signal: %d", termsig);
  186. killall(0, kidpids);
  187. }
  188. #endif
  189. #ifndef OPENSSL_NO_SOCK
  190. BIO *http_server_init_bio(const char *prog, const char *port)
  191. {
  192. BIO *acbio = NULL, *bufbio;
  193. int asock;
  194. bufbio = BIO_new(BIO_f_buffer());
  195. if (bufbio == NULL)
  196. goto err;
  197. acbio = BIO_new(BIO_s_accept());
  198. if (acbio == NULL
  199. || BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0
  200. || BIO_set_accept_port(acbio, port) < 0) {
  201. log_message(prog, LOG_ERR, "Error setting up accept BIO");
  202. goto err;
  203. }
  204. BIO_set_accept_bios(acbio, bufbio);
  205. bufbio = NULL;
  206. if (BIO_do_accept(acbio) <= 0) {
  207. log_message(prog, LOG_ERR, "Error starting accept");
  208. goto err;
  209. }
  210. /* Report back what address and port are used */
  211. BIO_get_fd(acbio, &asock);
  212. if (!report_server_accept(bio_out, asock, 1)) {
  213. log_message(prog, LOG_ERR, "Error printing ACCEPT string");
  214. goto err;
  215. }
  216. return acbio;
  217. err:
  218. BIO_free_all(acbio);
  219. BIO_free(bufbio);
  220. return NULL;
  221. }
  222. /*
  223. * Decode %xx URL-decoding in-place. Ignores malformed sequences.
  224. */
  225. static int urldecode(char *p)
  226. {
  227. unsigned char *out = (unsigned char *)p;
  228. unsigned char *save = out;
  229. for (; *p; p++) {
  230. if (*p != '%') {
  231. *out++ = *p;
  232. } else if (isxdigit(_UC(p[1])) && isxdigit(_UC(p[2]))) {
  233. /* Don't check, can't fail because of ixdigit() call. */
  234. *out++ = (OPENSSL_hexchar2int(p[1]) << 4)
  235. | OPENSSL_hexchar2int(p[2]);
  236. p += 2;
  237. } else {
  238. return -1;
  239. }
  240. }
  241. *out = '\0';
  242. return (int)(out - save);
  243. }
  244. /* if *pcbio != NULL, continue given connected session, else accept new */
  245. /* if found_keep_alive != NULL, return this way connection persistence state */
  246. int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
  247. char **ppath, BIO **pcbio, BIO *acbio,
  248. int *found_keep_alive,
  249. const char *prog, const char *port,
  250. int accept_get, int timeout)
  251. {
  252. BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL;
  253. int len;
  254. char reqbuf[2048], inbuf[2048];
  255. char *meth, *url, *end;
  256. ASN1_VALUE *req;
  257. int ret = 0;
  258. *preq = NULL;
  259. if (ppath != NULL)
  260. *ppath = NULL;
  261. if (cbio == NULL) {
  262. log_message(prog, LOG_DEBUG,
  263. "Awaiting new connection on port %s...", port);
  264. if (BIO_do_accept(acbio) <= 0)
  265. /* Connection loss before accept() is routine, ignore silently */
  266. return ret;
  267. *pcbio = cbio = BIO_pop(acbio);
  268. } else {
  269. log_message(prog, LOG_DEBUG, "Awaiting next request...");
  270. }
  271. if (cbio == NULL) {
  272. /* Cannot call http_server_send_status(cbio, ...) */
  273. ret = -1;
  274. goto out;
  275. }
  276. # ifdef HTTP_DAEMON
  277. if (timeout > 0) {
  278. (void)BIO_get_fd(cbio, &acfd);
  279. alarm(timeout);
  280. }
  281. # endif
  282. /* Read the request line. */
  283. len = BIO_gets(cbio, reqbuf, sizeof(reqbuf));
  284. if (len == 0)
  285. return ret;
  286. ret = 1;
  287. if (len < 0) {
  288. log_message(prog, LOG_WARNING, "Request line read error");
  289. (void)http_server_send_status(cbio, 400, "Bad Request");
  290. goto out;
  291. }
  292. if ((end = strchr(reqbuf, '\r')) != NULL
  293. || (end = strchr(reqbuf, '\n')) != NULL)
  294. *end = '\0';
  295. log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf);
  296. meth = reqbuf;
  297. url = meth + 3;
  298. if ((accept_get && strncmp(meth, "GET ", 4) == 0)
  299. || (url++, strncmp(meth, "POST ", 5) == 0)) {
  300. static const char http_version_str[] = " "HTTP_PREFIX_VERSION;
  301. static const size_t http_version_str_len = sizeof(http_version_str) - 1;
  302. /* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
  303. *(url++) = '\0';
  304. while (*url == ' ')
  305. url++;
  306. if (*url != '/') {
  307. log_message(prog, LOG_WARNING,
  308. "Invalid %s -- URL does not begin with '/': %s",
  309. meth, url);
  310. (void)http_server_send_status(cbio, 400, "Bad Request");
  311. goto out;
  312. }
  313. url++;
  314. /* Splice off the HTTP version identifier. */
  315. for (end = url; *end != '\0'; end++)
  316. if (*end == ' ')
  317. break;
  318. if (strncmp(end, http_version_str, http_version_str_len) != 0) {
  319. log_message(prog, LOG_WARNING,
  320. "Invalid %s -- bad HTTP/version string: %s",
  321. meth, end + 1);
  322. (void)http_server_send_status(cbio, 400, "Bad Request");
  323. goto out;
  324. }
  325. *end = '\0';
  326. /* above HTTP 1.0, connection persistence is the default */
  327. if (found_keep_alive != NULL)
  328. *found_keep_alive = end[http_version_str_len] > '0';
  329. /*-
  330. * Skip "GET / HTTP..." requests often used by load-balancers.
  331. * 'url' was incremented above to point to the first byte *after*
  332. * the leading slash, so in case 'GET / ' it is now an empty string.
  333. */
  334. if (strlen(meth) == 3 && url[0] == '\0') {
  335. (void)http_server_send_status(cbio, 200, "OK");
  336. goto out;
  337. }
  338. len = urldecode(url);
  339. if (len < 0) {
  340. log_message(prog, LOG_WARNING,
  341. "Invalid %s request -- bad URL encoding: %s",
  342. meth, url);
  343. (void)http_server_send_status(cbio, 400, "Bad Request");
  344. goto out;
  345. }
  346. if (strlen(meth) == 3) { /* GET */
  347. if ((getbio = BIO_new_mem_buf(url, len)) == NULL
  348. || (b64 = BIO_new(BIO_f_base64())) == NULL) {
  349. log_message(prog, LOG_ERR,
  350. "Could not allocate base64 bio with size = %d",
  351. len);
  352. goto fatal;
  353. }
  354. BIO_set_flags(b64, BIO_FLAGS_BASE64_NO_NL);
  355. getbio = BIO_push(b64, getbio);
  356. }
  357. } else {
  358. log_message(prog, LOG_WARNING,
  359. "HTTP request does not begin with %sPOST: %s",
  360. accept_get ? "GET or " : "", reqbuf);
  361. /* TODO provide better diagnosis in case client tries TLS */
  362. (void)http_server_send_status(cbio, 400, "Bad Request");
  363. goto out;
  364. }
  365. /* chop any further/duplicate leading or trailing '/' */
  366. while (*url == '/')
  367. url++;
  368. while (end >= url + 2 && end[-2] == '/' && end[-1] == '/')
  369. end--;
  370. *end = '\0';
  371. /* Read and skip past the headers. */
  372. for (;;) {
  373. char *key, *value, *line_end = NULL;
  374. len = BIO_gets(cbio, inbuf, sizeof(inbuf));
  375. if (len <= 0) {
  376. log_message(prog, LOG_WARNING, "Error reading HTTP header");
  377. (void)http_server_send_status(cbio, 400, "Bad Request");
  378. goto out;
  379. }
  380. if (inbuf[0] == '\r' || inbuf[0] == '\n')
  381. break;
  382. key = inbuf;
  383. value = strchr(key, ':');
  384. if (value == NULL) {
  385. log_message(prog, LOG_WARNING,
  386. "Error parsing HTTP header: missing ':'");
  387. (void)http_server_send_status(cbio, 400, "Bad Request");
  388. goto out;
  389. }
  390. *(value++) = '\0';
  391. while (*value == ' ')
  392. value++;
  393. line_end = strchr(value, '\r');
  394. if (line_end == NULL) {
  395. line_end = strchr(value, '\n');
  396. if (line_end == NULL) {
  397. log_message(prog, LOG_WARNING,
  398. "Error parsing HTTP header: missing end of line");
  399. (void)http_server_send_status(cbio, 400, "Bad Request");
  400. goto out;
  401. }
  402. }
  403. *line_end = '\0';
  404. /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
  405. if (found_keep_alive != NULL && strcasecmp(key, "Connection") == 0) {
  406. if (strcasecmp(value, "keep-alive") == 0)
  407. *found_keep_alive = 1;
  408. else if (strcasecmp(value, "close") == 0)
  409. *found_keep_alive = 0;
  410. }
  411. }
  412. # ifdef HTTP_DAEMON
  413. /* Clear alarm before we close the client socket */
  414. alarm(0);
  415. timeout = 0;
  416. # endif
  417. /* Try to read and parse request */
  418. req = ASN1_item_d2i_bio(it, getbio != NULL ? getbio : cbio, NULL);
  419. if (req == NULL) {
  420. log_message(prog, LOG_WARNING,
  421. "Error parsing DER-encoded request content");
  422. (void)http_server_send_status(cbio, 400, "Bad Request");
  423. } else if (ppath != NULL && (*ppath = OPENSSL_strdup(url)) == NULL) {
  424. log_message(prog, LOG_ERR,
  425. "Out of memory allocating %zu bytes", strlen(url) + 1);
  426. ASN1_item_free(req, it);
  427. goto fatal;
  428. }
  429. *preq = req;
  430. out:
  431. BIO_free_all(getbio);
  432. # ifdef HTTP_DAEMON
  433. if (timeout > 0)
  434. alarm(0);
  435. acfd = (int)INVALID_SOCKET;
  436. # endif
  437. return ret;
  438. fatal:
  439. (void)http_server_send_status(cbio, 500, "Internal Server Error");
  440. if (ppath != NULL) {
  441. OPENSSL_free(*ppath);
  442. *ppath = NULL;
  443. }
  444. BIO_free_all(cbio);
  445. *pcbio = NULL;
  446. ret = -1;
  447. goto out;
  448. }
  449. /* assumes that cbio does not do an encoding that changes the output length */
  450. int http_server_send_asn1_resp(BIO *cbio, int keep_alive,
  451. const char *content_type,
  452. const ASN1_ITEM *it, const ASN1_VALUE *resp)
  453. {
  454. int ret = BIO_printf(cbio, HTTP_1_0" 200 OK\r\n%s"
  455. "Content-type: %s\r\n"
  456. "Content-Length: %d\r\n\r\n",
  457. keep_alive ? "Connection: keep-alive\r\n" : "",
  458. content_type,
  459. ASN1_item_i2d(resp, NULL, it)) > 0
  460. && ASN1_item_i2d_bio(it, cbio, resp) > 0;
  461. (void)BIO_flush(cbio);
  462. return ret;
  463. }
  464. int http_server_send_status(BIO *cbio, int status, const char *reason)
  465. {
  466. int ret = BIO_printf(cbio, HTTP_1_0" %d %s\r\n\r\n",
  467. /* This implicitly cancels keep-alive */
  468. status, reason) > 0;
  469. (void)BIO_flush(cbio);
  470. return ret;
  471. }
  472. #endif