# define _POSIX_C_SOURCE 2
#endif
-#include <string.h>
#include <ctype.h>
#include "http_server.h"
#include "internal/sockets.h"
#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_STR " "HTTP_PREFIX_VERSION
#ifdef HTTP_DAEMON
#endif
#ifndef OPENSSL_NO_SOCK
-BIO *http_server_init_bio(const char *prog, const char *port)
+BIO *http_server_init(const char *prog, const char *port, int verb)
{
BIO *acbio = NULL, *bufbio;
int asock;
+ int port_num;
+ if (verb >= 0) {
+ if (verb > LOG_TRACE) {
+ log_message(prog, LOG_ERR,
+ "Logging verbosity level %d too high", verb);
+ return NULL;
+ }
+ verbosity = verb;
+ }
bufbio = BIO_new(BIO_f_buffer());
if (bufbio == NULL)
goto err;
acbio = BIO_new(BIO_s_accept());
if (acbio == NULL
|| BIO_set_bind_mode(acbio, BIO_BIND_REUSEADDR) < 0
- || BIO_set_accept_port(acbio, port) < 0) {
+ || BIO_set_accept_port(acbio, port /* may be "0" */) < 0) {
log_message(prog, LOG_ERR, "Error setting up accept BIO");
goto err;
}
/* Report back what address and port are used */
BIO_get_fd(acbio, &asock);
- if (!report_server_accept(bio_out, asock, 1)) {
+ port_num = report_server_accept(bio_out, asock, 1, 1);
+ if (port_num == 0) {
log_message(prog, LOG_ERR, "Error printing ACCEPT string");
goto err;
}
int http_server_get_asn1_req(const ASN1_ITEM *it, ASN1_VALUE **preq,
char **ppath, BIO **pcbio, BIO *acbio,
int *found_keep_alive,
- const char *prog, const char *port,
- int accept_get, int timeout)
+ const char *prog, int accept_get, int timeout)
{
BIO *cbio = *pcbio, *getbio = NULL, *b64 = NULL;
int len;
*ppath = NULL;
if (cbio == NULL) {
+ char *port;
+
+ get_sock_info_address(BIO_get_fd(acbio, NULL), NULL, &port);
+ if (port == NULL) {
+ log_message(prog, LOG_ERR, "Cannot get port listening on");
+ goto fatal;
+ }
log_message(prog, LOG_DEBUG,
- "Awaiting new connection on port %s...", port);
+ "Awaiting new connection on port %s ...", port);
+ OPENSSL_free(port);
+
if (BIO_do_accept(acbio) <= 0)
/* Connection loss before accept() is routine, ignore silently */
return ret;
*pcbio = cbio = BIO_pop(acbio);
} else {
- log_message(prog, LOG_DEBUG, "Awaiting next request...");
+ log_message(prog, LOG_DEBUG, "Awaiting next request ...");
}
if (cbio == NULL) {
/* Cannot call http_server_send_status(cbio, ...) */
*end = '\0';
log_message(prog, LOG_INFO, "Received request, 1st line: %s", reqbuf);
- meth = reqbuf;
- url = meth + 3;
- if ((accept_get && strncmp(meth, "GET ", 4) == 0)
- || (url++, strncmp(meth, "POST ", 5) == 0)) {
- static const char http_version_str[] = " "HTTP_PREFIX_VERSION;
- static const size_t http_version_str_len = sizeof(http_version_str) - 1;
+ url = meth = reqbuf;
+ if ((accept_get && CHECK_AND_SKIP_PREFIX(url, "GET "))
+ || CHECK_AND_SKIP_PREFIX(url, "POST ")) {
/* Expecting (GET|POST) {sp} /URL {sp} HTTP/1.x */
- *(url++) = '\0';
+ url[-1] = '\0';
while (*url == ' ')
url++;
if (*url != '/') {
for (end = url; *end != '\0'; end++)
if (*end == ' ')
break;
- if (strncmp(end, http_version_str, http_version_str_len) != 0) {
+ if (!HAS_PREFIX(end, HTTP_VERSION_STR)) {
log_message(prog, LOG_WARNING,
"Invalid %s -- bad HTTP/version string: %s",
meth, end + 1);
*end = '\0';
/* above HTTP 1.0, connection persistence is the default */
if (found_keep_alive != NULL)
- *found_keep_alive = end[http_version_str_len] > '0';
+ *found_keep_alive = end[sizeof(HTTP_VERSION_STR) - 1] > '0';
/*-
* Skip "GET / HTTP..." requests often used by load-balancers.
}
*line_end = '\0';
/* https://tools.ietf.org/html/rfc7230#section-6.3 Persistence */
- if (found_keep_alive != NULL && strcasecmp(key, "Connection") == 0) {
- if (strcasecmp(value, "keep-alive") == 0)
+ if (found_keep_alive != NULL
+ && OPENSSL_strcasecmp(key, "Connection") == 0) {
+ if (OPENSSL_strcasecmp(value, "keep-alive") == 0)
*found_keep_alive = 1;
- else if (strcasecmp(value, "close") == 0)
+ else if (OPENSSL_strcasecmp(value, "close") == 0)
*found_keep_alive = 0;
}
}