/*
 * Copyright 2001-2021 The OpenSSL Project Authors. All Rights Reserved.
 * 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
 */

#include "e_os.h"
#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>
#include "internal/sockets.h"
#include "internal/cryptlib.h" /* for ossl_assert() */

#define HAS_PREFIX(str, prefix) (strncmp(str, prefix, sizeof(prefix) - 1) == 0)
#define HTTP_PREFIX "HTTP/"
#define HTTP_VERSION_PATT "1." /* allow 1.x */
#define HTTP_VERSION_STR_LEN sizeof(HTTP_VERSION_PATT) /* == strlen("1.0") */
#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */
#define HTTP_LINE1_MINLEN (sizeof(HTTP_PREFIX_VERSION "x 200\n") - 1)
#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 */
    unsigned char *buf;         /* Buffer to write request or read response */
    int buf_size;               /* Buffer size */
    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 */
    char *server;               /* Optional server host name */
    char *port;                 /* Optional server port */
    BIO *mem;                   /* Memory BIO holding request/response header */
    BIO *req;                   /* BIO holding the request provided by caller */
    int method_POST;            /* HTTP method is POST (else GET) */
    char *expected_ct;          /* Optional expected Content-Type */
    int expect_asn1;            /* Response must be ASN.1-encoded */
    unsigned char *pos;         /* Current position sending data */
    long len_to_send;           /* Number of bytes still to send */
    size_t resp_len;            /* Length of response */
    size_t max_resp_len;        /* Maximum length of response, or 0 */
    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 */
    char *redirection_url;      /* Location obtained from HTTP status 301/302 */
};

/* HTTP states */

#define OHS_NOREAD         0x1000 /* If set no reading should be performed */
#define OHS_ERROR          (0 | OHS_NOREAD) /* Error condition */
#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 */
#define OHS_WRITE_HDR      (3 | OHS_NOREAD) /* Request header being sent */
#define OHS_WRITE_REQ      (4 | OHS_NOREAD) /* Request contents being sent */
#define OHS_FLUSH          (5 | OHS_NOREAD) /* Request being flushed */
#define OHS_FIRSTLINE       1 /* First line of response being read */
#define OHS_HEADERS         2 /* MIME headers of response being read */
#define OHS_REDIRECT        3 /* MIME headers being read, expecting Location */
#define OHS_ASN1_HEADER     4 /* ASN1 sequence header (tag+length) being read */
#define OHS_ASN1_CONTENT    5 /* ASN1 content octets being read */
#define OHS_ASN1_DONE      (6 | OHS_NOREAD) /* ASN1 content read completed */
#define OHS_STREAM         (7 | OHS_NOREAD) /* HTTP content stream to be read */

/* Low-level HTTP API implementation */

OSSL_HTTP_REQ_CTX *OSSL_HTTP_REQ_CTX_new(BIO *wbio, BIO *rbio, int buf_size)
{
    OSSL_HTTP_REQ_CTX *rctx;

    if (wbio == NULL || rbio == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }

    if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL)
        return NULL;
    rctx->state = OHS_ERROR;
    rctx->buf_size = buf_size > 0 ? buf_size : OSSL_HTTP_DEFAULT_MAX_LINE_LEN;
    rctx->buf = OPENSSL_malloc(rctx->buf_size);
    rctx->wbio = wbio;
    rctx->rbio = rbio;
    if (rctx->buf == NULL) {
        OPENSSL_free(rctx);
        return NULL;
    }
    rctx->max_resp_len = OSSL_HTTP_DEFAULT_MAX_RESP_LEN;
    /* everything else is 0, e.g. rctx->len_to_send, or NULL, e.g. rctx->mem  */
    return rctx;
}

