Added HTTP request types

This commit is contained in:
Pin
2022-02-21 15:03:26 -05:00
parent 44a6447047
commit 2f73f776f6
6 changed files with 155 additions and 32 deletions

View File

@@ -12,8 +12,10 @@
#include "socketHelp.h" #include "socketHelp.h"
#include "returnRequest.h" #include "returnRequest.h"
#include "server.h" #include "server.h"
#include "utils.h"
#define WEB_ROOT "content/" #define WEB_ROOT "content/"
#define BUFF_READ 1024
static int verbose_flag = 0; static int verbose_flag = 0;
bool enableHTTPS = 0; bool enableHTTPS = 0;
@@ -29,16 +31,25 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
char temp[1]; // Used to check newlines char temp[1]; // Used to check newlines
char *token = calloc(8, sizeof(char)); char *token = calloc(8, sizeof(char));
int line = 0; int line = 0;
char *checkLine = calloc(1000, sizeof(char)); int contentCheck = 0;
unsigned char *checkLine = calloc(1000, sizeof(unsigned char));
unsigned char *logLine = malloc(sizeof(unsigned char));
for (int i = 0; i < strlen((char *)buffer); i++) { // Creating empty requestBody
r->requestBody = calloc(8, sizeof(char));
for (int i = 0; i <= strlen((char *)buffer); i++) {
temp[0] = buffer[i]; temp[0] = buffer[i];
if ((!strcmp(temp, "\n")) && (i != 0)) { // Checking for newline character OR end of string
if (((!strcmp(temp, "\n")) && (i != 0)) || (i == strlen((char *)buffer))) {
// Config Check // Config Check
if (line == 0) { if (line == 0) {
token = strtok(checkLine, " "); logLine = calloc(strlen((char *)checkLine), sizeof(char));
strcpy((char *)logLine, (char *)checkLine);
token = strtok((char *)checkLine, " ");
// HTTP Request Type // HTTP Request Type
if (!strcmp(token, "GET")) { if ((!strcmp(token, "GET")) || (!strcmp(token, "POST")) ||
(!strcmp(token, "PUT")) || (!strcmp(token, "DELETE"))) {
// Grabbing HTTP Request Type // Grabbing HTTP Request Type
r->requestType = malloc(strlen(token)); r->requestType = malloc(strlen(token));
strcpy(r->requestType, token); strcpy(r->requestType, token);
@@ -50,36 +61,54 @@ int parseHTTPRequest(unsigned char *buffer, struct HTTPRequest *r) {
token = strtok(NULL, ""); token = strtok(NULL, "");
r->requestVersion = malloc(strlen(token)); r->requestVersion = malloc(strlen(token));
strcpy(r->requestVersion, token); strcpy(r->requestVersion, token);
} else if (!strcmp(token, "POST")) {
printDebug("POST RECEIVED");
return 2;
} else { } else {
char *errMessage = "Unsupported request type: ";
logLine = calloc(strlen(errMessage) + strlen(token), sizeof(unsigned char));
sprintf((char *)logLine, "%s%s", errMessage, token);
PrintLog(logLine);
free(logLine);
free(checkLine);
return 2; return 2;
} }
// Log Request
PrintLog(logLine);
} else { } else {
token = strtok(checkLine, ":"); if (contentCheck) { // Once content check is set to one everything after is part of the body
r->requestBody = realloc(r->requestBody,
(strlen((char *)checkLine) + strlen((char *)r->requestBody) + 1));
strcat((char *)r->requestBody, (char *)checkLine);
// Adding newline to requestBody
sprintf((char *)r->requestBody, "%s\n", r->requestBody);
} else {
if (strlen((char *)checkLine) == 1) { // Looking for blank empty line to end header info
contentCheck = 1;
}
token = strtok((char *)checkLine, ":");
// Host Check // Host Check
if (!strcmp(token, "Host")) { if (!strcmp(token, "Host")) {
token = strtok(NULL, ""); token = strtok(NULL, "");
r->requestHost = malloc(strlen(token)); r->requestHost = malloc(strlen(token));
strcpy(r->requestHost, token); strcpy(r->requestHost, token);
} }
// Reset checkline
} }
if (strlen(checkLine) > 0) { }
if (strlen((char *)checkLine) > 0) {
// Clear checkLine // Clear checkLine
memset(checkLine,0,strlen(checkLine)); memset(checkLine,0,strlen((char *)checkLine));
} }
line++; line++;
} else { } else {
strcat(checkLine, temp); strcat((char *)checkLine, temp);
} }
} }
if (strlen(r->requestType) == 0) { if (strlen(r->requestType) == 0) {
free(logLine);
free(checkLine);
return -1; return -1;
} }
free(logLine);
free(checkLine); free(checkLine);
return 0; return 0;
} }
@@ -128,12 +157,41 @@ int handleGetRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
return 0; return 0;
} }
int handlePUTRequest(int socket, struct HTTPRequest *r, SSL *ssl) {
FILE *fp;
char *reqDir;
char * workingReqDir;
char errResponse[256];
if (!strcmp(r->requestDir, "/")) {
workingReqDir = "index.html";
} else {
workingReqDir = r->requestDir;
}
reqDir = calloc(strlen(WEB_ROOT) + strlen(workingReqDir), sizeof(char));
sprintf(reqDir, "%s%s", WEB_ROOT, workingReqDir);
fp = fopen(reqDir, "w");
if (fp == NULL) {
sprintf(errResponse, "Error opening file: %s", workingReqDir);
printDebug(errResponse);
return404Request(socket, ssl);
return -1;
}
fprintf(fp, "%s", r->requestBody);
free(reqDir);
fclose(fp);
return201Request(socket, r->requestBody, ssl);
return 0;
}
int handleRequest(unsigned char buffer[], int socket, SSL *ssl) { int handleRequest(unsigned char buffer[], int socket, SSL *ssl) {
struct HTTPRequest r; // Holds relevant HTTP request information struct HTTPRequest r; // Holds relevant HTTP request information
int checkerr = 0; int checkerr = 0;
printDebug("Received Request");
// Grabbing relevant information out of request // Grabbing relevant information out of request
checkerr = parseHTTPRequest(buffer, &r); checkerr = parseHTTPRequest(buffer, &r);
if (checkerr != 0) { // Checking for HTTP parsing error if (checkerr != 0) { // Checking for HTTP parsing error
@@ -141,7 +199,7 @@ int handleRequest(unsigned char buffer[], int socket, SSL *ssl) {
printDebug("Error reading request, returning empty 404"); printDebug("Error reading request, returning empty 404");
} else { } else {
printDebug("Error parsing, returning 500"); printDebug("Error parsing, returning 500");
// return return500Request(socket, ssl); return return501Request(socket, ssl);
} }
return return400Request(socket, ssl); return return400Request(socket, ssl);
} }
@@ -149,10 +207,19 @@ int handleRequest(unsigned char buffer[], int socket, SSL *ssl) {
if (!strcmp(r.requestType, "GET")) { if (!strcmp(r.requestType, "GET")) {
handleGetRequest(socket, &r, ssl); handleGetRequest(socket, &r, ssl);
return 0; return 0;
} } else if (!strcmp(r.requestType, "POST")) {
// Return response to socket return501Request(socket, ssl);
return200Request(socket, NULL ,ssl);
return 0; return 0;
} else if (!strcmp(r.requestType, "PUT")) {
handlePUTRequest(socket, &r, ssl);
return 0;
} else if (!strcmp(r.requestType, "DELETE")) {
return501Request(socket, ssl);
return 0;
} else {
return500Request(socket, ssl);
return 0;
}
} }
int main(int argc, char **argv) { int main(int argc, char **argv) {
@@ -173,7 +240,8 @@ int main(int argc, char **argv) {
SSL_CTX *ctx = NULL; SSL_CTX *ctx = NULL;
unsigned char *buffer = calloc(8096, sizeof(unsigned char)); size_t bufSize = BUFF_READ;
unsigned char *buffer = calloc(bufSize, sizeof(unsigned char));
// Setting up options // Setting up options
static const struct option long_options[] = { static const struct option long_options[] = {
@@ -274,16 +342,38 @@ int main(int argc, char **argv) {
perror("Accept connection error"); perror("Accept connection error");
exit(EXIT_FAILURE); exit(EXIT_FAILURE);
} }
bufSize = BUFF_READ;
if ( enableHTTPS ) { if ( enableHTTPS ) {
size_t buffCont = 1;
SSL *ssl; SSL *ssl;
ssl = SSL_new(ctx); ssl = SSL_new(ctx);
SSL_set_fd(ssl, new_socket); SSL_set_fd(ssl, new_socket);
SSL_accept(ssl); SSL_accept(ssl);
SSL_read(ssl, buffer, 8096); do {
buffCont = SSL_read(ssl, buffer, BUFF_READ);
if (strlen((char *)buffer) == bufSize) {
bufSize *= 2;
buffer = realloc(buffer, bufSize);
}
} while(buffCont == 0);
if (strlen((char *)buffer) != 0) {
handleRequest(buffer, new_socket, ssl); handleRequest(buffer, new_socket, ssl);
buffer = calloc(bufSize, sizeof(unsigned char));
} else { } else {
read(new_socket, buffer, 1024); printDebug("Error reading from socket");
}
} else {
size_t buffCont = 1;
do {
buffCont = read(new_socket, buffer, BUFF_READ);
if (strlen((char *)buffer) == bufSize) {
bufSize *= 2;
buffer = realloc(buffer, bufSize);
}
} while(buffCont == 0);
handleRequest(buffer, new_socket, NULL); handleRequest(buffer, new_socket, NULL);
buffer = calloc(bufSize, sizeof(unsigned char));
} }
close(new_socket); close(new_socket);

View File

@@ -7,4 +7,5 @@ struct HTTPRequest {
char *requestVersion; char *requestVersion;
char *requestHost; char *requestHost;
char *requestDir; char *requestDir;
unsigned char *requestBody;
}; };

View File

@@ -2,8 +2,8 @@
int returnRequest(int socket, char *message, int status); int returnRequest(int socket, char *message, int status);
int return200Request(int socket, unsigned char *content ,SSL *ssl); int return200Request(int socket, unsigned char *content, SSL *ssl);
int return201Request(int socket, unsigned char *content ,SSL *ssl); int return201Request(int socket, unsigned char *content, SSL *ssl);
int return400Request(int socket, SSL *ssl); int return400Request(int socket, SSL *ssl);
int return403Request(int socket, SSL *ssl); int return403Request(int socket, SSL *ssl);

2
include/utils.h Normal file
View File

@@ -0,0 +1,2 @@
int PrintLog(unsigned char *message);

View File

@@ -18,20 +18,37 @@ int returnRequest(int socket, char *message, int status, SSL *ssl) {
} }
int return200Request(int socket, unsigned char *content, SSL *ssl) { int return200Request(int socket, unsigned char *content, SSL *ssl) {
char *message = "";//= "HTTP/1.1 200 OK\nContent-Length: 6\nConnection: close\n\nhello\n"; char *message = "";
message = calloc(strlen((char *)content) + 128, sizeof(unsigned char)); message = calloc(strlen((char *)content) + 128, sizeof(unsigned char));
sprintf(message, "HTTP/1.1 200 OK\nContent-Length: %zu\nConnection: close\n\n%s\n", sprintf(message, "HTTP/1.1 200 OK\nContent-Length: %zu\nConnection: close\n\n%s\n",
strlen((char *)content), content); strlen((char *)content), content);
return returnRequest(socket, message, 200, ssl); return returnRequest(socket, message, 200, ssl);
} }
int return201Request(int socket, unsigned char *content, SSL *ssl) {
char *message = "";
message = calloc(strlen((char *)content) + 128, sizeof(unsigned char));
sprintf(message, "HTTP/1.1 201 Created\nContent-Length: %zu\nConnection: close\n\n%s\n",
strlen((char *)content), content);
return returnRequest(socket, message, 201, ssl);
}
int return404Request(int socket, SSL *ssl) { int return404Request(int socket, SSL *ssl) {
char *message = "HTTP/1.1 404 Not Found\nContent-Length: 12\nConnection: close\n\n404 Request\n"; char *message = "HTTP/1.1 404 Not Found\nContent-Length: 12\nConnection: close\n\n404 Request\n";
return returnRequest(socket, message, 404, ssl); return returnRequest(socket, message, 404, ssl);
} }
int return400Request(int socket, SSL *ssl) { int return400Request(int socket, SSL *ssl) {
char *message = "HTTP/1.1 400 HTTP Request Not Valid\n Content-Length: 0\nConnection: close\n\n"; char *message = "HTTP/1.1 400 HTTP Request Not Valid\nContent-Length: 0\nConnection: close\n\n";
return returnRequest(socket, message, 400, ssl); return returnRequest(socket, message, 400, ssl);
} }
int return500Request(int socket, SSL *ssl) {
char *message = "HTTP/1.1 500 Internal Server Error\nContent-Length: 0\nConnection: close\n\n";
return returnRequest(socket, message, 500, ssl);
}
int return501Request(int socket, SSL *ssl) {
char *message = "HTTP/1.1 501 Not Implemented\nContent-Length: 0\nConnection: close\n\n";
return returnRequest(socket, message, 501, ssl);
}

13
src/utils.c Normal file
View File

@@ -0,0 +1,13 @@
#include <stdio.h>
#include <time.h>
int PrintLog(unsigned char *message) {
time_t UTCTime;
// Setting time in EPOC
time(&UTCTime);
struct tm *now = localtime(&UTCTime);
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;
}