Added HTTP request types
This commit is contained in:
134
cmd/server.c
134
cmd/server.c
@@ -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);
|
||||||
|
|||||||
@@ -7,4 +7,5 @@ struct HTTPRequest {
|
|||||||
char *requestVersion;
|
char *requestVersion;
|
||||||
char *requestHost;
|
char *requestHost;
|
||||||
char *requestDir;
|
char *requestDir;
|
||||||
|
unsigned char *requestBody;
|
||||||
};
|
};
|
||||||
|
|||||||
2
include/utils.h
Normal file
2
include/utils.h
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
int PrintLog(unsigned char *message);
|
||||||
|
|
||||||
@@ -18,13 +18,21 @@ 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);
|
||||||
@@ -35,3 +43,12 @@ int return400Request(int socket, SSL *ssl) {
|
|||||||
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
13
src/utils.c
Normal 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;
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user