void OSSL_HTTP_REQ_CTX_free(OSSL_HTTP_REQ_CTX *rctx)
{
    if (rctx == NULL)
        return;
    /*
     * 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 */
    BIO_free(rctx->mem);
    BIO_free(rctx->req);
    OPENSSL_free(rctx->buf);
    OPENSSL_free(rctx->proxy);
    OPENSSL_free(rctx->server);
    OPENSSL_free(rctx->port);
    OPENSSL_free(rctx->expected_ct);
    OPENSSL_free(rctx);
}

BIO *OSSL_HTTP_REQ_CTX_get0_mem_bio(const OSSL_HTTP_REQ_CTX *rctx)
{
    if (rctx == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }
    return rctx->mem;
}

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;
}

void OSSL_HTTP_REQ_CTX_set_max_response_length(OSSL_HTTP_REQ_CTX *rctx,
                                               unsigned long len)
{
    if (rctx == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return;
    }
    rctx->max_resp_len = len != 0 ? (size_t)len : OSSL_HTTP_DEFAULT_MAX_RESP_LEN;
}

/*
 * Create request line using |rctx| and |path| (or "/" in case |path| is NULL).
 * Server name (and port) must be given if and only if plain HTTP proxy is used.
 */
int OSSL_HTTP_REQ_CTX_set_request_line(OSSL_HTTP_REQ_CTX *rctx, int method_POST,
                                       const char *server, const char *port,
                                       const char *path)
{
    if (rctx == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    BIO_free(rctx->mem);
    if ((rctx->mem = BIO_new(BIO_s_mem())) == NULL)
        return 0;

    rctx->method_POST = method_POST != 0;
    if (BIO_printf(rctx->mem, "%s ", rctx->method_POST ? "POST" : "GET") <= 0)
        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
         */
        if (BIO_printf(rctx->mem, OSSL_HTTP_PREFIX"%s", server) <= 0)
            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;
    /*
     * Add (the rest of) the path and the HTTP version,
     * which is fixed to 1.0 for straightforward implementation of keep-alive
     */
    if (BIO_printf(rctx->mem, "%s "HTTP_1_0"\r\n", path) <= 0)
        return 0;

    rctx->resp_len = 0;
    rctx->state = OHS_ADD_HEADERS;
    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) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    if (rctx->mem == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }

    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;
    }
    return BIO_write(rctx->mem, "\r\n", 2) == 2;
}

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
            && rctx->state != OHS_ERROR && rctx->state != OHS_ADD_HEADERS) {
        /* 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;
    else /* take over any |overall_timeout| arg of OSSL_HTTP_open(), else 0 */
        rctx->max_time = rctx->max_total_time;
    rctx->keep_alive = keep_alive;
    return 1;
}

static int set1_content(OSSL_HTTP_REQ_CTX *rctx,
                        const char *content_type, BIO *req)
{
    long req_len;

    if (rctx == NULL || (req == NULL && content_type != NULL)) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }

    if (rctx->keep_alive != 0
            && !OSSL_HTTP_REQ_CTX_add1_header(rctx, "Connection", "keep-alive"))
        return 0;

    BIO_free(rctx->req);
    rctx->req = NULL;
    if (req == NULL)
        return 1;
    if (!rctx->method_POST) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }

    if (content_type != NULL
            && BIO_printf(rctx->mem, "Content-Type: %s\r\n", content_type) <= 0)
        return 0;

    /* streaming BIO may not support querying size */
    if (((req_len = BIO_ctrl(req, BIO_CTRL_INFO, 0, NULL)) <= 0
         || BIO_printf(rctx->mem, "Content-Length: %ld\r\n", req_len) > 0)
        && BIO_up_ref(req)) {
        rctx->req = req;
        return 1;
    }
    return 0;
}

int OSSL_HTTP_REQ_CTX_set1_req(OSSL_HTTP_REQ_CTX *rctx, const char *content_type,
                               const ASN1_ITEM *it, const ASN1_VALUE *req)
{
    BIO *mem = NULL;
    int res = 1;

    if (req != NULL)
        res = (mem = ASN1_item_i2d_mem_bio(it, req)) != NULL;
    res = res && set1_content(rctx, content_type, mem);
    BIO_free(mem);
    return res;
}

