aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDenis Vlasenko <vda.linux@googlemail.com>2006-11-21 00:07:31 +0000
committerDenis Vlasenko <vda.linux@googlemail.com>2006-11-21 00:07:31 +0000
commita3ee69fa6ccf83c9f3506b6ccbdc9e253df77077 (patch)
treeb13c9b970172068f8c4589d8b343304f283d83fa
parent0bb993f39b98c4673588a4ace458feda1809fe57 (diff)
downloadbusybox-w32-a3ee69fa6ccf83c9f3506b6ccbdc9e253df77077.tar.gz
busybox-w32-a3ee69fa6ccf83c9f3506b6ccbdc9e253df77077.tar.bz2
busybox-w32-a3ee69fa6ccf83c9f3506b6ccbdc9e253df77077.zip
httpd: get rid of big, useless blocks (deindent,
bring code under 80 columns)
-rw-r--r--networking/httpd.c396
1 files changed, 197 insertions, 199 deletions
diff --git a/networking/httpd.c b/networking/httpd.c
index 71792862e..40f37ba07 100644
--- a/networking/httpd.c
+++ b/networking/httpd.c
@@ -963,212 +963,211 @@ static int sendCgi(const char *url,
963 int inFd; 963 int inFd;
964 int outFd; 964 int outFd;
965 int firstLine = 1; 965 int firstLine = 1;
966 int status;
967 size_t post_readed_size, post_readed_idx;
966 968
967 if (pipe(fromCgi) != 0) 969 if (pipe(fromCgi) != 0)
968 return 0; 970 return 0;
969 if (pipe(toCgi) != 0) 971 if (pipe(toCgi) != 0)
970 return 0; 972 return 0;
973
971 pid = fork(); 974 pid = fork();
972 if (pid < 0) 975 if (pid < 0)
973 return 0; 976 return 0;
977
978 if (!pid) {
979 /* child process */
980 char *script;
981 char *purl = strdup(url);
982 char realpath_buff[MAXPATHLEN];
983
984 if (purl == NULL)
985 _exit(242);
974 986
975 do { 987 inFd = toCgi[0];
976 if (!pid) { 988 outFd = fromCgi[1];
977 /* child process */ 989
978 char *script; 990 dup2(inFd, 0); // replace stdin with the pipe
979 char *purl = strdup(url); 991 dup2(outFd, 1); // replace stdout with the pipe
980 char realpath_buff[MAXPATHLEN]; 992 if (!DEBUG)
981 993 dup2(outFd, 2); // replace stderr with the pipe
982 if (purl == NULL) 994
983 _exit(242); 995 close(toCgi[0]);
984 996 close(toCgi[1]);
985 inFd = toCgi[0]; 997 close(fromCgi[0]);
986 outFd = fromCgi[1]; 998 close(fromCgi[1]);
987 999
988 dup2(inFd, 0); // replace stdin with the pipe 1000 close(config->accepted_socket);
989 dup2(outFd, 1); // replace stdout with the pipe 1001 close(config->server_socket);
990 if (!DEBUG) 1002
991 dup2(outFd, 2); // replace stderr with the pipe 1003 /*
992 1004 * Find PATH_INFO.
993 close(toCgi[0]); 1005 */
994 close(toCgi[1]); 1006 script = purl;
995 close(fromCgi[0]); 1007 while ((script = strchr(script + 1, '/')) != NULL) {
996 close(fromCgi[1]); 1008 /* have script.cgi/PATH_INFO or dirs/script.cgi[/PATH_INFO] */
997 1009 struct stat sb;
998 close(config->accepted_socket); 1010
999 close(config->server_socket); 1011 *script = '\0';
1000 1012 if (is_directory(purl + 1, 1, &sb) == 0) {
1001 /* 1013 /* not directory, found script.cgi/PATH_INFO */
1002 * Find PATH_INFO. 1014 *script = '/';
1003 */ 1015 break;
1004 script = purl;
1005 while ((script = strchr(script + 1, '/')) != NULL) {
1006 /* have script.cgi/PATH_INFO or dirs/script.cgi[/PATH_INFO] */
1007 struct stat sb;
1008
1009 *script = '\0';
1010 if (is_directory(purl + 1, 1, &sb) == 0) {
1011 /* not directory, found script.cgi/PATH_INFO */
1012 *script = '/';
1013 break;
1014 }
1015 *script = '/'; /* is directory, find next '/' */
1016 }
1017 setenv1("PATH_INFO", script); /* set /PATH_INFO or "" */
1018 /* setenv1("PATH", getenv("PATH")); redundant */
1019 setenv1("REQUEST_METHOD", request);
1020 if (config->query) {
1021 char *uri = alloca(strlen(purl) + 2 + strlen(config->query));
1022 if (uri)
1023 sprintf(uri, "%s?%s", purl, config->query);
1024 setenv1("REQUEST_URI", uri);
1025 } else {
1026 setenv1("REQUEST_URI", purl);
1027 } 1016 }
1028 if (script != NULL) 1017 *script = '/'; /* is directory, find next '/' */
1029 *script = '\0'; /* reduce /PATH_INFO */ 1018 }
1030 /* SCRIPT_FILENAME required by PHP in CGI mode */ 1019 setenv1("PATH_INFO", script); /* set /PATH_INFO or "" */
1031 if (!realpath(purl + 1, realpath_buff)) 1020 /* setenv1("PATH", getenv("PATH")); redundant */
1032 goto error_execing_cgi; 1021 setenv1("REQUEST_METHOD", request);
1033 setenv1("SCRIPT_FILENAME", realpath_buff); 1022 if (config->query) {
1034 /* set SCRIPT_NAME as full path: /cgi-bin/dirs/script.cgi */ 1023 char *uri = alloca(strlen(purl) + 2 + strlen(config->query));
1035 setenv1("SCRIPT_NAME", purl); 1024 if (uri)
1036 setenv1("QUERY_STRING", config->query); 1025 sprintf(uri, "%s?%s", purl, config->query);
1037 setenv1("SERVER_SOFTWARE", httpdVersion); 1026 setenv1("REQUEST_URI", uri);
1038 putenv("SERVER_PROTOCOL=HTTP/1.0"); 1027 } else {
1039 putenv("GATEWAY_INTERFACE=CGI/1.1"); 1028 setenv1("REQUEST_URI", purl);
1040 setenv1("REMOTE_ADDR", config->rmt_ip_str); 1029 }
1030 if (script != NULL)
1031 *script = '\0'; /* reduce /PATH_INFO */
1032 /* SCRIPT_FILENAME required by PHP in CGI mode */
1033 if (!realpath(purl + 1, realpath_buff))
1034 goto error_execing_cgi;
1035 setenv1("SCRIPT_FILENAME", realpath_buff);
1036 /* set SCRIPT_NAME as full path: /cgi-bin/dirs/script.cgi */
1037 setenv1("SCRIPT_NAME", purl);
1038 setenv1("QUERY_STRING", config->query);
1039 setenv1("SERVER_SOFTWARE", httpdVersion);
1040 putenv("SERVER_PROTOCOL=HTTP/1.0");
1041 putenv("GATEWAY_INTERFACE=CGI/1.1");
1042 setenv1("REMOTE_ADDR", config->rmt_ip_str);
1041#if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV 1043#if ENABLE_FEATURE_HTTPD_SET_REMOTE_PORT_TO_ENV
1042 setenv_long("REMOTE_PORT", config->port); 1044 setenv_long("REMOTE_PORT", config->port);
1043#endif 1045#endif
1044 if (bodyLen) 1046 if (bodyLen)
1045 setenv_long("CONTENT_LENGTH", bodyLen); 1047 setenv_long("CONTENT_LENGTH", bodyLen);
1046 if (cookie) 1048 if (cookie)
1047 setenv1("HTTP_COOKIE", cookie); 1049 setenv1("HTTP_COOKIE", cookie);
1048 if (content_type) 1050 if (content_type)
1049 setenv1("CONTENT_TYPE", content_type); 1051 setenv1("CONTENT_TYPE", content_type);
1050#if ENABLE_FEATURE_HTTPD_BASIC_AUTH 1052#if ENABLE_FEATURE_HTTPD_BASIC_AUTH
1051 if (config->remoteuser) { 1053 if (config->remoteuser) {
1052 setenv1("REMOTE_USER", config->remoteuser); 1054 setenv1("REMOTE_USER", config->remoteuser);
1053 putenv("AUTH_TYPE=Basic"); 1055 putenv("AUTH_TYPE=Basic");
1054 } 1056 }
1055#endif 1057#endif
1056 if (config->referer) 1058 if (config->referer)
1057 setenv1("HTTP_REFERER", config->referer); 1059 setenv1("HTTP_REFERER", config->referer);
1058 1060
1059 /* set execve argp[0] without path */ 1061 /* set execve argp[0] without path */
1060 argp[0] = strrchr(purl, '/') + 1; 1062 argp[0] = strrchr(purl, '/') + 1;
1061 /* but script argp[0] must have absolute path and chdiring to this */ 1063 /* but script argp[0] must have absolute path and chdiring to this */
1062 script = strrchr(realpath_buff, '/'); 1064 script = strrchr(realpath_buff, '/');
1063 if (!script) 1065 if (!script)
1064 goto error_execing_cgi; 1066 goto error_execing_cgi;
1065 *script = '\0'; 1067 *script = '\0';
1066 if (chdir(realpath_buff) == 0) { 1068 if (chdir(realpath_buff) == 0) {
1067 // now run the program. If it fails, 1069 // now run the program. If it fails,
1068 // use _exit() so no destructors 1070 // use _exit() so no destructors
1069 // get called and make a mess. 1071 // get called and make a mess.
1070#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR 1072#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
1071 char *interpr = NULL; 1073 char *interpr = NULL;
1072 char *suffix = strrchr(purl, '.'); 1074 char *suffix = strrchr(purl, '.');
1073 1075
1074 if (suffix) { 1076 if (suffix) {
1075 Htaccess *cur; 1077 Htaccess *cur;
1076 for (cur = config->script_i; cur; cur = cur->next) { 1078 for (cur = config->script_i; cur; cur = cur->next) {
1077 if (strcmp(cur->before_colon + 1, suffix) == 0) { 1079 if (strcmp(cur->before_colon + 1, suffix) == 0) {
1078 interpr = cur->after_colon; 1080 interpr = cur->after_colon;
1079 break; 1081 break;
1080 }
1081 } 1082 }
1082 } 1083 }
1084 }
1083#endif 1085#endif
1084 *script = '/'; 1086 *script = '/';
1085#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR 1087#if ENABLE_FEATURE_HTTPD_CONFIG_WITH_SCRIPT_INTERPR
1086 if (interpr) 1088 if (interpr)
1087 execv(interpr, argp); 1089 execv(interpr, argp);
1088 else 1090 else
1089#endif 1091#endif
1090 execv(realpath_buff, argp); 1092 execv(realpath_buff, argp);
1091 } 1093 }
1092 error_execing_cgi: 1094 error_execing_cgi:
1093 /* send to stdout (even if we are not from inetd) */ 1095 /* send to stdout (even if we are not from inetd) */
1094 config->accepted_socket = 1; 1096 config->accepted_socket = 1;
1095 sendHeaders(HTTP_NOT_FOUND); 1097 sendHeaders(HTTP_NOT_FOUND);
1096 _exit(242); 1098 _exit(242);
1097 } /* end child */ 1099 } /* end child */
1098 1100
1099 } while (0); 1101 /* parent process */
1100 1102
1101 if (pid > 0) { 1103 post_readed_size = 0;
1102 /* parent process */ 1104 post_readed_idx = 0;
1103 int status; 1105 inFd = fromCgi[0];
1104 size_t post_readed_size = 0, post_readed_idx = 0; 1106 outFd = toCgi[1];
1107 close(fromCgi[1]);
1108 close(toCgi[0]);
1109 signal(SIGPIPE, SIG_IGN);
1105 1110
1106 inFd = fromCgi[0]; 1111 while (1) {
1107 outFd = toCgi[1]; 1112 fd_set readSet;
1108 close(fromCgi[1]); 1113 fd_set writeSet;
1109 close(toCgi[0]); 1114 char wbuf[128];
1110 signal(SIGPIPE, SIG_IGN); 1115 int nfound;
1111 1116 int count;
1112 while (1) { 1117
1113 fd_set readSet; 1118 FD_ZERO(&readSet);
1114 fd_set writeSet; 1119 FD_ZERO(&writeSet);
1115 char wbuf[128]; 1120 FD_SET(inFd, &readSet);
1116 int nfound; 1121 if (bodyLen > 0 || post_readed_size > 0) {
1117 int count; 1122 FD_SET(outFd, &writeSet);
1118 1123 nfound = outFd > inFd ? outFd : inFd;
1119 FD_ZERO(&readSet); 1124 if (post_readed_size == 0) {
1120 FD_ZERO(&writeSet); 1125 FD_SET(config->accepted_socket, &readSet);
1121 FD_SET(inFd, &readSet); 1126 if (nfound < config->accepted_socket)
1122 if (bodyLen > 0 || post_readed_size > 0) { 1127 nfound = config->accepted_socket;
1123 FD_SET(outFd, &writeSet);
1124 nfound = outFd > inFd ? outFd : inFd;
1125 if (post_readed_size == 0) {
1126 FD_SET(config->accepted_socket, &readSet);
1127 if (nfound < config->accepted_socket)
1128 nfound = config->accepted_socket;
1129 }
1130 /* Now wait on the set of sockets! */
1131 nfound = select(nfound + 1, &readSet, &writeSet, 0, NULL);
1132 } else {
1133 if (!bodyLen) {
1134 close(outFd);
1135 bodyLen = -1;
1136 }
1137 nfound = select(inFd + 1, &readSet, 0, 0, NULL);
1138 } 1128 }
1129 /* Now wait on the set of sockets! */
1130 nfound = select(nfound + 1, &readSet, &writeSet, 0, NULL);
1131 } else {
1132 if (!bodyLen) {
1133 close(outFd);
1134 bodyLen = -1;
1135 }
1136 nfound = select(inFd + 1, &readSet, 0, 0, NULL);
1137 }
1139 1138
1140 if (nfound <= 0) { 1139 if (nfound <= 0) {
1141 if (waitpid(pid, &status, WNOHANG) > 0) { 1140 if (waitpid(pid, &status, WNOHANG) > 0) {
1142 close(inFd); 1141 close(inFd);
1143 if (DEBUG && WIFEXITED(status)) 1142 if (DEBUG && WIFEXITED(status))
1144 bb_error_msg("piped has exited with status=%d", WEXITSTATUS(status)); 1143 bb_error_msg("piped has exited with status=%d", WEXITSTATUS(status));
1145 if (DEBUG && WIFSIGNALED(status)) 1144 if (DEBUG && WIFSIGNALED(status))
1146 bb_error_msg("piped has exited with signal=%d", WTERMSIG(status)); 1145 bb_error_msg("piped has exited with signal=%d", WTERMSIG(status));
1147 break; 1146 break;
1148 } 1147 }
1149 } else if (post_readed_size > 0 && FD_ISSET(outFd, &writeSet)) { 1148 } else if (post_readed_size > 0 && FD_ISSET(outFd, &writeSet)) {
1150 count = full_write(outFd, wbuf + post_readed_idx, post_readed_size); 1149 count = full_write(outFd, wbuf + post_readed_idx, post_readed_size);
1151 if (count > 0) { 1150 if (count > 0) {
1152 post_readed_size -= count; 1151 post_readed_size -= count;
1153 post_readed_idx += count; 1152 post_readed_idx += count;
1154 if (post_readed_size == 0) 1153 if (post_readed_size == 0)
1155 post_readed_idx = 0; 1154 post_readed_idx = 0;
1156 } else { 1155 } else {
1157 post_readed_size = post_readed_idx = bodyLen = 0; /* broken pipe to CGI */ 1156 post_readed_size = post_readed_idx = bodyLen = 0; /* broken pipe to CGI */
1158 }
1159 } else if (bodyLen > 0 && post_readed_size == 0 && FD_ISSET(config->accepted_socket, &readSet)) {
1160 count = bodyLen > (int)sizeof(wbuf) ? (int)sizeof(wbuf) : bodyLen;
1161 count = safe_read(config->accepted_socket, wbuf, count);
1162 if (count > 0) {
1163 post_readed_size += count;
1164 bodyLen -= count;
1165 } else {
1166 bodyLen = 0; /* closed */
1167 }
1168 } 1157 }
1169 if (FD_ISSET(inFd, &readSet)) { 1158 } else if (bodyLen > 0 && post_readed_size == 0 && FD_ISSET(config->accepted_socket, &readSet)) {
1170 int s = config->accepted_socket; 1159 count = bodyLen > (int)sizeof(wbuf) ? (int)sizeof(wbuf) : bodyLen;
1171 char *rbuf = config->buf; 1160 count = safe_read(config->accepted_socket, wbuf, count);
1161 if (count > 0) {
1162 post_readed_size += count;
1163 bodyLen -= count;
1164 } else {
1165 bodyLen = 0; /* closed */
1166 }
1167 }
1168 if (FD_ISSET(inFd, &readSet)) {
1169 int s = config->accepted_socket;
1170 char *rbuf = config->buf;
1172 1171
1173#ifndef PIPE_BUF 1172#ifndef PIPE_BUF
1174# define PIPESIZE 4096 /* amount of buffering in a pipe */ 1173# define PIPESIZE 4096 /* amount of buffering in a pipe */
@@ -1179,28 +1178,27 @@ static int sendCgi(const char *url,
1179# error "PIPESIZE >= MAX_MEMORY_BUFF" 1178# error "PIPESIZE >= MAX_MEMORY_BUFF"
1180#endif 1179#endif
1181 1180
1182 // There is something to read 1181 // There is something to read
1183 count = safe_read(inFd, rbuf, PIPESIZE); 1182 count = safe_read(inFd, rbuf, PIPESIZE);
1184 if (count == 0) 1183 if (count == 0)
1185 break; /* closed */ 1184 break; /* closed */
1186 if (count > 0) { 1185 if (count > 0) {
1187 if (firstLine) { 1186 if (firstLine) {
1188 rbuf[count] = 0; 1187 rbuf[count] = 0;
1189 /* check to see if the user script added headers */ 1188 /* check to see if the user script added headers */
1190 if (strncmp(rbuf, "HTTP/1.0 200 OK\r\n", 4) != 0) { 1189 if (strncmp(rbuf, "HTTP/1.0 200 OK\r\n", 4) != 0) {
1191 full_write(s, "HTTP/1.0 200 OK\r\n", 17); 1190 full_write(s, "HTTP/1.0 200 OK\r\n", 17);
1192 }
1193 if (strstr(rbuf, "ontent-") == 0) {
1194 full_write(s, "Content-type: text/plain\r\n\r\n", 28);
1195 }
1196 firstLine = 0;
1197 } 1191 }
1198 if (full_write(s, rbuf, count) != count) 1192 if (strstr(rbuf, "ontent-") == 0) {
1199 break; 1193 full_write(s, "Content-type: text/plain\r\n\r\n", 28);
1200 1194 }
1201 if (DEBUG) 1195 firstLine = 0;
1202 fprintf(stderr, "cgi read %d bytes\n", count);
1203 } 1196 }
1197 if (full_write(s, rbuf, count) != count)
1198 break;
1199
1200 if (DEBUG)
1201 fprintf(stderr, "cgi read %d bytes\n", count);
1204 } 1202 }
1205 } 1203 }
1206 } 1204 }