소스 검색

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

bel 9 년 전
부모
커밋
2a2155ce0f
1개의 변경된 파일50개의 추가작업 그리고 90개의 파일을 삭제
  1. 50 90
      src/civetweb.c

+ 50 - 90
src/civetweb.c

@@ -9838,12 +9838,22 @@ struct mg_connection *mg_connect_client(
 }
 
 
+struct {
+	const char *proto;
+	size_t proto_len;
+	int default_port;
+} static abs_uri_protocols[] = {{"http://", 7, 80},
+                                {"https://", 8, 443},
+                                {"ws://", 5, 80},
+                                {"wss://", 6, 443},
+                                {NULL, 0, 0}};
+
+
 static int is_valid_uri(const char *uri)
 {
-	size_t proto_len;
-	char *hostend, *portbegin;
+	int i;
+	char *hostend, *portbegin, *portend;
 	unsigned long port;
-	char *pend;
 
 	/* According to the HTTP standard
 	 * http://www.w3.org/Protocols/rfc2616/rfc2616-sec5.html#sec5.1.2
@@ -9863,34 +9873,30 @@ static int is_valid_uri(const char *uri)
 	 * 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;
-	}
+	for (i = 0; abs_uri_protocols[i].proto != NULL; i++) {
+		if (mg_strncasecmp(uri,
+		                   abs_uri_protocols[i].proto,
+		                   abs_uri_protocols[i].proto_len) == 0) {
 
-	hostend = strchr(uri + proto_len, '/');
-	if (!hostend) {
-		return 0;
-	}
-	portbegin = strchr(uri + proto_len, ':');
-	if (!portbegin) {
-		return 1;
-	}
+			hostend = strchr(uri + abs_uri_protocols[i].proto_len, '/');
+			if (!hostend) {
+				return 0;
+			}
+			portbegin = strchr(uri + abs_uri_protocols[i].proto_len, ':');
+			if (!portbegin) {
+				return 1;
+			}
 
-	port = strtoul(portbegin + 1, &pend, 10);
-	if ((pend != hostend) || !is_valid_port(port)) {
-		return 0;
+			port = strtoul(portbegin + 1, &portend, 10);
+			if ((portend != hostend) || !port || !is_valid_port(port)) {
+				return 0;
+			}
+
+			return 1;
+		}
 	}
 
-	return port && is_valid_port(port);
+	return 0;
 }
 
 
@@ -9899,8 +9905,9 @@ static int is_absolute_uri_at_current_server(const char *uri,
 {
 	const char *domain;
 	size_t domain_len;
-	unsigned long port;
-	char *pend;
+	unsigned long port = 0;
+	int i;
+	char *hostend, *portbegin, *portend;
 
 	/* DNS is case insensitive, so use case insensitive string compare here */
 	domain = conn->ctx->config[AUTHENTICATION_DOMAIN];
@@ -9912,76 +9919,29 @@ static int is_absolute_uri_at_current_server(const char *uri,
 		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 {
+	for (i = 0; abs_uri_protocols[i].proto != NULL; i++) {
+		if (mg_strncasecmp(uri,
+		                   abs_uri_protocols[i].proto,
+		                   abs_uri_protocols[i].proto_len) == 0) {
+
+			hostend = strchr(uri + abs_uri_protocols[i].proto_len, '/');
+			if (!hostend) {
 				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;
-				}
+			portbegin = strchr(uri + abs_uri_protocols[i].proto_len, ':');
+			if (!portbegin) {
+				port = abs_uri_protocols[i].default_port;
 			} 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 != '/') {
+				port = strtoul(portbegin + 1, &portend, 10);
+				if ((portend != hostend) || !port || !is_valid_port(port)) {
 					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)) {
+	if (!port) {
+		/* port remains 0 if the protocol is not found */
 		return 0;
 	}