static int add1_headers(OSSL_HTTP_REQ_CTX *rctx,
                        const STACK_OF(CONF_VALUE) *headers, const char *host)
{
    int i;
    int add_host = host != NULL && *host != '\0';
    CONF_VALUE *hdr;

    for (i = 0; i < sk_CONF_VALUE_num(headers); i++) {
        hdr = sk_CONF_VALUE_value(headers, i);
        if (add_host && strcasecmp("host", hdr->name) == 0)
            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;
}

/* 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,
                                           int buf_size, int overall_timeout)
{
    OSSL_HTTP_REQ_CTX *rctx = OSSL_HTTP_REQ_CTX_new(wbio, rbio, buf_size);

    if (rctx == NULL)
        return NULL;
    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;

 err:
    OSSL_HTTP_REQ_CTX_free(rctx);
    return NULL;
}

/*
 * Parse first HTTP response line. This should be like this: "HTTP/1.0 200 OK".
 * We need to obtain the numeric code and (optional) informational message.
 */

static int parse_http_line1(char *line, int *found_keep_alive)
{
    int i, retcode;
    char *code, *reason, *end;

    if (!HAS_PREFIX(line, HTTP_PREFIX_VERSION))
        goto err;
    /* above HTTP 1.0, connection persistence is the default */
    *found_keep_alive = line[strlen(HTTP_PREFIX_VERSION)] > '0';

    /* Skip to first whitespace (past protocol info) */
    for (code = line; *code != '\0' && !ossl_isspace(*code); code++)
        continue;
    if (*code == '\0')
        goto err;

    /* Skip past whitespace to start of response code */
    while (*code != '\0' && ossl_isspace(*code))
        code++;
    if (*code == '\0')
        goto err;

    /* Find end of response code: first whitespace after start of code */
    for (reason = code; *reason != '\0' && !ossl_isspace(*reason); reason++)
        continue;

    if (*reason == '\0')
        goto err;

    /* Set end of response code and start of message */
    *reason++ = '\0';

    /* Attempt to parse numeric code */
    retcode = strtoul(code, &end, 10);
    if (*end != '\0')
        goto err;

    /* 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:
        if (retcode < 400)
            retcode = HTTP_R_STATUS_CODE_UNSUPPORTED;
        else
            retcode = HTTP_R_RECEIVED_ERROR;
        if (*reason == '\0')
            ERR_raise_data(ERR_LIB_HTTP, retcode, "code=%s", code);
        else
            ERR_raise_data(ERR_LIB_HTTP, retcode,
                           "code=%s, reason=%s", code, reason);
        return 0;
    }

 err:
    i = 0;
    while (i < 60 && ossl_isprint(line[i]))
        i++;
    line[i] = '\0';
    ERR_raise_data(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR, "content=%s", line);
    return 0;
}

static int check_set_resp_len(OSSL_HTTP_REQ_CTX *rctx, size_t len)
{
    if (rctx->max_resp_len != 0 && len > rctx->max_resp_len)
        ERR_raise_data(ERR_LIB_HTTP, HTTP_R_MAX_RESP_LEN_EXCEEDED,
                       "length=%zu, max=%zu", len, rctx->max_resp_len);
    if (rctx->resp_len != 0 && rctx->resp_len != len)
        ERR_raise_data(ERR_LIB_HTTP, HTTP_R_INCONSISTENT_CONTENT_LENGTH,
                       "ASN.1 length=%zu, Content-Length=%zu",
                       len, rctx->resp_len);
    rctx->resp_len = len;
    return 1;
}

/*
 * 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)
{
    int i, found_expected_ct = 0, found_keep_alive = 0;
    long n;
    size_t resp_len;
    const unsigned char *p;
    char *key, *value, *line_end = NULL;

    if (rctx == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return 0;
    }
    if (rctx->mem == NULL || rctx->wbio == NULL || rctx->rbio == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_SHOULD_NOT_HAVE_BEEN_CALLED);
        return 0;
    }

    rctx->redirection_url = NULL;
 next_io:
    if ((rctx->state & OHS_NOREAD) == 0) {
        if (rctx->expect_asn1)
            n = BIO_read(rctx->rbio, rctx->buf, rctx->buf_size);
        else
            n = BIO_gets(rctx->rbio, (char *)rctx->buf, rctx->buf_size);
        if (n <= 0) {
            if (BIO_should_retry(rctx->rbio))
                return -1;
            ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA);
            return 0;
        }

        /* Write data to memory BIO */
        if (BIO_write(rctx->mem, rctx->buf, n) != n)
            return 0;
    }

    switch (rctx->state) {
    case OHS_ADD_HEADERS:
        /* 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;

        /* fall thru */
    case OHS_WRITE_INIT:
        rctx->len_to_send = BIO_get_mem_data(rctx->mem, &rctx->pos);
        rctx->state = OHS_WRITE_HDR;

        /* fall thru */
    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) {
            i = BIO_write(rctx->wbio, rctx->pos, rctx->len_to_send);
            if (i <= 0) {
                if (BIO_should_retry(rctx->wbio))
                    return -1;
                rctx->state = OHS_ERROR;
                return 0;
            }
            rctx->pos += i;
            rctx->len_to_send -= i;
            goto next_io;
        }
        if (rctx->state == OHS_WRITE_HDR) {
            (void)BIO_reset(rctx->mem);
            rctx->state = OHS_WRITE_REQ;
        }
        if (rctx->req != NULL && !BIO_eof(rctx->req)) {
            n = BIO_read(rctx->req, rctx->buf, rctx->buf_size);
            if (n <= 0) {
                if (BIO_should_retry(rctx->rbio))
                    return -1;
                ERR_raise(ERR_LIB_HTTP, HTTP_R_FAILED_READING_DATA);
                return 0;
            }
            rctx->pos = rctx->buf;
            rctx->len_to_send = n;
            goto next_io;
        }
        rctx->state = OHS_FLUSH;

        /* fall thru */
    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) {
            if (n >= rctx->buf_size) {
                rctx->state = OHS_ERROR;
                return 0;
            }
            goto next_io;
        }
        n = BIO_gets(rctx->mem, (char *)rctx->buf, rctx->buf_size);

        if (n <= 0) {
            if (BIO_should_retry(rctx->mem))
                goto next_io;
            rctx->state = OHS_ERROR;
            return 0;
        }

        /* Don't allow excessive lines */
        if (n == rctx->buf_size) {
            ERR_raise(ERR_LIB_HTTP, HTTP_R_RESPONSE_LINE_TOO_LONG);
            rctx->state = OHS_ERROR;
            return 0;
        }

        /* First line */
        if (rctx->state == OHS_FIRSTLINE) {
            switch (parse_http_line1((char *)rctx->buf, &found_keep_alive)) {
            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 */
                if (!rctx->method_POST) { /* method is GET */
                    rctx->state = OHS_REDIRECT;
                    goto next_line;
                }
                ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED);
                /* redirection is not supported/recommended for POST */
                /* fall through */
            default:
                rctx->state = OHS_ERROR;
                return 0;
            }
        }
        key = (char *)rctx->buf;
        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) {
            if (rctx->state == OHS_REDIRECT
                    && strcasecmp(key, "Location") == 0) {
                rctx->redirection_url = value;
                return 0;
            }
            if (rctx->expected_ct != NULL
                    && strcasecmp(key, "Content-Type") == 0) {
                if (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;
            }

            /* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
            if (strcasecmp(key, "Connection") == 0) {
                if (strcasecmp(value, "keep-alive") == 0)
                    found_keep_alive = 1;
                else if (strcasecmp(value, "close") == 0)
                    found_keep_alive = 0;
            } else if (strcasecmp(key, "Content-Length") == 0) {
                resp_len = (size_t)strtoul(value, &line_end, 10);
                if (line_end == value || *line_end != '\0') {
                    ERR_raise_data(ERR_LIB_HTTP,
                                   HTTP_R_ERROR_PARSING_CONTENT_LENGTH,
                                   "input=%s", value);
                    return 0;
                }
                if (!check_set_resp_len(rctx, resp_len))
                    return 0;
            }
        }

        /* Look for blank line indicating end of headers */
        for (p = rctx->buf; *p != '\0'; p++) {
            if (*p != '\r' && *p != '\n')
                break;
        }
        if (*p != '\0') /* not end of headers */
            goto next_line;

        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;
        }
        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;
        }

        if (rctx->state == OHS_REDIRECT) {
            /* http status code indicated redirect but there was no Location */
            ERR_raise(ERR_LIB_HTTP, HTTP_R_MISSING_REDIRECT_LOCATION);
            return 0;
        }

        if (!rctx->expect_asn1) {
            rctx->state = OHS_STREAM;
            return 1;
        }

        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)) {
            ERR_raise(ERR_LIB_HTTP, HTTP_R_MISSING_ASN1_ENCODING);
            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)) {
                ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_PARSING_ASN1_LENGTH);
                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;

        rctx->state = OHS_ASN1_CONTENT;

        /* Fall thru */
    case OHS_ASN1_CONTENT:
    default:
        n = BIO_get_mem_data(rctx->mem, NULL);
        if (n < 0 || (size_t)n < rctx->resp_len)
            goto next_io;

        rctx->state = OHS_ASN1_DONE;
        return 1;
    }
}

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;

}

