Added the ability to throw an error
This commit is contained in:
@@ -25,9 +25,11 @@
|
||||
#define ERROR_404 "404 Not Found"
|
||||
#define ERROR_500 "500 Internal Server Error"
|
||||
|
||||
int sendStringResponse(Connection *conn, char *status, char *str);
|
||||
int sendBinaryResponse(Connection *conn, char *status, void *data, size_t len);
|
||||
int sendErrorResponse(Connection *conn, char *error);
|
||||
char *getCode(int code);
|
||||
int sendStringResponse(Connection *conn, const char *status, char *str);
|
||||
int sendBinaryResponse(Connection *conn, const char *status,
|
||||
void *data, size_t len);
|
||||
int sendErrorResponse(Connection *conn, const char *error);
|
||||
//sendErrorResponse(conn, ERROR_404);
|
||||
int sendHeader(Connection *conn, char *status, size_t len);
|
||||
int sendHeader(Connection *conn, const char *status, size_t len);
|
||||
#endif
|
||||
|
||||
@@ -24,6 +24,7 @@
|
||||
typedef enum {
|
||||
READ,
|
||||
EXEC,
|
||||
THROW,
|
||||
} Command;
|
||||
|
||||
typedef struct {
|
||||
|
||||
@@ -50,7 +50,7 @@ Stream *acceptStream(Listener *listener, int flags);
|
||||
void freeListener(Listener *listener);
|
||||
void freeStream(Stream *stream);
|
||||
|
||||
ssize_t sendStream(Stream *stream, void *data, size_t len);
|
||||
ssize_t sendStream(Stream *stream, const void *data, size_t len);
|
||||
ssize_t recvStream(Stream *stream, void *data, size_t len);
|
||||
//return value is the same as the read and write syscalls.
|
||||
#endif
|
||||
|
||||
@@ -30,14 +30,16 @@
|
||||
#include <responses.h>
|
||||
#include <responseutil.h>
|
||||
|
||||
static int resilientSend(Stream *stream, char *buff, size_t len) {
|
||||
static int resilientSend(Stream *stream, const void *buff, size_t len) {
|
||||
//Will either write len bytes, or return 1 for error.
|
||||
const char *data = (const char *) buff;
|
||||
//using character pointers to do pointer arithmetic
|
||||
while (len > 0) {
|
||||
ssize_t sent = sendStream(stream, buff, len);
|
||||
ssize_t sent = sendStream(stream, data, len);
|
||||
if (sent < 0)
|
||||
return 1;
|
||||
len -= sent;
|
||||
buff += sent;
|
||||
data += sent;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
@@ -142,7 +144,8 @@ static int execResponse(Connection *conn, char *path) {
|
||||
close(1);
|
||||
close(output[0]);
|
||||
dup2(output[1], 1);
|
||||
char **args = malloc((conn->fieldCount*2 + 2) * sizeof(char *));
|
||||
char **args =
|
||||
malloc((conn->fieldCount*2 + 2) * sizeof(char *));
|
||||
if (args == NULL) {
|
||||
close(output[1]);
|
||||
exit(EXIT_FAILURE);
|
||||
@@ -239,6 +242,10 @@ int sendResponse(Connection *conn, Sitefile *site) {
|
||||
execResponse(conn,
|
||||
site->content[i].arg);
|
||||
break;
|
||||
case THROW:
|
||||
sendErrorResponse(conn,
|
||||
site->content[i].arg);
|
||||
break;
|
||||
default:
|
||||
sendErrorResponse(conn, ERROR_500);
|
||||
return 1;
|
||||
|
||||
@@ -48,7 +48,24 @@ static int sendConnection(Connection *conn, char *format, ...) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
int sendStringResponse(Connection *conn, char *status, char *str) {
|
||||
char *getCode(int code) {
|
||||
switch (code) {
|
||||
case 200:
|
||||
return strdup(CODE_200);
|
||||
case 400:
|
||||
return strdup(ERROR_400);
|
||||
case 403:
|
||||
return strdup(ERROR_403);
|
||||
case 404:
|
||||
return strdup(ERROR_404);
|
||||
case 500:
|
||||
return strdup(ERROR_500);
|
||||
default:
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
int sendStringResponse(Connection *conn, const char *status, char *str) {
|
||||
return sendConnection(conn,
|
||||
"HTTP/1.1 %s\r\n"
|
||||
CONST_FIELDS
|
||||
@@ -59,7 +76,7 @@ int sendStringResponse(Connection *conn, char *status, char *str) {
|
||||
);
|
||||
}
|
||||
|
||||
int sendErrorResponse(Connection *conn, char *error) {
|
||||
int sendErrorResponse(Connection *conn, const char *error) {
|
||||
const char *template =
|
||||
"<meta charset=utf-8>"
|
||||
"<h1 text-align=center>"
|
||||
@@ -73,7 +90,7 @@ int sendErrorResponse(Connection *conn, char *error) {
|
||||
return ret;
|
||||
}
|
||||
|
||||
int sendBinaryResponse(Connection *conn, char *status,
|
||||
int sendBinaryResponse(Connection *conn, const char *status,
|
||||
void *data, size_t len) {
|
||||
if (sendConnection(conn,
|
||||
"HTTP/1.1 %s\r\n"
|
||||
@@ -86,7 +103,7 @@ int sendBinaryResponse(Connection *conn, char *status,
|
||||
return sendStream(conn->stream, data, len) < len;
|
||||
}
|
||||
|
||||
int sendHeader(Connection *conn, char *status, size_t len) {
|
||||
int sendHeader(Connection *conn, const char *status, size_t len) {
|
||||
return (sendConnection(conn,
|
||||
"HTTP/1.1 %s\r\n"
|
||||
CONST_FIELDS
|
||||
|
||||
@@ -22,6 +22,7 @@
|
||||
|
||||
#include <util.h>
|
||||
#include <sitefile.h>
|
||||
#include <responseutil.h>
|
||||
|
||||
typedef enum {
|
||||
SUCCESS,
|
||||
@@ -156,15 +157,6 @@ error:
|
||||
return ERROR;
|
||||
}
|
||||
|
||||
static char *copyString(char *str) {
|
||||
size_t len = strlen(str);
|
||||
char *ret = malloc(len + 1);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
memcpy(ret, str, len + 1);
|
||||
return ret;
|
||||
}
|
||||
|
||||
Sitefile *parseSitefile(char *path) {
|
||||
FILE *file = fopen(path, "r");
|
||||
if (file == NULL)
|
||||
@@ -211,7 +203,7 @@ Sitefile *parseSitefile(char *path) {
|
||||
else if (strcmp(argv[1], "host") == 0) {
|
||||
if (ret->size == lasthostset)
|
||||
free(host);
|
||||
host = copyString(argv[2]);
|
||||
host = strdup(argv[2]);
|
||||
lasthostset = ret->size;
|
||||
}
|
||||
else
|
||||
@@ -230,9 +222,9 @@ Sitefile *parseSitefile(char *path) {
|
||||
goto error;
|
||||
}
|
||||
else if (strcmp(argv[1], "key") == 0)
|
||||
ret->key = copyString(argv[2]);
|
||||
ret->key = strdup(argv[2]);
|
||||
else if (strcmp(argv[1], "cert") == 0)
|
||||
ret->cert = copyString(argv[2]);
|
||||
ret->cert = strdup(argv[2]);
|
||||
else if (strcmp(argv[1], "timeout") == 0)
|
||||
ret->timeout = atoi(argv[2]);
|
||||
else
|
||||
@@ -255,17 +247,23 @@ Sitefile *parseSitefile(char *path) {
|
||||
goto error;
|
||||
|
||||
if (strcmp(argv[0], "read") == 0) {
|
||||
ret->content[ret->size].arg = copyString(argv[2]);
|
||||
ret->content[ret->size].arg = strdup(argv[2]);
|
||||
if (ret->content[ret->size].arg == NULL)
|
||||
goto error;
|
||||
ret->content[ret->size].command = READ;
|
||||
}
|
||||
else if (strcmp(argv[0], "exec") == 0) {
|
||||
ret->content[ret->size].arg = copyString(argv[2]);
|
||||
ret->content[ret->size].arg = strdup(argv[2]);
|
||||
if (ret->content[ret->size].arg == NULL)
|
||||
goto error;
|
||||
ret->content[ret->size].command = EXEC;
|
||||
}
|
||||
else if (strcmp(argv[0], "throw") == 0) {
|
||||
ret->content[ret->size].arg = getCode(atoi(argv[2]));
|
||||
if (ret->content[ret->size].arg == NULL)
|
||||
goto error;
|
||||
ret->content[ret->size].command = THROW;
|
||||
}
|
||||
else
|
||||
goto error;
|
||||
freeTokens(argc, argv);
|
||||
|
||||
@@ -154,7 +154,7 @@ void freeStream(Stream *stream) {
|
||||
free(stream);
|
||||
}
|
||||
|
||||
ssize_t sendStream(Stream *stream, void *data, size_t len) {
|
||||
ssize_t sendStream(Stream *stream, const void *data, size_t len) {
|
||||
switch (stream->type) {
|
||||
case TCP:
|
||||
return write(stream->fd, data, len);
|
||||
|
||||
Reference in New Issue
Block a user