/* This is the same as serverSocketAccept except that it takes a maxsecs arg which is the maximum # of seconds to wait for a connection. If the time expires before a connection comes in, INVALID_SOCKET is returned. */ SOCKET serverSocketAccept(SERVERSOCKET ss, struct sockaddr_in *sa, socklen_t *salen, int maxsecs) { struct timeval tv; tv.tv_sec = maxsecs; tv.tv_usec = 0; fd_set rfds; FD_ZERO(&rfds); FD_SET(ss, &rfds); int r = select(ss + 1, &rfds, NULL, NULL, &tv); if(r) return serverSocketAccept(ss, sa, salen); return INVALID_SOCKET; }
int main(int argc, char **argv) { int err; parseArguments(argc, argv); if (nodaemon == 0) { err = daemonise(); if (err != 0) exit(1); err = writePidFile(pidFile); if (err != 0) exit(1); } err = signalisation(); if (err != 0) exit(1); serverSocket = openServerSocket(port); if (serverSocket == -1) exit(1); request_t req; response_t resp; output_t output; memset(&output, 0, sizeof(output_t)); while (serverSocket != -1) { memset(&req, 0, sizeof(request_t)); memset(&resp, 0, sizeof(response_t)); int client = serverSocketAccept(serverSocket); if (client == -1) continue; int r = parseRequest(client, &req, &resp); if (r != 0) { clientPrintf(client, "HTTP/1.1 %03d\r\n", resp.status); closeClient(client); continue; } if (1) { printf("path: %s\n", req.path); for (int i =0; i < req.num_args; i++) printf("arg[%d]: %s = %s\n", i, req.names[i], req.values[i]); } const char* cmdline = findCommand(req.path); if (cmdline == NULL) { log_warn("Daemon: Invalid path: '%s'\n", req.path); clientPrint(client, "HTTP/1.1 404\r\n"); closeClient(client); continue; } if (execute(&output, cmdline) != 0) { clientPrint(client, "HTTP/1.1 500\r\n"); // Internal server error closeClient(client); continue; } if ((output.count > 8) && (strncmp(output.buf, "HTTP/1.1", 8) == 0)) { clientWrite(client, output.buf, output.count); } else { clientPrintf(client, "HTTP/1.1 200\r\nContent-Length: %d\r\n\r\n", output.count); clientWrite(client, output.buf, output.count); } closeClient(client); output_clear(&output); if (req.path) free(req.path); } removePidFile(pidFile); return 0; }
int main(int argc, char **argv) { int err; server_init(); parse_arguments(argc, argv); log_set_file(logFile); if (nodaemon == 0) { err = daemonise(); if (err != 0) exit(1); err = writePidFile(pidFile); if (err != 0) exit(1); err = drop_privileges(); if (err != 0) exit(1); } err = signalisation(); if (err != 0) exit(1); serverSocket = openServerSocket(NULL, port); if (serverSocket == -1) exit(1); log_info("Server ready for connections"); request_t req; response_t resp; memset(&req, 0, sizeof(request_t)); memset(&resp, 0, sizeof(response_t)); while (serverSocket != -1) { int client = serverSocketAccept(serverSocket); if (client == -1) { continue; } int r = parseRequest(client, &req, &resp); if (r != 0) { clientPrintf(client, "HTTP/1.1 %03d\r\n", resp.status); closeClient(client); continue; } log_info("Request: %s", req.path); if (1) { list_t* l = req.args; while (l) { pair_t* p = (pair_t*) l->data; log_debug("args[]: %s = %s", p->name, p->value); l = l->next; } l = req.headers; while (l) { pair_t* p = (pair_t*) l->data; log_debug("headers[]: '%s': '%s'", p->name, p->value); l = l->next; } } server_handle_request(&req, &resp); // Debug printf if (resp.status != 0) { clientPrintf(client, "HTTP/1.1 %03d\r\n" "Content-Length: %d\r\n" "Content-Type: %s\r\n" "\r\n", resp.status, resp.length, resp.content_type); clientWrite(client, resp.body, resp.length); } else { log_err("main.c, request status == 0, request not handle!"); } closeClient(client); request_clear(&req); response_clear(&resp); } removePidFile(pidFile); return 0; }