#ifndef OPENSSL_NO_SOCK

/* set up a new connection BIO, to HTTP server or to HTTP(S) proxy if given */
static BIO *http_new_bio(const char *server /* optionally includes ":port" */,
                         const char *server_port /* explicit server port */,
                         int use_ssl,
                         const char *proxy /* optionally includes ":port" */,
                         const char *proxy_port /* explicit proxy port */)
{
    const char *host = server;
    const char *port = server_port;
    BIO *cbio;

    if (!ossl_assert(server != NULL))
        return NULL;

    if (proxy != NULL) {
        host = proxy;
        port = proxy_port;
    }

    if (port == NULL && strchr(host, ':') == NULL)
        port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;

    cbio = BIO_new_connect(host /* optionally includes ":port" */);
    if (cbio == NULL)
        goto end;
    if (port != NULL)
        (void)BIO_set_conn_port(cbio, port);

 end:
    return cbio;
}
#endif /* OPENSSL_NO_SOCK */

/* Exchange request and response via HTTP on (non-)blocking BIO */
BIO *OSSL_HTTP_REQ_CTX_exchange(OSSL_HTTP_REQ_CTX *rctx)
{
    int rv;

    if (rctx == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        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 */
        if (BIO_wait(rctx->rbio, rctx->max_time, 100 /* milliseconds */) <= 0)
            return NULL;
    }

    if (rv == 0) {
        if (rctx->redirection_url == NULL) { /* an error occurred */
            if (rctx->len_to_send > 0)
                ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_SENDING);
            else
                ERR_raise(ERR_LIB_HTTP, HTTP_R_ERROR_RECEIVING);
        }
        return NULL;
    }
    return rctx->state == OHS_STREAM ? rctx->rbio : rctx->mem;
}

