struct ossl_http_req_ctx_st {
int state; /* Current I/O state */
- unsigned char *iobuf; /* Line buffer */
- int iobuflen; /* Line buffer length */
+ unsigned char *readbuf; /* Buffer for reading response by line */
+ int readbuflen; /* Buffer length, equals maxline */
BIO *wbio; /* BIO to send request to */
BIO *rbio; /* BIO to read response from */
BIO *mem; /* Memory BIO response is built into */
char *redirection_url; /* Location given with HTTP status 301/302 */
};
-#define HTTP_DEFAULT_MAX_LINE_LENGTH (4 * 1024)
-#define HTTP_DEFAULT_MAX_RESP_LEN (100 * 1024)
-
/* HTTP states */
#define OHS_NOREAD 0x1000 /* If set no reading should be performed */
if ((rctx = OPENSSL_zalloc(sizeof(*rctx))) == NULL)
return NULL;
rctx->state = OHS_ERROR;
- rctx->iobuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH;
- rctx->iobuf = OPENSSL_malloc(rctx->iobuflen);
+ rctx->readbuflen = maxline > 0 ? maxline : HTTP_DEFAULT_MAX_LINE_LENGTH;
+ rctx->readbuf = OPENSSL_malloc(rctx->readbuflen);
rctx->wbio = wbio;
rctx->rbio = rbio;
rctx->mem = BIO_new(BIO_s_mem());
- if (rctx->iobuf == NULL || rctx->mem == NULL) {
+ if (rctx->readbuf == NULL || rctx->mem == NULL) {
OSSL_HTTP_REQ_CTX_free(rctx);
return NULL;
}
if (rctx == NULL)
return;
BIO_free(rctx->mem); /* this may indirectly call ERR_clear_error() */
- OPENSSL_free(rctx->iobuf);
+ OPENSSL_free(rctx->readbuf);
OPENSSL_free(rctx);
}
"length=%lu, max=%lu", 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,
- "length=%lu, before=%lu", len, rctx->resp_len);
+ "ASN.1 length=%lu, Content-Length=%lu",
+ len, rctx->resp_len);
rctx->resp_len = len;
return 1;
}
rctx->redirection_url = NULL;
next_io:
if ((rctx->state & OHS_NOREAD) == 0) {
- n = BIO_read(rctx->rbio, rctx->iobuf, rctx->iobuflen);
+ n = BIO_read(rctx->rbio, rctx->readbuf, rctx->readbuflen);
if (n <= 0) {
if (BIO_should_retry(rctx->rbio))
return -1;
}
/* Write data to memory BIO */
- if (BIO_write(rctx->mem, rctx->iobuf, n) != n)
+ if (BIO_write(rctx->mem, rctx->readbuf, n) != n)
return 0;
}
*/
n = BIO_get_mem_data(rctx->mem, &p);
if (n <= 0 || memchr(p, '\n', n) == 0) {
- if (n >= rctx->iobuflen) {
+ if (n >= rctx->readbuflen) {
rctx->state = OHS_ERROR;
return 0;
}
goto next_io;
}
- n = BIO_gets(rctx->mem, (char *)rctx->iobuf, rctx->iobuflen);
+ n = BIO_gets(rctx->mem, (char *)rctx->readbuf, rctx->readbuflen);
if (n <= 0) {
if (BIO_should_retry(rctx->mem))
}
/* Don't allow excessive lines */
- if (n == rctx->iobuflen) {
+ if (n == rctx->readbuflen) {
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->iobuf)) {
+ switch (parse_http_line1((char *)rctx->readbuf)) {
case HTTP_STATUS_CODE_OK:
rctx->state = OHS_HEADERS;
goto next_line;
return 0;
}
}
- key = (char *)rctx->iobuf;
+ key = (char *)rctx->readbuf;
value = strchr(key, ':');
if (value != NULL) {
*(value++) = '\0';
}
}
- /* Look for blank line: end of headers */
- for (p = rctx->iobuf; *p != '\0'; p++) {
+ /* Look for blank line indicating end of headers */
+ for (p = rctx->readbuf; *p != '\0'; p++) {
if (*p != '\r' && *p != '\n')
break;
}
OSSL_HTTP_REQ_CTX_new() allocates a new HTTP request context structure,
which gets populated with the B<BIO> to send the request to (I<wbio>),
the B<BIO> to read the response from (I<rbio>, which may be equal to I<wbio>),
+the maximum expected response header line length (I<maxline>, where any
+zero or less indicates using the B<HTTP_DEFAULT_MAX_LINE_LENGTH> of 4KiB;
+this length is also used as the number of content bytes read at a time),
the request method (I<method_POST>, which may be 1 to indicate that the C<POST>
method is to be used, or 0 to indicate that the C<GET> method is to be used),
-the maximum expected response header length (I<max_resp_len>,
-where any zero or less indicates the default of 4KiB),
+the maximum allowed response content length (I<max_resp_len>, where 0 means
+that the B<HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB),
a response timeout measure in seconds (I<timeout>,
where 0 indicates no timeout, i.e., waiting indefinitely),
the expected MIME content type of the response (I<expected_content_type>,
several times until a timeout is reached, and DER decodes the received
response using the ASN.1 template I<it>.
-OSSL_HTTP_REQ_CTX_set_max_response_length() sets the maximum response length
-for I<rctx> to I<len>. If the response exceeds this length an error occurs.
-If not set a default value of 100k is used.
-
OSSL_HTTP_REQ_CTX_get0_mem_bio() returns the internal memory B<BIO>. This can
be used to affect the HTTP request text. I<Use with caution!>
+OSSL_HTTP_REQ_CTX_set_max_response_length() sets the maximum allowed
+response content length for I<rctx> to I<len>. If not set or I<len> is 0
+then the B<HTTP_DEFAULT_MAX_RESP_LEN> is used, which currently is 100 KiB.
+If the C<Content-Length> header is present and exceeds this value or
+the content is an ASN.1 encoded structure with a length exceeding this value
+or both length indications are present but disagree then an error occurs.
+
=head1 WARNINGS
The server's response may be unexpected if the hostname that was used to