httpd shrink and logging update, part 4 of 7
authorDenis Vlasenko <vda.linux@googlemail.com>
Fri, 17 Aug 2007 19:19:42 +0000 (19:19 -0000)
committerDenis Vlasenko <vda.linux@googlemail.com>
Fri, 17 Aug 2007 19:19:42 +0000 (19:19 -0000)
   text    data     bss     dec     hex filename
   9836       0       0    9836    266c busybox.t1/networking/httpd.o.orig
   9724       0       0    9724    25fc busybox.t2/networking/httpd.o
   9657       0       0    9657    25b9 busybox.t3/networking/httpd.o
   9342       0       0    9342    247e busybox.t4/networking/httpd.o
   9342       0       0    9342    247e busybox.t5/networking/httpd.o
   9262       0       0    9262    242e busybox.t6/networking/httpd.o
   9283       0       0    9283    2443 busybox.t7/networking/httpd.o
   9334       0       0    9334    2476 busybox.t8/networking/httpd.o

networking/httpd.c

index 35aa492d01820ac6b7a6d11a3a832c1cf6ed6994..69d994a47991d0f3bec129ac4a9f77a2a540c4a9 100644 (file)
@@ -1506,7 +1506,7 @@ static int checkPerm(const char *path, const char *request)
                        }
                        /* unauthorized */
                }
-       }   /* for */
+       } /* for */
 
        return prev == NULL;
 }
@@ -1542,7 +1542,6 @@ static void handle_incoming_and_exit(void)
        char *content_type = 0;
 #endif
        struct sigaction sa;
-
 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH
        int credentials = -1;  /* if not required this is Ok */
 #endif
@@ -1552,229 +1551,226 @@ static void handle_incoming_and_exit(void)
        sa.sa_flags = 0; /* no SA_RESTART */
        sigaction(SIGALRM, &sa, NULL);
 
-       /* It's not a real loop (it ends with while(0)).
-        * Break from this "loop" jumps to exit(0) */
-       do {
-               alarm(TIMEOUT);
-               if (!get_line())
-                       _exit(0);  /* EOF or error or empty line */
+       alarm(TIMEOUT);
+       if (!get_line())
+               _exit(0);  /* EOF or error or empty line */
 
-               purl = strpbrk(iobuf, " \t");
-               if (purl == NULL) {
-                       send_headers_and_exit(HTTP_BAD_REQUEST);
-               }
-               *purl = '\0';
+       purl = strpbrk(iobuf, " \t");
+       if (purl == NULL) {
+               send_headers_and_exit(HTTP_BAD_REQUEST);
+       }
+       *purl = '\0';
 #if ENABLE_FEATURE_HTTPD_CGI
+       if (strcasecmp(iobuf, prequest) != 0) {
+               prequest = "POST";
                if (strcasecmp(iobuf, prequest) != 0) {
-                       prequest = "POST";
-                       if (strcasecmp(iobuf, prequest) != 0) {
-                               send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
-                       }
-               }
-#else
-               if (strcasecmp(iobuf, request_GET) != 0) {
                        send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
                }
+       }
+#else
+       if (strcasecmp(iobuf, request_GET) != 0) {
+               send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
+       }
 #endif
-               *purl = ' ';
-               count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &blank);
+       *purl = ' ';
+       count = sscanf(purl, " %[^ ] HTTP/%d.%*d", iobuf, &blank);
 
-               if (count < 1 || iobuf[0] != '/') {
-                       /* Garbled request/URL */
-                       send_headers_and_exit(HTTP_BAD_REQUEST);
-               }
-               url = alloca(strlen(iobuf) + sizeof("/index.html"));
-               if (url == NULL) {
-                       send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
-               }
-               strcpy(url, iobuf);
-               /* extract url args if present */
-               test = strchr(url, '?');
-               g_query = NULL;
-               if (test) {
-                       *test++ = '\0';
-                       g_query = test;
-               }
+       if (count < 1 || iobuf[0] != '/') {
+               /* Garbled request/URL */
+               send_headers_and_exit(HTTP_BAD_REQUEST);
+       }
+       url = alloca(strlen(iobuf) + sizeof("/index.html"));
+       if (url == NULL) {
+               send_headers_and_exit(HTTP_INTERNAL_SERVER_ERROR);
+       }
+       strcpy(url, iobuf);
+       /* extract url args if present */
+       test = strchr(url, '?');
+       g_query = NULL;
+       if (test) {
+               *test++ = '\0';
+               g_query = test;
+       }
 