int OSSL_HTTP_is_alive(const OSSL_HTTP_REQ_CTX *rctx)
{
    return rctx != NULL && rctx->keep_alive != 0;
}

/* High-level HTTP API implementation */

/* Initiate an HTTP session using bio, else use given server, proxy, etc. */
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,
                                  int buf_size, int overall_timeout)
{
    BIO *cbio; /* == bio if supplied, used as connection BIO if rbio is NULL */
    OSSL_HTTP_REQ_CTX *rctx = NULL;

    if (use_ssl && bio_update_fn == NULL) {
        ERR_raise(ERR_LIB_HTTP, HTTP_R_TLS_NOT_ENABLED);
        return NULL;
    }
    if (rbio != NULL && (bio == NULL || bio_update_fn != NULL)) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT);
        return NULL;
    }

    if (bio != NULL) {
        cbio = bio;
        if (proxy != NULL || no_proxy != NULL) {
            ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT);
            return NULL;
        }
    } else {
#ifndef OPENSSL_NO_SOCK
        char *proxy_host = NULL, *proxy_port = NULL;

        if (server == NULL) {
            ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
            return NULL;
        }
        if (port != NULL && *port == '\0')
            port = NULL;
        if (port == NULL && strchr(server, ':') == NULL)
            port = use_ssl ? OSSL_HTTPS_PORT : OSSL_HTTP_PORT;
        proxy = OSSL_HTTP_adapt_proxy(proxy, no_proxy, server, use_ssl);
        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;
        cbio = http_new_bio(server, port, use_ssl, proxy_host, proxy_port);
        OPENSSL_free(proxy_host);
        OPENSSL_free(proxy_port);
        if (cbio == NULL)
            return NULL;
#else
        ERR_raise(ERR_LIB_HTTP, HTTP_R_SOCK_NOT_SUPPORTED);
        return NULL;
#endif
    }

    (void)ERR_set_mark(); /* prepare removing any spurious libssl errors */
    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);
        goto end;
    }
    /* now overall_timeout is guaranteed to be >= 0 */

    /* callback can be used to wrap or prepend TLS session */
    if (bio_update_fn != NULL) {
        BIO *orig_bio = cbio;

        cbio = (*bio_update_fn)(cbio, arg, 1 /* connect */, use_ssl);
        if (cbio == NULL) {
            cbio = orig_bio;
            goto end;
        }
    }

    rctx = http_req_ctx_new(bio == NULL, cbio, rbio != NULL ? rbio : cbio,
                            bio_update_fn, arg, use_ssl, proxy, server, port,
                            buf_size, overall_timeout);

 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;
}

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)
{
    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;
    if (use_http_proxy && (rctx->server == NULL || rctx->port == NULL)) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_INVALID_ARGUMENT);
        return 0;
    }
    rctx->max_resp_len = max_resp_len; /* allows for 0: indefinite */

    return OSSL_HTTP_REQ_CTX_set_request_line(rctx, req != NULL,
                                              use_http_proxy ? rctx->server
                                              : NULL, rctx->port, path)
        && add1_headers(rctx, headers, rctx->server)
        && OSSL_HTTP_REQ_CTX_set_expected(rctx, expected_content_type,
                                          expect_asn1, timeout, keep_alive)
        && set1_content(rctx, content_type, req);
}

