136 lines
4.6 KiB
C
136 lines
4.6 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <time.h>
|
|
#include <string.h>
|
|
#include <unistd.h>
|
|
#include <wait.h>
|
|
|
|
#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;
|
|
}
|
|
|