mirror of
https://github.com/openssl/openssl.git
synced 2025-02-17 14:32:04 +08:00
http_client.c: Dump response on error when tracing is enabled
Reviewed-by: Tomas Mraz <tomas@openssl.org> Reviewed-by: Dmitry Belyavskiy <beldmit@gmail.com> Reviewed-by: David von Oheimb <david.von.oheimb@siemens.com> (Merged from https://github.com/openssl/openssl/pull/18386)
This commit is contained in:
parent
3c58d44749
commit
e8fdb06035
@ -20,6 +20,7 @@
|
||||
#include <openssl/cmperr.h>
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/http.h>
|
||||
#include <openssl/trace.h>
|
||||
#include "internal/sockets.h"
|
||||
#include "internal/common.h" /* for ossl_assert() */
|
||||
|
||||
@ -485,6 +486,7 @@ static int may_still_retry(time_t max_time, int *ptimeout)
|
||||
int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
{
|
||||
int i, found_expected_ct = 0, found_keep_alive = 0;
|
||||
int found_text_ct = 0;
|
||||
long n;
|
||||
size_t resp_len;
|
||||
const unsigned char *p;
|
||||
@ -540,6 +542,8 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
case OHS_WRITE_INIT:
|
||||
rctx->len_to_send = BIO_get_mem_data(rctx->mem, &rctx->pos);
|
||||
rctx->state = OHS_WRITE_HDR;
|
||||
if (OSSL_TRACE_ENABLED(HTTP))
|
||||
OSSL_TRACE(HTTP, "Sending request header:\n");
|
||||
|
||||
/* fall thru */
|
||||
case OHS_WRITE_HDR:
|
||||
@ -548,6 +552,10 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
/* Copy some chunk of data from rctx->req to rctx->wbio */
|
||||
|
||||
if (rctx->len_to_send > 0) {
|
||||
if (OSSL_TRACE_ENABLED(HTTP)
|
||||
&& rctx->state == OHS_WRITE_HDR && rctx->len_to_send <= INT_MAX)
|
||||
OSSL_TRACE2(HTTP, "%.*s", (int)rctx->len_to_send, rctx->pos);
|
||||
|
||||
i = BIO_write(rctx->wbio, rctx->pos, rctx->len_to_send);
|
||||
if (i <= 0) {
|
||||
if (BIO_should_retry(rctx->wbio))
|
||||
@ -631,6 +639,13 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* dump all response header lines */
|
||||
if (OSSL_TRACE_ENABLED(HTTP)) {
|
||||
if (rctx->state == OHS_FIRSTLINE)
|
||||
OSSL_TRACE(HTTP, "Received response header:\n");
|
||||
OSSL_TRACE1(HTTP, "%s", buf);
|
||||
}
|
||||
|
||||
/* First line */
|
||||
if (rctx->state == OHS_FIRSTLINE) {
|
||||
switch (parse_http_line1(buf, &found_keep_alive)) {
|
||||
@ -669,15 +684,20 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
rctx->redirection_url = value;
|
||||
return 0;
|
||||
}
|
||||
if (rctx->state == OHS_HEADERS && rctx->expected_ct != NULL
|
||||
&& OPENSSL_strcasecmp(key, "Content-Type") == 0) {
|
||||
if (OPENSSL_strcasecmp(rctx->expected_ct, value) != 0) {
|
||||
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_UNEXPECTED_CONTENT_TYPE,
|
||||
"expected=%s, actual=%s",
|
||||
rctx->expected_ct, value);
|
||||
return 0;
|
||||
if (OPENSSL_strcasecmp(key, "Content-Type") == 0) {
|
||||
if (rctx->state == OHS_HEADERS
|
||||
&& rctx->expected_ct != NULL) {
|
||||
if (OPENSSL_strcasecmp(rctx->expected_ct, value) != 0) {
|
||||
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;
|
||||
}
|
||||
found_expected_ct = 1;
|
||||
if (OPENSSL_strncasecmp(value, "text/", 5) == 0)
|
||||
found_text_ct = 1;
|
||||
}
|
||||
|
||||
/* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
|
||||
@ -717,8 +737,12 @@ int OSSL_HTTP_REQ_CTX_nbio(OSSL_HTTP_REQ_CTX *rctx)
|
||||
rctx->keep_alive = 0;
|
||||
}
|
||||
|
||||
if (rctx->state == OHS_ERROR)
|
||||
if (rctx->state == OHS_ERROR) {
|
||||
if (OSSL_TRACE_ENABLED(HTTP)
|
||||
&& found_text_ct && BIO_get_mem_data(rctx->mem, &p) > 0)
|
||||
OSSL_TRACE1(HTTP, "%s", p);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (rctx->expected_ct != NULL && !found_expected_ct) {
|
||||
ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MISSING_CONTENT_TYPE,
|
||||
|
@ -138,8 +138,9 @@ static const struct trace_category_st trace_categories[] = {
|
||||
TRACE_CATEGORY_(STORE),
|
||||
TRACE_CATEGORY_(DECODER),
|
||||
TRACE_CATEGORY_(ENCODER),
|
||||
TRACE_CATEGORY_(REF_COUNT)
|
||||
};
|
||||
TRACE_CATEGORY_(REF_COUNT),
|
||||
TRACE_CATEGORY_(HTTP),
|
||||
}; /* KEEP THIS LIST IN SYNC with #define OSSL_TRACE_CATEGORY_... in trace.h */
|
||||
|
||||
const char *OSSL_trace_get_category_name(int num)
|
||||
{
|
||||
|
@ -1060,6 +1060,10 @@ although they usually contain hints that would be helpful for diagnostics.
|
||||
For assisting in such cases the CMP client offers a workaround via the
|
||||
B<-unprotected_errors> option, which allows accepting such negative messages.
|
||||
|
||||
If OpenSSL was built with trace support enabled
|
||||
and the environment variable B<OPENSSL_TRACE> includes B<HTTP>,
|
||||
the request and response headers of HTTP transfers are printed.
|
||||
|
||||
=head1 EXAMPLES
|
||||
|
||||
=head2 Simple examples using the default OpenSSL configuration file
|
||||
|
@ -710,8 +710,8 @@ see L<openssl-env(7)>.
|
||||
|
||||
Enable tracing output of OpenSSL library, by name.
|
||||
This output will only make sense if you know OpenSSL internals well.
|
||||
Also, it might not give you any output at all, depending on how
|
||||
OpenSSL was built.
|
||||
Also, it might not give you any output at all
|
||||
if OpenSSL was built without tracing support.
|
||||
|
||||
The value is a comma separated list of names, with the following
|
||||
available:
|
||||
@ -766,6 +766,10 @@ policy evaluation.
|
||||
|
||||
BIGNUM context.
|
||||
|
||||
=item B<HTTP>
|
||||
|
||||
HTTP client diagnostics
|
||||
|
||||
=back
|
||||
|
||||
=back
|
||||
|
@ -213,6 +213,13 @@ This may be omitted if the GET method is used and "keep-alive" is not requested.
|
||||
When the request context is fully prepared, the HTTP exchange may be performed
|
||||
with OSSL_HTTP_REQ_CTX_nbio() or OSSL_HTTP_REQ_CTX_exchange().
|
||||
|
||||
=head1 NOTES
|
||||
|
||||
When built with tracing enabled, OSSL_HTTP_REQ_CTX_nbio() and all functions
|
||||
using it, such as OSSL_HTTP_REQ_CTX_exchange() and L<OSSL_HTTP_transfer(3)>,
|
||||
may be traced using B<OSSL_TRACE_CATEGORY_HTTP>.
|
||||
See also L<OSSL_trace_enabled(3)> and L<openssl(1)/ENVIRONMENT>.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_HTTP_REQ_CTX_new() returns a pointer to a B<OSSL_HTTP_REQ_CTX>, or NULL
|
||||
@ -248,7 +255,8 @@ L<ASN1_item_i2d_mem_bio(3)>,
|
||||
L<OSSL_HTTP_open(3)>,
|
||||
L<OSSL_HTTP_get(3)>,
|
||||
L<OSSL_HTTP_transfer(3)>,
|
||||
L<OSSL_HTTP_close(3)>
|
||||
L<OSSL_HTTP_close(3)>,
|
||||
L<OSSL_trace_enabled(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
|
@ -245,6 +245,10 @@ C<http_proxy>, C<HTTP_PROXY>, C<https_proxy>, C<HTTPS_PROXY>, C<no_proxy>, and
|
||||
C<NO_PROXY>, have been chosen for maximal compatibility with
|
||||
other HTTP client implementations such as wget, curl, and git.
|
||||
|
||||
When built with tracing enabled, OSSL_HTTP_transfer() and all functions using it
|
||||
may be traced using B<OSSL_TRACE_CATEGORY_HTTP>.
|
||||
See also L<OSSL_trace_enabled(3)> and L<openssl(1)/ENVIRONMENT>.
|
||||
|
||||
=head1 RETURN VALUES
|
||||
|
||||
OSSL_HTTP_open() returns on success a B<OSSL_HTTP_REQ_CTX>, else NULL.
|
||||
@ -266,7 +270,8 @@ OSSL_HTTP_close() returns 0 if anything went wrong while disconnecting, else 1.
|
||||
|
||||
L<OSSL_HTTP_parse_url(3)>, L<BIO_new_connect(3)>,
|
||||
L<ASN1_item_i2d_mem_bio(3)>, L<ASN1_item_d2i_bio(3)>,
|
||||
L<OSSL_HTTP_is_alive(3)>
|
||||
L<OSSL_HTTP_is_alive(3)>,
|
||||
L<OSSL_trace_enabled(3)>
|
||||
|
||||
=head1 HISTORY
|
||||
|
||||
|
@ -57,8 +57,10 @@ extern "C" {
|
||||
# define OSSL_TRACE_CATEGORY_DECODER 15
|
||||
# define OSSL_TRACE_CATEGORY_ENCODER 16
|
||||
# define OSSL_TRACE_CATEGORY_REF_COUNT 17
|
||||
# define OSSL_TRACE_CATEGORY_HTTP 18
|
||||
/* Count of available categories. */
|
||||
# define OSSL_TRACE_CATEGORY_NUM 18
|
||||
# define OSSL_TRACE_CATEGORY_NUM 19
|
||||
/* KEEP THIS LIST IN SYNC with trace_categories[] in crypto/trace.c */
|
||||
|
||||
/* Returns the trace category number for the given |name| */
|
||||
int OSSL_trace_get_category_num(const char *name);
|
||||
|
Loading…
Reference in New Issue
Block a user