/*-
 * 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 */

    resp = OSSL_HTTP_REQ_CTX_exchange(rctx);
    if (resp == NULL) {
        if (rctx->redirection_url != NULL) {
            if (redirection_url == NULL)
                ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_NOT_ENABLED);
            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)
#ifndef OPENSSL_NO_CMP
                    || (lib == ERR_LIB_CMP
                        && reason == CMP_R_POTENTIALLY_INVALID_CERTIFICATE)
#endif
                ) {
                if (rctx->server != NULL) {
                    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);
                }
                if (rctx->proxy != NULL)
                    ERR_add_error_data(2, " proxy=", rctx->proxy);
                if (err == 0) {
                    BIO_snprintf(buf, sizeof(buf), " peer has disconnected%s",
                                 rctx->use_ssl ? " violating the protocol" :
                                 ", likely because it requires the use of TLS");
                    ERR_add_error_data(1, buf);
                }
            }
        }
    }

    if (resp != NULL && !BIO_up_ref(resp))
        resp = NULL;
    return resp;
}

static int redirection_ok(int n_redir, const char *old_url, const char *new_url)
{
    if (n_redir >= HTTP_VERSION_MAX_REDIRECTIONS) {
        ERR_raise(ERR_LIB_HTTP, HTTP_R_TOO_MANY_REDIRECTIONS);
        return 0;
    }
    if (*new_url == '/') /* redirection to same server => same protocol */
        return 1;
    if (HAS_PREFIX(old_url, OSSL_HTTPS_NAME":") &&
        !HAS_PREFIX(new_url, OSSL_HTTPS_NAME":")) {
        ERR_raise(ERR_LIB_HTTP, HTTP_R_REDIRECTION_FROM_HTTPS_TO_HTTP);
        return 0;
    }
    return 1;
}

