#include #include #include #include #include #include #include "server.h" #include "httpStruct.h" #define BUFF_READ 1024 #define NUM_SUPPORTED_VERSIONS 2 static char supportedHTTPVersions[NUM_SUPPORTED_VERSIONS][16] = { "HTTP/1.1", "HTTP/1.0" }; int PrintLog(unsigned char *message) { time_t UTCTime; // Setting time in EPOC time(&UTCTime); struct tm *now = localtime(&UTCTime); if (!strcmp(WEB_ROOT_DIR, "/var/www/html/")) { FILE *fp; fp = fopen("/var/log/seaweb/log", "w"); fprintf(fp, "[Log] %02d/%02d/%d %02d:%02d:%02d - %s\n", (now->tm_mon + 1), now->tm_mday, (now->tm_year + 1900), now->tm_hour, now->tm_min, now->tm_sec, message); fclose(fp); } else { printf("[Log] %02d/%02d/%d %02d:%02d:%02d - %s\n", (now->tm_mon + 1), now->tm_mday, (now->tm_year + 1900), now->tm_hour, now->tm_min, now->tm_sec, message); } return 0; } int checkHTTPVersion(char *version) { int supported = -1; // Default fail state char testVer[16]; strcpy(testVer, version); for (int i = 0; i < NUM_SUPPORTED_VERSIONS; i++) { if (!strcmp(testVer, supportedHTTPVersions[i])) { supported = 0; } } return supported; } char *php_cgi(char *sPath, struct HTTPRequest *r) { int phpPipe[2]; char *buf = NULL; size_t bufLen = 1024; buf = malloc(bufLen); pipe(phpPipe); pid_t pid; int status = 0; pid = fork(); if (pid == 0) { // Child fork char script[500]; char *queryString = NULL; close(phpPipe[0]); dup2(phpPipe[1], STDOUT_FILENO); strcpy(script, "SCRIPT_FILENAME="); strcat(script, WEB_ROOT_DIR); strcat(script, sPath); putenv("GATEWAY_INTERFACE=CGI/1.1"); putenv(script); putenv("REDIRECT_STATUS=true"); putenv("SERVER_PROTOCOL=HTTP/1.1"); putenv("REMOTE_HOST=127.0.0.1"); if (!strcmp(r->requestType, "POST")) { putenv("REQUEST_METHOD=POST"); char conLenString[256]; sprintf(conLenString, "CONTENT_LENGTH=%zu", r->requestBodyLen); putenv(conLenString); putenv("CONTENT_TYPE=application/x-www-form-urlencoded"); queryString = malloc(r->requestBodyLen + 24); sprintf(queryString, "QUERY_STRING=%s", r->requestBody); putenv(queryString); // Starting fork to pipe stdin into php-cgi int phpPipe2[2]; pipe(phpPipe2); pid_t pid2; pid2 = fork(); if (pid2 == 0) { // Child fork close(phpPipe2[0]); dup2(phpPipe2[1], STDOUT_FILENO); printf("%s", r->requestBody); close(phpPipe2[1]); exit(EXIT_SUCCESS); } else if (pid < 0) { // Error forking printDebug("Error in stdin php frok"); } else { // Parent fork close(phpPipe[1]); dup2(phpPipe2[0], STDIN_FILENO); execlp("/usr/bin/php-cgi", "php-cgi", NULL); } } else { queryString = malloc(strlen(r->requestVars) + 24); sprintf(queryString, "QUERY_STRING=%s", r->requestVars); putenv(queryString); putenv("REQUEST_METHOD=GET"); execl("/usr/bin/php-cgi", "php-cgi", NULL); } } else if (pid < 0) { // Error forking printDebug("Error forking php exec"); } else { // Parent fork size_t buffCount; close(phpPipe[1]); do { buffCount = read(phpPipe[0], buf, BUFF_READ); if (strlen(buf) == bufLen) { bufLen *= 2; buf = realloc(buf, bufLen); } } while (buffCount == 0); do { waitpid(pid, &status, WUNTRACED); } while (!WIFEXITED(status) && !WIFSIGNALED(status)); } close(phpPipe[0]); if (status != 0) { return NULL; } return buf; }