Browse Source

Support absolute uri (#197) - (Step 1/?)

bel 9 năm trước cách đây
mục cha
commit
0dc10e0dc6
1 tập tin đã thay đổi với 105 bổ sung10 xóa
  1. 105 10
      src/civetweb.c

+ 105 - 10
src/civetweb.c

@@ -9838,19 +9838,114 @@ struct mg_connection *mg_connect_client(
 }
 
 
-static int is_valid_uri(const char *uri)
+static int is_valid_uri(const char *uri, const struct mg_context *ctx)
 {
+	const char *domain;
+	size_t domain_len;
+	unsigned long port;
+	char *pend;
+	int i;
+
 	/* According to the HTTP standard
 	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
 	 * URI can be an asterisk (*) or should start with slash (relative uri),
-     * or it should start with the protocoll (absolute uri). */
-    if (uri[0] == '*' && uri[1] == '\0') {
-        return 1;
-    }
-    if (uri[0] == '/') {
-        return 1;
-    }
-    /* TODO: support absoluteURI #197 */
+	 * or it should start with the protocoll (absolute uri). */
+	if (uri[0] == '*' && uri[1] == '\0') {
+		return 1;
+	}
+	if (uri[0] == '/') {
+		return 1;
+	}
+
+	/* DNS is case insensitive, so use case insensitive string compare here */
+	domain = ctx->config[AUTHENTICATION_DOMAIN];
+	if (!domain) {
+		return 0;
+	}
+	domain_len = strlen(domain);
+	if (!domain_len) {
+		return 0;
+	}
+
+	if (mg_strncasecmp(uri, "http://", 7) == 0) {
+		if (mg_strncasecmp(uri + 7, domain, domain_len) == 0) {
+			if (uri[7 + domain_len] == '/') {
+				port = 80;
+			} else if (uri[7 + domain_len] == ':') {
+				port = strtoul(uri + 7 + domain_len + 1, &pend, 10);
+				if (!pend || *pend != '/') {
+					return 0;
+				}
+			} else {
+				return 0;
+			}
+		} else {
+			/* not the correct domain */
+			return 0;
+		}
+	} else if (mg_strncasecmp(uri, "https://", 8) == 0) {
+		if (mg_strncasecmp(uri + 8, domain, domain_len) == 0) {
+			if (uri[8 + domain_len] == '/') {
+				port = 443;
+			} else if (uri[8 + domain_len] == ':') {
+				port = strtoul(uri + 8 + domain_len + 1, &pend, 10);
+				if (!pend || *pend != '/') {
+					return 0;
+				}
+			} else {
+				return 0;
+			}
+		} else {
+			/* not the correct domain */
+			return 0;
+		}
+	} else if (mg_strncasecmp(uri, "ws://", 5) == 0) {
+		if (mg_strncasecmp(uri + 5, domain, domain_len) == 0) {
+			if (uri[5 + domain_len] == '/') {
+				port = 80;
+			} else if (uri[5 + domain_len] == ':') {
+				port = strtoul(uri + 5 + domain_len + 1, &pend, 10);
+				if (!pend || *pend != '/') {
+					return 0;
+				}
+			} else {
+				return 0;
+			}
+		} else {
+			/* not the correct domain */
+			return 0;
+		}
+	} else if (mg_strncasecmp(uri, "wss://", 6) == 0) {
+		if (mg_strncasecmp(uri + 6, domain, domain_len) == 0) {
+			if (uri[6 + domain_len] == '/') {
+				port = 443;
+			} else if (uri[6 + domain_len] == ':') {
+				port = strtoul(uri + 6 + domain_len + 1, &pend, 10);
+				if (!pend || *pend != '/') {
+					return 0;
+				}
+			} else {
+				return 0;
+			}
+		} else {
+			/* not the correct domain */
+			return 0;
+		}
+	} else {
+		/* unknown protocol */
+		return 0;
+	}
+
+	if (!is_valid_port(port)) {
+		return 0;
+	}
+
+	for (i = 0; i < (int)ctx->num_listening_sockets; i++) {
+		if (ctx->listening_ports[i] == port) {
+			return 1;
+		}
+	}
+
 	return 0;
 }
 
@@ -10222,7 +10317,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 (!is_valid_uri(conn->request_info.uri, conn->ctx)) {
 				mg_snprintf(conn,
 				            NULL, /* No truncation check for ebuf */
 				            ebuf,