/* Get data via HTTP from server at given URL, potentially with redirection */
BIO *OSSL_HTTP_get(const char *url, 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 *expected_ct, int expect_asn1,
                   size_t max_resp_len, int timeout)
{
    char *current_url, *redirection_url = NULL;
    int n_redirs = 0;
    char *host;
    char *port;
    char *path;
    int use_ssl;
    OSSL_HTTP_REQ_CTX *rctx;
    BIO *resp = NULL;

    if (url == NULL) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        return NULL;
    }
    if ((current_url = OPENSSL_strdup(url)) == NULL)
        return NULL;

    for (;;) {
        if (!OSSL_HTTP_parse_url(current_url, &use_ssl, NULL /* user */, &host,
                                 &port, NULL /* port_num */, &path, NULL, NULL))
            break;

        rctx = OSSL_HTTP_open(host, port, proxy, no_proxy,
                              use_ssl, bio, rbio, bio_update_fn, arg,
                              buf_size, timeout);
    new_rpath:
        if (rctx != NULL) {
            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 */))
                OSSL_HTTP_REQ_CTX_free(rctx);
            else
                resp = OSSL_HTTP_exchange(rctx, &redirection_url);
        }
        OPENSSL_free(path);
        if (resp == NULL && redirection_url != NULL) {
            if (redirection_ok(++n_redirs, current_url, redirection_url)) {
                (void)BIO_reset(bio);
                OPENSSL_free(current_url);
                current_url = redirection_url;
                if (*redirection_url == '/') { /* redirection to same server */
                    path = OPENSSL_strdup(redirection_url);
                    goto new_rpath;
                }
                OPENSSL_free(host);
                OPENSSL_free(port);
                (void)OSSL_HTTP_close(rctx, 1);
                continue;
            }
            /* if redirection not allowed, ignore it */
            OPENSSL_free(redirection_url);
        }
        OPENSSL_free(host);
        OPENSSL_free(port);
        if (!OSSL_HTTP_close(rctx, resp != NULL)) {
            BIO_free(resp);
            resp = NULL;
        }
        break;
    }
    OPENSSL_free(current_url);
    return resp;
}

/* Exchange request and response over a connection managed via |prctx| */
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,
                        size_t max_resp_len, int timeout, int keep_alive)
{
    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,
                              buf_size, timeout);
        timeout = -1; /* Already set during opening the connection */
    }
    if (rctx != NULL) {
        if (OSSL_HTTP_set1_request(rctx, path, headers, content_type, req,
                                   expected_ct, expect_asn1,
                                   max_resp_len, timeout, keep_alive))
            resp = OSSL_HTTP_exchange(rctx, NULL);
        if (resp == NULL || !OSSL_HTTP_is_alive(rctx)) {
            if (!OSSL_HTTP_close(rctx, resp != NULL)) {
                BIO_free(resp);
                resp = NULL;
            }
            rctx = NULL;
        }
    }
    if (prctx != NULL)
        *prctx = rctx;
    return resp;
}

