|
@@ -141,12 +141,14 @@ static void DEBUG_TRACE_FUNC(const char *func,
|
|
|
...) PRINTF_ARGS(3, 4);
|
|
|
|
|
|
#define DEBUG_TRACE(fmt, ...) \
|
|
|
- DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
|
|
|
+ DEBUG_TRACE_FUNC(__func__, __LINE__, fmt, __VA_ARGS__)
|
|
|
+
|
|
|
+#define NEED_DEBUG_TRACE_FUNC
|
|
|
|
|
|
#else
|
|
|
#define DEBUG_TRACE(fmt, ...) \
|
|
|
- do { \
|
|
|
- } while (0)
|
|
|
+ do { \
|
|
|
+ } while (0)
|
|
|
#endif /* DEBUG */
|
|
|
#endif /* DEBUG_TRACE */
|
|
|
|
|
@@ -154,16 +156,16 @@ static void DEBUG_TRACE_FUNC(const char *func,
|
|
|
#if !defined(DEBUG_ASSERT)
|
|
|
#if defined(DEBUG)
|
|
|
#define DEBUG_ASSERT(cond) \
|
|
|
- do { \
|
|
|
- if (!(cond)) { \
|
|
|
- DEBUG_TRACE("ASSERTION FAILED: %s", #cond); \
|
|
|
- exit(2); /* Exit with error */ \
|
|
|
- } \
|
|
|
- } while (0)
|
|
|
+ do { \
|
|
|
+ if (!(cond)) { \
|
|
|
+ DEBUG_TRACE("ASSERTION FAILED: %s", #cond); \
|
|
|
+ exit(2); /* Exit with error */ \
|
|
|
+ } \
|
|
|
+ } while (0)
|
|
|
#else
|
|
|
#define DEBUG_ASSERT(cond) \
|
|
|
- do { \
|
|
|
- } while (0)
|
|
|
+ do { \
|
|
|
+ } while (0)
|
|
|
#endif /* DEBUG */
|
|
|
#endif
|
|
|
|
|
@@ -1505,8 +1507,7 @@ mg_get_current_time_ns(void)
|
|
|
#endif
|
|
|
|
|
|
|
|
|
-#if !defined(DEBUG_TRACE)
|
|
|
-#if defined(DEBUG)
|
|
|
+#if defined(NEED_DEBUG_TRACE_FUNC)
|
|
|
static void
|
|
|
DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...)
|
|
|
{
|
|
@@ -1542,8 +1543,7 @@ DEBUG_TRACE_FUNC(const char *func, unsigned line, const char *fmt, ...)
|
|
|
funlockfile(stdout);
|
|
|
nslast = nsnow;
|
|
|
}
|
|
|
-#endif /* DEBUG */
|
|
|
-#endif /* DEBUG_TRACE */
|
|
|
+#endif /* NEED_DEBUG_TRACE_FUNC */
|
|
|
|
|
|
|
|
|
#define MD5_STATIC static
|
|
@@ -2487,6 +2487,7 @@ struct mg_connection {
|
|
|
* mg_get_connection_info_impl */
|
|
|
#endif
|
|
|
|
|
|
+ const char *host; /* Host (HTTP/1.1 header or SNI) */
|
|
|
SSL *ssl; /* SSL descriptor */
|
|
|
SSL_CTX *client_ssl_ctx; /* SSL context for client connections */
|
|
|
struct socket client; /* Connected client */
|
|
@@ -3092,11 +3093,11 @@ mg_strcasecmp(const char *s1, const char *s2)
|
|
|
|
|
|
|
|
|
static char *
|
|
|
-mg_strndup(const char *ptr, size_t len)
|
|
|
+mg_strndup_ctx(const char *ptr, size_t len, struct mg_context *ctx)
|
|
|
{
|
|
|
char *p;
|
|
|
|
|
|
- if ((p = (char *)mg_malloc(len + 1)) != NULL) {
|
|
|
+ if ((p = (char *)mg_malloc_ctx(len + 1, ctx)) != NULL) {
|
|
|
mg_strlcpy(p, ptr, len + 1);
|
|
|
}
|
|
|
|
|
@@ -3105,9 +3106,15 @@ mg_strndup(const char *ptr, size_t len)
|
|
|
|
|
|
|
|
|
static char *
|
|
|
+mg_strdup_ctx(const char *str, struct mg_context *ctx)
|
|
|
+{
|
|
|
+ return mg_strndup_ctx(str, strlen(str), ctx);
|
|
|
+}
|
|
|
+
|
|
|
+static char *
|
|
|
mg_strdup(const char *str)
|
|
|
{
|
|
|
- return mg_strndup(str, strlen(str));
|
|
|
+ return mg_strndup_ctx(str, strlen(str), NULL);
|
|
|
}
|
|
|
|
|
|
|
|
@@ -7048,7 +7055,8 @@ interpret_uri(struct mg_connection *conn, /* in/out: request (must be valid) */
|
|
|
filename);
|
|
|
|
|
|
/* this index file is a script */
|
|
|
- tmp_str2 = mg_strdup(filename + sep_pos + 1);
|
|
|
+ tmp_str2 = mg_strdup_ctx(filename + sep_pos + 1,
|
|
|
+ conn->phys_ctx);
|
|
|
mg_snprintf(conn,
|
|
|
&truncated,
|
|
|
filename,
|
|
@@ -7675,7 +7683,8 @@ parse_auth_header(struct mg_connection *conn,
|
|
|
|
|
|
/* CGI needs it as REMOTE_USER */
|
|
|
if (ah->user != NULL) {
|
|
|
- conn->request_info.remote_user = mg_strdup(ah->user);
|
|
|
+ conn->request_info.remote_user =
|
|
|
+ mg_strdup_ctx(ah->user, conn->phys_ctx);
|
|
|
} else {
|
|
|
return 0;
|
|
|
}
|
|
@@ -8268,7 +8277,7 @@ connect_socket(struct mg_context *ctx /* may be NULL */,
|
|
|
/* While getaddrinfo on Windows will work with [::1],
|
|
|
* getaddrinfo on Linux only works with ::1 (without []). */
|
|
|
size_t l = strlen(host + 1);
|
|
|
- char *h = (l > 1) ? mg_strdup(host + 1) : NULL;
|
|
|
+ char *h = (l > 1) ? mg_strdup_ctx(host + 1, ctx) : NULL;
|
|
|
if (h) {
|
|
|
h[l - 1] = 0;
|
|
|
if (mg_inet_pton(AF_INET6, h, &sa->sin6, sizeof(sa->sin6))) {
|
|
@@ -12141,14 +12150,18 @@ get_first_ssl_listener_index(const struct mg_context *ctx)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static void
|
|
|
-redirect_to_https_port(struct mg_connection *conn, int ssl_index)
|
|
|
+/* Return host (without port) */
|
|
|
+/* Use mg_free to free the result */
|
|
|
+static const char *
|
|
|
+alloc_get_host(struct mg_connection *conn)
|
|
|
{
|
|
|
char host[1025];
|
|
|
const char *host_header;
|
|
|
size_t hostlen;
|
|
|
|
|
|
- host_header = mg_get_header(conn, "Host");
|
|
|
+ host_header = get_header(conn->request_info.http_headers,
|
|
|
+ conn->request_info.num_headers,
|
|
|
+ "Host");
|
|
|
hostlen = sizeof(host);
|
|
|
if (host_header != NULL) {
|
|
|
char *pos;
|
|
@@ -12159,19 +12172,26 @@ redirect_to_https_port(struct mg_connection *conn, int ssl_index)
|
|
|
if (pos != NULL) {
|
|
|
*pos = '\0';
|
|
|
}
|
|
|
+ DEBUG_TRACE("Host: %s", host);
|
|
|
} else {
|
|
|
- /* Cannot get host from the Host: header.
|
|
|
- * Fallback to our IP address. */
|
|
|
- if (conn) {
|
|
|
- sockaddr_to_string(host, hostlen, &conn->client.lsa);
|
|
|
- }
|
|
|
+ sockaddr_to_string(host, hostlen, &conn->client.lsa);
|
|
|
+ DEBUG_TRACE("IP: %s", host);
|
|
|
}
|
|
|
|
|
|
+ return mg_strdup_ctx(host, conn->phys_ctx);
|
|
|
+}
|
|
|
+
|
|
|
+
|
|
|
+static void
|
|
|
+redirect_to_https_port(struct mg_connection *conn, int ssl_index)
|
|
|
+{
|
|
|
+ conn->must_close = 1;
|
|
|
+
|
|
|
/* Send host, port, uri and (if it exists) ?query_string */
|
|
|
- if (conn) {
|
|
|
+ if (conn->host) {
|
|
|
mg_printf(conn,
|
|
|
"HTTP/1.1 302 Found\r\nLocation: https://%s:%d%s%s%s\r\n\r\n",
|
|
|
- host,
|
|
|
+ conn->host,
|
|
|
#if defined(USE_IPV6)
|
|
|
(conn->phys_ctx->listening_sockets[ssl_index].lsa.sa.sa_family
|
|
|
== AF_INET6)
|
|
@@ -12318,7 +12338,7 @@ mg_set_handler_type(struct mg_context *phys_ctx,
|
|
|
"Cannot create new request handler struct, OOM");
|
|
|
return;
|
|
|
}
|
|
|
- tmp_rh->uri = mg_strdup(uri);
|
|
|
+ tmp_rh->uri = mg_strdup_ctx(uri, phys_ctx);
|
|
|
if (!tmp_rh->uri) {
|
|
|
mg_unlock_context(phys_ctx);
|
|
|
mg_free(tmp_rh);
|
|
@@ -14105,10 +14125,14 @@ ssl_get_client_cert_info(struct mg_connection *conn)
|
|
|
mg_malloc_ctx(sizeof(struct mg_client_cert), conn->phys_ctx);
|
|
|
if (conn->request_info.client_cert) {
|
|
|
conn->request_info.client_cert->peer_cert = (void *)cert;
|
|
|
- conn->request_info.client_cert->subject = mg_strdup(str_subject);
|
|
|
- conn->request_info.client_cert->issuer = mg_strdup(str_issuer);
|
|
|
- conn->request_info.client_cert->serial = mg_strdup(str_serial);
|
|
|
- conn->request_info.client_cert->finger = mg_strdup(str_finger);
|
|
|
+ conn->request_info.client_cert->subject =
|
|
|
+ mg_strdup_ctx(str_subject, conn->phys_ctx);
|
|
|
+ conn->request_info.client_cert->issuer =
|
|
|
+ mg_strdup_ctx(str_issuer, conn->phys_ctx);
|
|
|
+ conn->request_info.client_cert->serial =
|
|
|
+ mg_strdup_ctx(str_serial, conn->phys_ctx);
|
|
|
+ conn->request_info.client_cert->finger =
|
|
|
+ mg_strdup_ctx(str_finger, conn->phys_ctx);
|
|
|
} else {
|
|
|
mg_cry(conn,
|
|
|
"Out of memory: Cannot allocate memory for client "
|
|
@@ -15122,6 +15146,11 @@ close_connection(struct mg_connection *conn)
|
|
|
conn->client.sock = INVALID_SOCKET;
|
|
|
}
|
|
|
|
|
|
+ if (conn->host) {
|
|
|
+ mg_free((void *)conn->host);
|
|
|
+ conn->host = NULL;
|
|
|
+ }
|
|
|
+
|
|
|
mg_unlock_connection(conn);
|
|
|
|
|
|
#if defined(USE_SERVER_STATS)
|
|
@@ -15729,6 +15758,11 @@ get_request(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
|
|
|
}
|
|
|
|
|
|
/* Message is a valid request */
|
|
|
+
|
|
|
+ /* Is there a "host" ? */
|
|
|
+ conn->host = alloc_get_host(conn);
|
|
|
+
|
|
|
+ /* Do we know the content length? */
|
|
|
if ((cl = get_header(conn->request_info.http_headers,
|
|
|
conn->request_info.num_headers,
|
|
|
"Content-Length")) != NULL) {
|
|
@@ -15789,6 +15823,8 @@ get_response(struct mg_connection *conn, char *ebuf, size_t ebuf_len, int *err)
|
|
|
}
|
|
|
|
|
|
/* Message is a valid response */
|
|
|
+
|
|
|
+ /* Do we know the content length? */
|
|
|
if ((cl = get_header(conn->response_info.http_headers,
|
|
|
conn->response_info.num_headers,
|
|
|
"Content-Length")) != NULL) {
|
|
@@ -16528,7 +16564,8 @@ worker_thread_run(struct worker_thread_args *thread_args)
|
|
|
conn->buf_size = (int)ctx->max_request_size;
|
|
|
|
|
|
conn->phys_ctx = ctx;
|
|
|
- conn->dom_ctx = &(ctx->dd); /* Use default domain, until more is knwon */
|
|
|
+ conn->dom_ctx = &(ctx->dd); /* Use default domain and default host */
|
|
|
+ conn->host = NULL; /* until we have more information. */
|
|
|
|
|
|
conn->thread_index = thread_args->index;
|
|
|
conn->request_info.user_data = ctx->user_data;
|
|
@@ -17177,7 +17214,7 @@ mg_start(const struct mg_callbacks *callbacks,
|
|
|
mg_cry(fc(ctx), "warning: %s: duplicate option", name);
|
|
|
mg_free(ctx->dd.config[idx]);
|
|
|
}
|
|
|
- ctx->dd.config[idx] = mg_strdup(value);
|
|
|
+ ctx->dd.config[idx] = mg_strdup_ctx(value, ctx);
|
|
|
DEBUG_TRACE("[%s] -> [%s]", name, value);
|
|
|
}
|
|
|
|
|
@@ -17185,7 +17222,7 @@ mg_start(const struct mg_callbacks *callbacks,
|
|
|
for (i = 0; config_options[i].name != NULL; i++) {
|
|
|
default_value = config_options[i].default_value;
|
|
|
if ((ctx->dd.config[i] == NULL) && (default_value != NULL)) {
|
|
|
- ctx->dd.config[i] = mg_strdup(default_value);
|
|
|
+ ctx->dd.config[i] = mg_strdup_ctx(default_value, ctx);
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -17445,7 +17482,7 @@ mg_start_domain(struct mg_context *ctx, const char **options)
|
|
|
mg_cry(fc(ctx), "warning: %s: duplicate option", name);
|
|
|
mg_free(new_dom->config[idx]);
|
|
|
}
|
|
|
- new_dom->config[idx] = mg_strdup(value);
|
|
|
+ new_dom->config[idx] = mg_strdup_ctx(value, ctx);
|
|
|
DEBUG_TRACE("[%s] -> [%s]", name, value);
|
|
|
}
|
|
|
|
|
@@ -17460,7 +17497,7 @@ mg_start_domain(struct mg_context *ctx, const char **options)
|
|
|
for (i = 0; config_options[i].name != NULL; i++) {
|
|
|
default_value = ctx->dd.config[i];
|
|
|
if ((new_dom->config[i] == NULL) && (default_value != NULL)) {
|
|
|
- new_dom->config[i] = mg_strdup(default_value);
|
|
|
+ new_dom->config[i] = mg_strdup_ctx(default_value, ctx);
|
|
|
}
|
|
|
}
|
|
|
|