Sfoglia il codice sorgente

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

bel 9 anni fa
parent
commit
de04b44535
1 ha cambiato i file con 58 aggiunte e 12 eliminazioni
  1. 58 12
      src/civetweb.c

+ 58 - 12
src/civetweb.c

@@ -9838,24 +9838,70 @@ struct mg_connection *mg_connect_client(
 }
 }
 
 
 
 
-static int is_valid_uri(const char *uri, const struct mg_connection *conn)
+static int is_valid_uri(const char *uri)
 {
 {
-	const char *domain;
-	size_t domain_len;
+	size_t proto_len;
+	char *hostend, *portbegin;
 	unsigned long port;
 	unsigned long port;
 	char *pend;
 	char *pend;
 
 
 	/* According to the HTTP standard
 	/* According to the HTTP standard
 	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
 	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
 	 * URI can be an asterisk (*) or should start with slash (relative uri),
 	 * URI can be an asterisk (*) or should start with slash (relative uri),
-	 * or it should start with the protocoll (absolute uri). */
+	 * or it should start with the protocol (absolute uri). */
 	if (uri[0] == '*' && uri[1] == '\0') {
 	if (uri[0] == '*' && uri[1] == '\0') {
+		/* asterisk */
 		return 1;
 		return 1;
 	}
 	}
 	if (uri[0] == '/') {
 	if (uri[0] == '/') {
+		/* relative uri */
+		return 1;
+	}
+
+	/* it could be an absolute uri */
+	/* is_valid_uri only checks if the uri is valid, not if it is
+	 * addressing the current server. So civetweb can also be used
+	 * as a proxy server. */
+
+	if (mg_strncasecmp(uri, "http://", 7) == 0) {
+		proto_len = 7;
+	} else if (mg_strncasecmp(uri, "https://", 8) == 0) {
+		proto_len = 8;
+	} else if (mg_strncasecmp(uri, "ws://", 5) == 0) {
+		proto_len = 5;
+	} else if (mg_strncasecmp(uri, "wss://", 6) == 0) {
+		proto_len = 6;
+	} else {
+		/* unknown protocol */
+		return 0;
+	}
+
+	hostend = strchr(uri + proto_len, '/');
+	if (!hostend) {
+		return 0;
+	}
+	portbegin = strchr(uri + proto_len, ':');
+	if (!portbegin) {
 		return 1;
 		return 1;
 	}
 	}
 
 
+	port = strtoul(portbegin + 1, &pend, 10);
+	if ((pend != hostend) || !is_valid_port(port)) {
+		return 0;
+	}
+
+	return port && is_valid_port(port);
+}
+
+
+static int is_absolute_uri_at_current_server(const char *uri,
+                                             const struct mg_connection *conn)
+{
+	const char *domain;
+	size_t domain_len;
+	unsigned long port;
+	char *pend;
+
 	/* DNS is case insensitive, so use case insensitive string compare here */
 	/* DNS is case insensitive, so use case insensitive string compare here */
 	domain = conn->ctx->config[AUTHENTICATION_DOMAIN];
 	domain = conn->ctx->config[AUTHENTICATION_DOMAIN];
 	if (!domain) {
 	if (!domain) {
@@ -9939,13 +9985,13 @@ static int is_valid_uri(const char *uri, const struct mg_connection *conn)
 		return 0;
 		return 0;
 	}
 	}
 
 
-#if defined(USE_IPV6)
-	if (conn->client.lsa.sa.sa_family == AF_INET6) {
-		return (conn->client.lsa.sin6.sin6_port == port);
-	}
-#endif
-	
-    return (conn->client.lsa.sin.sin_port == port);
+#if defined(USE_IPV6)
+	if (conn->client.lsa.sa.sa_family == AF_INET6) {
+		return (conn->client.lsa.sin6.sin6_port == port);
+	}
+#endif
+
+	return (conn->client.lsa.sin.sin_port == port);
 }
 }
 
 
 
 
@@ -10316,7 +10362,7 @@ static void process_new_connection(struct mg_connection *conn)
 					/*assert(ebuf[0] != '\0');*/
 					/*assert(ebuf[0] != '\0');*/
 					send_http_error(conn, reqerr, "%s", ebuf);
 					send_http_error(conn, reqerr, "%s", ebuf);
 				}
 				}
-			} else if (!is_valid_uri(conn->request_info.uri, conn)) {
+			} else if (!is_valid_uri(conn->request_info.uri)) {
 				mg_snprintf(conn,
 				mg_snprintf(conn,
 				            NULL, /* No truncation check for ebuf */
 				            NULL, /* No truncation check for ebuf */
 				            ebuf,
 				            ebuf,