int OSSL_HTTP_close(OSSL_HTTP_REQ_CTX *rctx, int ok)
{
    int ret = 1;

    /* callback can be used to clean up TLS session on disconnect */
    if (rctx != NULL && rctx->upd_fn != NULL)
        ret = (*rctx->upd_fn)(rctx->wbio, rctx->upd_arg, 0, ok) != NULL;
    OSSL_HTTP_REQ_CTX_free(rctx);
    return ret;
}

/* 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)
{
#undef BUF_SIZE
#define BUF_SIZE (8 * 1024)
    char *mbuf = OPENSSL_malloc(BUF_SIZE);
    char *mbufp;
    int read_len = 0;
    int ret = 0;
    BIO *fbio = BIO_new(BIO_f_buffer());
    int rv;
    time_t max_time = timeout > 0 ? time(NULL) + timeout : 0;

    if (bio == NULL || server == NULL
            || (bio_err != NULL && prog == NULL)) {
        ERR_raise(ERR_LIB_HTTP, ERR_R_PASSED_NULL_PARAMETER);
        goto end;
    }
    if (port == NULL || *port == '\0')
        port = OSSL_HTTPS_PORT;

    if (mbuf == NULL || fbio == NULL) {
        BIO_printf(bio_err /* may be NULL */, "%s: out of memory", prog);
        goto end;
    }
    BIO_push(fbio, bio);

    BIO_printf(fbio, "CONNECT %s:%s "HTTP_1_0"\r\n", server, port);

    /*
     * 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));
        }
    proxy_end:
        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 */
        rv = BIO_wait(fbio, max_time, 100 /* milliseconds */);
        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:
         * HTTP/d.d ddd reason text\r\n
         */
        read_len = BIO_gets(fbio, mbuf, BUF_SIZE);
        /* the BIO may not block, so we must wait for the 1st line to come in */
        if (read_len < (int)HTTP_LINE1_MINLEN)
            continue;

        /* Check for HTTP/1.x */
        if (!HAS_PREFIX(mbuf, HTTP_PREFIX) != 0) {
            ERR_raise(ERR_LIB_HTTP, HTTP_R_HEADER_PARSE_ERROR);
            BIO_printf(bio_err, "%s: HTTP CONNECT failed, non-HTTP response\n",
                       prog);
            /* Wrong protocol, not even HTTP, so stop reading headers */
            goto end;
        }
        mbufp = mbuf + strlen(HTTP_PREFIX);
        if (!HAS_PREFIX(mbufp, HTTP_VERSION_PATT) != 0) {
            ERR_raise(ERR_LIB_HTTP, HTTP_R_RECEIVED_WRONG_HTTP_VERSION);
            BIO_printf(bio_err,
                       "%s: HTTP CONNECT failed, bad HTTP version %.*s\n",
                       prog, (int)HTTP_VERSION_STR_LEN, mbufp);
            goto end;
        }
        mbufp += HTTP_VERSION_STR_LEN;

        /* RFC 7231 4.3.6: any 2xx status code is valid */
        if (!HAS_PREFIX(mbufp, " 2")) {
            /* chop any trailing whitespace */
            while (read_len > 0 && ossl_isspace(mbuf[read_len - 1]))
                read_len--;
            mbuf[read_len] = '\0';
            ERR_raise_data(ERR_LIB_HTTP, HTTP_R_CONNECT_FAILURE,
                           "reason=%s", mbufp);
            BIO_printf(bio_err, "%s: HTTP CONNECT failed, reason=%s\n",
                       prog, mbufp);
            goto end;
        }
        ret = 1;
        break;
    }

    /* Read past all following headers */
    do {
        /*
         * This does not necessarily catch the case when the full
         * 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;
#undef BUF_SIZE
}
