/*
* 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() */
#include "http_local.h"
#define HTTP_PREFIX "HTTP/"
#define HTTP_VERSION_PATT "1." /* allow 1.x */
#define HTTP_PREFIX_VERSION HTTP_PREFIX""HTTP_VERSION_PATT
#define HTTP_1_0 HTTP_PREFIX_VERSION"0" /* "HTTP/1.0" */
#define HTTP_VERSION_PATT_LEN strlen(HTTP_PREFIX_VERSION)
#define HTTP_VERSION_STR_LEN (HTTP_VERSION_PATT_LEN + 1)
#define HTTP_LINE1_MINLEN ((int)strlen(HTTP_PREFIX_VERSION "x 200\n"))
#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 *readbuf; /* Buffer for reading response by line */
int readbuflen; /* Buffer length, equals buf_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 and response */
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 */
long len_to_send; /* Number of bytes in request still to send */
unsigned long resp_len; /* Length of response */
size_t max_resp_len; /* Maximum length of response */
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;