-               test = decodeString(url, 0);
-               if (test == NULL)
-                       send_headers_and_exit(HTTP_BAD_REQUEST);
-               if (test == url + 1) {
-                       /* '/' or NUL is encoded */
-                       send_headers_and_exit(HTTP_NOT_FOUND);
-               }
+       test = decodeString(url, 0);
+       if (test == NULL)
+               send_headers_and_exit(HTTP_BAD_REQUEST);
+       if (test == url + 1) {
+               /* '/' or NUL is encoded */
+               send_headers_and_exit(HTTP_NOT_FOUND);
+       }
 
-               /* algorithm stolen from libbb bb_simplify_path(),
-                * but don't strdup and reducing trailing slash and protect out root */
-               purl = test = url;
-               do {
-                       if (*purl == '/') {
-                               /* skip duplicate (or initial) slash */
-                               if (*test == '/') {
+       /* algorithm stolen from libbb bb_simplify_path(),
+        * but don't strdup and reducing trailing slash and protect out root */
+       purl = test = url;
+       do {
+               if (*purl == '/') {
+                       /* skip duplicate (or initial) slash */
+                       if (*test == '/') {
+                               continue;
+                       }
+                       if (*test == '.') {
+                               /* skip extra '.' */
+                               if (test[1] == '/' || !test[1]) {
                                        continue;
                                }
-                               if (*test == '.') {
-                                       /* skip extra '.' */
-                                       if (test[1] == '/' || !test[1]) {
-                                               continue;
-                                       }
-                                       /* '..': be careful */
-                                       if (test[1] == '.' && (test[2] == '/' || !test[2])) {
-                                               ++test;
-                                               if (purl == url) {
-                                                       /* protect root */
-                                                       send_headers_and_exit(HTTP_BAD_REQUEST);
-                                               }
-                                               while (*--purl != '/') /* omit previous dir */;
-                                                       continue;
+                               /* '..': be careful */
+                               if (test[1] == '.' && (test[2] == '/' || !test[2])) {
+                                       ++test;
+                                       if (purl == url) {
+                                               /* protect root */
+                                               send_headers_and_exit(HTTP_BAD_REQUEST);
                                        }
+                                       while (*--purl != '/') /* omit previous dir */;
+                                               continue;
                                }
                        }
-                       *++purl = *test;
-               } while (*++test);
-               *++purl = '\0';       /* so keep last character */
-               test = purl;          /* end ptr */
-
-               /* If URL is directory, adding '/' */
-               if (test[-1] != '/') {
-                       if (is_directory(url + 1, 1, &sb)) {
-                               found_moved_temporarily = url;
-                       }
                }
-               if (verbose > 1)
-                       bb_error_msg("url:%s", url);
-
-               test = url;
-               ip_allowed = checkPermIP();
-               while (ip_allowed && (test = strchr(test + 1, '/')) != NULL) {
-                       /* have path1/path2 */
-                       *test = '\0';
-                       if (is_directory(url + 1, 1, &sb)) {
-                               /* may be having subdir config */
-                               parse_conf(url + 1, SUBDIR_PARSE);
-                               ip_allowed = checkPermIP();
-                       }
-                       *test = '/';
+               *++purl = *test;
+       } while (*++test);
+       *++purl = '\0';       /* so keep last character */
+       test = purl;          /* end ptr */
+
+       /* If URL is directory, adding '/' */
+       if (test[-1] != '/') {
+               if (is_directory(url + 1, 1, &sb)) {
+                       found_moved_temporarily = url;
+               }
+       }
+
+       if (verbose > 1)
+               bb_error_msg("url:%s", url);
+
+       test = url;
+       ip_allowed = checkPermIP();
+       while (ip_allowed && (test = strchr(test + 1, '/')) != NULL) {
+               /* have path1/path2 */
+               *test = '\0';
+               if (is_directory(url + 1, 1, &sb)) {
+                       /* may be having subdir config */
+                       parse_conf(url + 1, SUBDIR_PARSE);
+                       ip_allowed = checkPermIP();
                }
-               if (blank >= 0) {
-                       /* read until blank line for HTTP version specified, else parse immediate */
-                       while (1) {
-                               alarm(TIMEOUT);
-                               if (!get_line())
-                                       break; /* EOF or error or empty line */
-
-                               if (DEBUG)
-                                       bb_error_msg("header: '%s'", iobuf);
+               *test = '/';
+       }
+       if (blank >= 0) {
+               /* read until blank line for HTTP version specified, else parse immediate */
+               while (1) {
+                       alarm(TIMEOUT);
+                       if (!get_line())
+                               break; /* EOF or error or empty line */
+
+                       if (DEBUG)
+                               bb_error_msg("header: '%s'", iobuf);
 #if ENABLE_FEATURE_HTTPD_CGI
-                               /* try and do our best to parse more lines */
-                               if ((STRNCASECMP(iobuf, "Content-length:") == 0)) {
-                                       /* extra read only for POST */
-                                       if (prequest != request_GET) {
-                                               test = iobuf + sizeof("Content-length:") - 1;
-                                               if (!test[0])
-                                                       _exit(0);
-                                               errno = 0;
-                                               /* not using strtoul: it ignores leading minus! */
-                                               length = strtol(test, &test, 10);
-                                               /* length is "ulong", but we need to pass it to int later */
-                                               /* so we check for negative or too large values in one go: */
-                                               /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */
-                                               if (test[0] || errno || length > INT_MAX)
-                                                       _exit(0);
-                                       }
-                               } else if (STRNCASECMP(iobuf, "Cookie:") == 0) {
-                                       cookie = strdup(skip_whitespace(iobuf + sizeof("Cookie:")-1));
-                               } else if (STRNCASECMP(iobuf, "Content-Type:") == 0) {
-                                       content_type = strdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1));
-                               } else if (STRNCASECMP(iobuf, "Referer:") == 0) {
-                                       referer = strdup(skip_whitespace(iobuf + sizeof("Referer:")-1));
-                               } else if (STRNCASECMP(iobuf, "User-Agent:") == 0) {
-                                       user_agent = strdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1));
+                       /* try and do our best to parse more lines */
+                       if ((STRNCASECMP(iobuf, "Content-length:") == 0)) {
+                               /* extra read only for POST */
+                               if (prequest != request_GET) {
+                                       test = iobuf + sizeof("Content-length:") - 1;
+                                       if (!test[0])
+                                               _exit(0);
+                                       errno = 0;
+                                       /* not using strtoul: it ignores leading minus! */
+                                       length = strtol(test, &test, 10);
+                                       /* length is "ulong", but we need to pass it to int later */
+                                       /* so we check for negative or too large values in one go: */
+                                       /* (long -> ulong conv caused negatives to be seen as > INT_MAX) */
+                                       if (test[0] || errno || length > INT_MAX)
+                                               _exit(0);
                                }
+                       } else if (STRNCASECMP(iobuf, "Cookie:") == 0) {
+                               cookie = strdup(skip_whitespace(iobuf + sizeof("Cookie:")-1));
+                       } else if (STRNCASECMP(iobuf, "Content-Type:") == 0) {
+                               content_type = strdup(skip_whitespace(iobuf + sizeof("Content-Type:")-1));
+                       } else if (STRNCASECMP(iobuf, "Referer:") == 0) {
+                               referer = strdup(skip_whitespace(iobuf + sizeof("Referer:")-1));
+                       } else if (STRNCASECMP(iobuf, "User-Agent:") == 0) {
+                               user_agent = strdup(skip_whitespace(iobuf + sizeof("User-Agent:")-1));
+                       }
 #endif
 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH
-                               if (STRNCASECMP(iobuf, "Authorization:") == 0) {
-                                       /* We only allow Basic credentials.
-                                        * It shows up as "Authorization: Basic <userid:password>" where
-                                        * the userid:password is base64 encoded.
-                                        */
-                                       test = skip_whitespace(iobuf + sizeof("Authorization:")-1);
-                                       if (STRNCASECMP(test, "Basic") != 0)
-                                               continue;
-                                       test += sizeof("Basic")-1;
-                                       /* decodeBase64() skips whitespace itself */
-                                       decodeBase64(test);
-                                       credentials = checkPerm(url, test);
-                               }
+                       if (STRNCASECMP(iobuf, "Authorization:") == 0) {
+                               /* We only allow Basic credentials.
+                                * It shows up as "Authorization: Basic <userid:password>" where
+                                * the userid:password is base64 encoded.
+                                */
+                               test = skip_whitespace(iobuf + sizeof("Authorization:")-1);
+                               if (STRNCASECMP(test, "Basic") != 0)
+                                       continue;
+                               test += sizeof("Basic")-1;
+                               /* decodeBase64() skips whitespace itself */
+                               decodeBase64(test);
+                               credentials = checkPerm(url, test);
+                       }
 #endif          /* FEATURE_HTTPD_BASIC_AUTH */
-                       } /* while extra header reading */
-               }
-               alarm(0);
+               } /* while extra header reading */
+       }
 
-               if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) {
-                       /* protect listing [/path]/httpd_conf or IP deny */
-                       send_headers_and_exit(HTTP_FORBIDDEN);
-               }
+       alarm(0);
+
+       if (strcmp(bb_basename(url), httpd_conf) == 0 || ip_allowed == 0) {
+               /* protect listing [/path]/httpd_conf or IP deny */
+               send_headers_and_exit(HTTP_FORBIDDEN);
+       }
 
 #if ENABLE_FEATURE_HTTPD_BASIC_AUTH
-               if (credentials <= 0 && checkPerm(url, ":") == 0) {
-                       send_headers_and_exit(HTTP_UNAUTHORIZED);
-               }
+       if (credentials <= 0 && checkPerm(url, ":") == 0) {
+               send_headers_and_exit(HTTP_UNAUTHORIZED);
+       }
 #endif
 
-               if (found_moved_temporarily) {
-                       send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
-               }
+       if (found_moved_temporarily) {
+               send_headers_and_exit(HTTP_MOVED_TEMPORARILY);
+       }
 
-               test = url + 1;      /* skip first '/' */
+       test = url + 1;      /* skip first '/' */
 
 #if ENABLE_FEATURE_HTTPD_CGI
-               if (strncmp(test, "cgi-bin", 7) == 0) {
-                       if (test[7] == '/' && test[8] == '\0') {
-                               /* protect listing cgi-bin/ */
-                               send_headers_and_exit(HTTP_FORBIDDEN);
-                       }
-                       send_cgi_and_exit(url, prequest, length, cookie, content_type);
+       if (strncmp(test, "cgi-bin", 7) == 0) {
+               if (test[7] == '/' && test[8] == '\0') {
+                       /* protect listing cgi-bin/ */
+                       send_headers_and_exit(HTTP_FORBIDDEN);
                }
+               send_cgi_and_exit(url, prequest, length, cookie, content_type);
+       }
 #if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
-               {
-                       char *suffix = strrchr(test, '.');
-                       if (suffix) {
-                               Htaccess *cur;
-                               for (cur = script_i; cur; cur = cur->next) {
-                                       if (strcmp(cur->before_colon + 1, suffix) == 0) {
-                                               send_cgi_and_exit(url, prequest, length, cookie, content_type);
-                                       }
+       {
+               char *suffix = strrchr(test, '.');
+               if (suffix) {
+                       Htaccess *cur;
+                       for (cur = script_i; cur; cur = cur->next) {
+                               if (strcmp(cur->before_colon + 1, suffix) == 0) {
+                                       send_cgi_and_exit(url, prequest, length, cookie, content_type);
                                }
                        }
                }
+       }
 #endif
-               if (prequest != request_GET) {
-                       send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
-               }
+       if (prequest != request_GET) {
+               send_headers_and_exit(HTTP_NOT_IMPLEMENTED);
+       }
 #endif  /* FEATURE_HTTPD_CGI */
-               if (purl[-1] == '/')
-                       strcpy(purl, "index.html");
-               if (stat(test, &sb) == 0) {
-                       /* It's a dir URL and there is index.html */
-                       ContentLength = sb.st_size;
-                       last_mod = sb.st_mtime;
-               }
+       if (purl[-1] == '/')
+               strcpy(purl, "index.html");
+       if (stat(test, &sb) == 0) {
+               /* It's a dir URL and there is index.html */
+               ContentLength = sb.st_size;
+               last_mod = sb.st_mtime;
+       }
 #if ENABLE_FEATURE_HTTPD_CGI
-               else if (purl[-1] == '/') {
-                       /* It's a dir URL and there is no index.html
-                        * Try cgi-bin/index.cgi */
-                       if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) {
-                               purl[0] = '\0';
-                               g_query = url;
-                               send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type);
-                       }
+       else if (purl[-1] == '/') {
+               /* It's a dir URL and there is no index.html
+                * Try cgi-bin/index.cgi */
+               if (access("/cgi-bin/index.cgi"+1, X_OK) == 0) {
+                       purl[0] = '\0';
+                       g_query = url;
+                       send_cgi_and_exit("/cgi-bin/index.cgi", prequest, length, cookie, content_type);
                }
+       }
 #endif  /* FEATURE_HTTPD_CGI */
-               send_file_and_exit(test);
-       } while (0);
 
-       _exit(0);
+       send_file_and_exit(test);
 
 #if 0 /* Is this needed? Why? */
        if (DEBUG)
@@ -1817,7 +1813,6 @@ static void handle_incoming_and_exit(void)
 static void mini_httpd(int server) ATTRIBUTE_NORETURN;
 static void mini_httpd(int server)
 {
-       /* copy the ports we are watching to the readfd set */
        while (1) {
                int n;
                len_and_sockaddr fromAddr;