|
@@ -9595,6 +9595,7 @@ static void reset_per_request_attributes(struct mg_connection *conn)
|
|
|
conn->request_info.remote_user = NULL;
|
|
|
conn->request_info.request_method = NULL;
|
|
|
conn->request_info.uri = NULL;
|
|
|
+ conn->request_info.rel_uri = NULL;
|
|
|
conn->request_info.http_version = NULL;
|
|
|
conn->request_info.num_headers = 0;
|
|
|
conn->data_len = 0;
|
|
@@ -9849,6 +9850,7 @@ struct {
|
|
|
{NULL, 0, 0}};
|
|
|
|
|
|
|
|
|
+/* return 0 for invalid uri, 1 for *, 2 for relative uri, 3 for absolute uri without port and 4 dor absolute uri with port */
|
|
|
static int is_valid_uri(const char *uri)
|
|
|
{
|
|
|
int i;
|
|
@@ -9865,7 +9867,7 @@ static int is_valid_uri(const char *uri)
|
|
|
}
|
|
|
if (uri[0] == '/') {
|
|
|
/* relative uri */
|
|
|
- return 1;
|
|
|
+ return 2;
|
|
|
}
|
|
|
|
|
|
/* it could be an absolute uri */
|
|
@@ -9884,7 +9886,7 @@ static int is_valid_uri(const char *uri)
|
|
|
}
|
|
|
portbegin = strchr(uri + abs_uri_protocols[i].proto_len, ':');
|
|
|
if (!portbegin) {
|
|
|
- return 1;
|
|
|
+ return 3;
|
|
|
}
|
|
|
|
|
|
port = strtoul(portbegin + 1, &portend, 10);
|
|
@@ -9892,7 +9894,7 @@ static int is_valid_uri(const char *uri)
|
|
|
return 0;
|
|
|
}
|
|
|
|
|
|
- return 1;
|
|
|
+ return 4;
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -9900,8 +9902,10 @@ static int is_valid_uri(const char *uri)
|
|
|
}
|
|
|
|
|
|
|
|
|
-static int is_absolute_uri_at_current_server(const char *uri,
|
|
|
- const struct mg_connection *conn)
|
|
|
+/* Return NULL or the relative uri at the current server */
|
|
|
+static const char *
|
|
|
+is_absolute_uri_at_current_server(const char *uri,
|
|
|
+ const struct mg_connection *conn)
|
|
|
{
|
|
|
const char *domain;
|
|
|
size_t domain_len;
|
|
@@ -9937,6 +9941,7 @@ static int is_absolute_uri_at_current_server(const char *uri,
|
|
|
return 0;
|
|
|
}
|
|
|
}
|
|
|
+ /* protocol found, port set */
|
|
|
}
|
|
|
}
|
|
|
|
|
@@ -9947,11 +9952,17 @@ static int is_absolute_uri_at_current_server(const char *uri,
|
|
|
|
|
|
#if defined(USE_IPV6)
|
|
|
if (conn->client.lsa.sa.sa_family == AF_INET6) {
|
|
|
- return (conn->client.lsa.sin6.sin6_port == port);
|
|
|
- }
|
|
|
+ if (conn->client.lsa.sin6.sin6_port != port) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ } else
|
|
|
#endif
|
|
|
-
|
|
|
- return (conn->client.lsa.sin.sin_port == port);
|
|
|
+ {
|
|
|
+ if (conn->client.lsa.sin.sin_port == port) {
|
|
|
+ return 0;
|
|
|
+ }
|
|
|
+ }
|
|
|
+ return hostend;
|
|
|
}
|
|
|
|
|
|
|
|
@@ -10299,13 +10310,15 @@ mg_connect_websocket_client(const char *host,
|
|
|
return conn;
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void process_new_connection(struct mg_connection *conn)
|
|
|
{
|
|
|
if (conn && conn->ctx) {
|
|
|
struct mg_request_info *ri = &conn->request_info;
|
|
|
int keep_alive_enabled, keep_alive, discard_len;
|
|
|
char ebuf[100];
|
|
|
- int reqerr;
|
|
|
+ const char *hostend;
|
|
|
+ int reqerr, uri_type;
|
|
|
|
|
|
keep_alive_enabled =
|
|
|
!strcmp(conn->ctx->config[ENABLE_KEEP_ALIVE], "yes");
|
|
@@ -10322,7 +10335,7 @@ static void process_new_connection(struct mg_connection *conn)
|
|
|
/*assert(ebuf[0] != '\0');*/
|
|
|
send_http_error(conn, reqerr, "%s", ebuf);
|
|
|
}
|
|
|
- } else if (!is_valid_uri(conn->request_info.uri)) {
|
|
|
+ } else if ((uri_type = is_valid_uri(conn->request_info.uri)) == 0) {
|
|
|
mg_snprintf(conn,
|
|
|
NULL, /* No truncation check for ebuf */
|
|
|
ebuf,
|
|
@@ -10341,6 +10354,36 @@ static void process_new_connection(struct mg_connection *conn)
|
|
|
send_http_error(conn, 505, "%s", ebuf);
|
|
|
}
|
|
|
|
|
|
+ switch (uri_type) {
|
|
|
+ case 1:
|
|
|
+ /* Asterisk */
|
|
|
+ conn->request_info.rel_uri = NULL;
|
|
|
+ break;
|
|
|
+ case 2:
|
|
|
+ /* relative uri */
|
|
|
+ conn->request_info.rel_uri = conn->request_info.uri;
|
|
|
+ break;
|
|
|
+ case 3:
|
|
|
+ /* absolute uri */
|
|
|
+ hostend = is_absolute_uri_at_current_server(
|
|
|
+ conn->request_info.uri, conn);
|
|
|
+ if (hostend) {
|
|
|
+ conn->request_info.rel_uri = hostend;
|
|
|
+ } else {
|
|
|
+ conn->request_info.rel_uri = NULL;
|
|
|
+ }
|
|
|
+ break;
|
|
|
+ default:
|
|
|
+ mg_snprintf(conn,
|
|
|
+ NULL, /* No truncation check for ebuf */
|
|
|
+ ebuf,
|
|
|
+ sizeof(ebuf),
|
|
|
+ "Invalid URI: [%s]",
|
|
|
+ ri->uri);
|
|
|
+ send_http_error(conn, 400, "%s", ebuf);
|
|
|
+ break;
|
|
|
+ }
|
|
|
+
|
|
|
if (ebuf[0] == '\0') {
|
|
|
handle_request(conn);
|
|
|
if (conn->ctx->callbacks.end_request != NULL) {
|
|
@@ -10392,6 +10435,7 @@ static void process_new_connection(struct mg_connection *conn)
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
/* Worker threads take accepted socket from the queue */
|
|
|
static int consume_socket(struct mg_context *ctx, struct socket *sp)
|
|
|
{
|
|
@@ -10431,6 +10475,7 @@ static int consume_socket(struct mg_context *ctx, struct socket *sp)
|
|
|
#undef QUEUE_SIZE
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void *worker_thread_run(void *thread_func_param)
|
|
|
{
|
|
|
struct mg_context *ctx = (struct mg_context *)thread_func_param;
|
|
@@ -10524,8 +10569,8 @@ static void *worker_thread_run(void *thread_func_param)
|
|
|
return NULL;
|
|
|
}
|
|
|
|
|
|
-/* Threads have different return types on Windows and Unix. */
|
|
|
|
|
|
+/* Threads have different return types on Windows and Unix. */
|
|
|
#ifdef _WIN32
|
|
|
static unsigned __stdcall worker_thread(void *thread_func_param)
|
|
|
{
|
|
@@ -10540,6 +10585,7 @@ static void *worker_thread(void *thread_func_param)
|
|
|
}
|
|
|
#endif /* _WIN32 */
|
|
|
|
|
|
+
|
|
|
/* Master thread adds accepted socket to a queue */
|
|
|
static void produce_socket(struct mg_context *ctx, const struct socket *sp)
|
|
|
{
|
|
@@ -10567,6 +10613,7 @@ static void produce_socket(struct mg_context *ctx, const struct socket *sp)
|
|
|
#undef QUEUE_SIZE
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void accept_new_connection(const struct socket *listener,
|
|
|
struct mg_context *ctx)
|
|
|
{
|
|
@@ -10636,6 +10683,7 @@ static void accept_new_connection(const struct socket *listener,
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+
|
|
|
static void master_thread_run(void *thread_func_param)
|
|
|
{
|
|
|
struct mg_context *ctx = (struct mg_context *)thread_func_param;
|