mirror of
https://github.com/sigmasternchen/CShore
synced 2025-03-15 16:18:56 +00:00
added error response
This commit is contained in:
parent
f816772d96
commit
94647efd6e
4 changed files with 79 additions and 22 deletions
23
main.c
23
main.c
|
@ -13,22 +13,17 @@
|
||||||
struct networkingConfig netConfig;
|
struct networkingConfig netConfig;
|
||||||
|
|
||||||
static void handler(struct request request, struct response _response) {
|
static void handler(struct request request, struct response _response) {
|
||||||
method_t method = request.metaData.method;
|
|
||||||
const char* path = request.metaData.path;
|
|
||||||
const char* queryString = request.metaData.queryString;
|
|
||||||
//const char* peer = request.peer.addr;
|
|
||||||
//int port = request.peer.port;
|
|
||||||
|
|
||||||
ctx_t ctx = {
|
ctx_t ctx = {
|
||||||
method: method,
|
method: request.metaData.method,
|
||||||
path: path,
|
path: request.metaData.path,
|
||||||
queryString: queryString
|
queryString: request.metaData.queryString,
|
||||||
|
peerAddr: request.peer.addr,
|
||||||
|
peerPort: request.peer.port
|
||||||
};
|
};
|
||||||
|
|
||||||
response_t response = routerHandler(ctx);
|
response_t response = routerHandler(ctx);
|
||||||
if (response.output == NULL) {
|
if (response.output == NULL) {
|
||||||
response.status = 500;
|
response = errorResponse(500, "route did not provide a reponse handler");
|
||||||
response.headers = headers_create();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int fd = _response.sendHeader(response.status, &response.headers, &request);
|
int fd = _response.sendHeader(response.status, &response.headers, &request);
|
||||||
|
@ -45,11 +40,7 @@ static void handler(struct request request, struct response _response) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (response.output == NULL) {
|
response.output(out, response._userData);
|
||||||
fprintf(out, "Internal Server Error\n");
|
|
||||||
} else {
|
|
||||||
response.output(out, response._userData);
|
|
||||||
}
|
|
||||||
|
|
||||||
fclose(out);
|
fclose(out);
|
||||||
}
|
}
|
||||||
|
|
65
request.c
65
request.c
|
@ -8,6 +8,9 @@
|
||||||
#include <headers.h>
|
#include <headers.h>
|
||||||
#include <util.h>
|
#include <util.h>
|
||||||
#include <mime.h>
|
#include <mime.h>
|
||||||
|
#include <status.h>
|
||||||
|
|
||||||
|
#include <json.h>
|
||||||
|
|
||||||
|
|
||||||
#include "request.h"
|
#include "request.h"
|
||||||
|
@ -20,11 +23,23 @@ response_t emptyResponse() {
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static errorformat_t errorformat = JSON;
|
||||||
|
|
||||||
|
void setDefaultErrorFormat(errorformat_t format) {
|
||||||
|
errorformat = format;
|
||||||
|
}
|
||||||
|
|
||||||
|
void _rawOutputAndFree(FILE* out, void* _userData) {
|
||||||
|
fprintf(out, "%s", (char*) _userData);
|
||||||
|
|
||||||
|
free(_userData);
|
||||||
|
}
|
||||||
|
|
||||||
void _rawOutput(FILE* out, void* _userData) {
|
void _rawOutput(FILE* out, void* _userData) {
|
||||||
fprintf(out, "%s", (const char*) _userData);
|
fprintf(out, "%s", (const char*) _userData);
|
||||||
}
|
}
|
||||||
|
|
||||||
response_t rawResponse(int status, const char* txt) {
|
response_t _rawResponse(int status, char* txt, bool free) {
|
||||||
response_t response = emptyResponse();
|
response_t response = emptyResponse();
|
||||||
response.status = status;
|
response.status = status;
|
||||||
|
|
||||||
|
@ -35,10 +50,50 @@ response_t rawResponse(int status, const char* txt) {
|
||||||
|
|
||||||
headers_mod(&response.headers, "Content-Length", tmp);
|
headers_mod(&response.headers, "Content-Length", tmp);
|
||||||
response._userData = (void*) txt;
|
response._userData = (void*) txt;
|
||||||
response.output = _rawOutput;
|
|
||||||
|
if (free) {
|
||||||
|
response.output = _rawOutputAndFree;
|
||||||
|
} else {
|
||||||
|
response.output = _rawOutput;
|
||||||
|
}
|
||||||
return response;
|
return response;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
response_t rawResponse(int status, const char* txt) {
|
||||||
|
return _rawResponse(status, (char*) txt, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
response_t errorResponse(int status, const char* message) {
|
||||||
|
const char* statusString = getStatusStrings(status).statusString;
|
||||||
|
|
||||||
|
if (message == NULL) {
|
||||||
|
message = "";
|
||||||
|
}
|
||||||
|
|
||||||
|
char* tmp;
|
||||||
|
switch(errorformat) {
|
||||||
|
case RAW:
|
||||||
|
tmp = malloc(strlen(statusString) + 1 + strlen(message) + 1);
|
||||||
|
sprintf(tmp, "%s\n%s", statusString, message);
|
||||||
|
return _rawResponse(status, tmp, true);
|
||||||
|
case JSON:
|
||||||
|
tmp = getTimestamp();
|
||||||
|
jsonValue_t* json = json_object(true, 5,
|
||||||
|
"timestamp", json_string(tmp),
|
||||||
|
"status", json_long(status),
|
||||||
|
"error", json_string(statusString),
|
||||||
|
"message", json_string(message),
|
||||||
|
"path", json_string("not yet implemented")
|
||||||
|
);
|
||||||
|
free(tmp);
|
||||||
|
tmp = json_stringify(json);
|
||||||
|
json_free(json);
|
||||||
|
return _rawResponse(status, tmp, true);
|
||||||
|
default:
|
||||||
|
return rawResponse(500, "Internel Server Error\nunknown error format");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void _fileOutput(FILE* out, void* _userData) {
|
void _fileOutput(FILE* out, void* _userData) {
|
||||||
FILE* in = (FILE*) _userData;
|
FILE* in = (FILE*) _userData;
|
||||||
|
|
||||||
|
@ -58,16 +113,16 @@ response_t fileResponse(const char* file) {
|
||||||
|
|
||||||
struct stat statObj;
|
struct stat statObj;
|
||||||
if (stat(file, &statObj) < 0) {
|
if (stat(file, &statObj) < 0) {
|
||||||
return rawResponse(500, strerror(errno));
|
return errorResponse(500, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!S_ISREG(statObj.st_mode)) {
|
if (!S_ISREG(statObj.st_mode)) {
|
||||||
return rawResponse(500, "not a file");
|
return errorResponse(500, "not a file");
|
||||||
}
|
}
|
||||||
|
|
||||||
FILE* stream = fopen(file, "r");
|
FILE* stream = fopen(file, "r");
|
||||||
if (stream == NULL) {
|
if (stream == NULL) {
|
||||||
return rawResponse(500, "");
|
return errorResponse(500, strerror(errno));
|
||||||
}
|
}
|
||||||
|
|
||||||
int length = strlenOfNumber(statObj.st_size);
|
int length = strlenOfNumber(statObj.st_size);
|
||||||
|
|
11
request.h
11
request.h
|
@ -12,6 +12,8 @@ typedef struct {
|
||||||
method_t method;
|
method_t method;
|
||||||
const char* path;
|
const char* path;
|
||||||
const char* queryString;
|
const char* queryString;
|
||||||
|
const char* peerAddr;
|
||||||
|
int peerPort;
|
||||||
} ctx_t;
|
} ctx_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
|
@ -22,8 +24,17 @@ typedef struct {
|
||||||
void (*output) (FILE* conenction, void* _userData);
|
void (*output) (FILE* conenction, void* _userData);
|
||||||
} response_t;
|
} response_t;
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
RAW,
|
||||||
|
JSON
|
||||||
|
} errorformat_t;
|
||||||
|
|
||||||
|
void setDefaultErrorFormat(errorformat_t format);
|
||||||
|
|
||||||
response_t emptyResponse();
|
response_t emptyResponse();
|
||||||
|
|
||||||
|
response_t errorResponse(int status, const char* message);
|
||||||
|
|
||||||
response_t rawResponse(int status, const char* txt);
|
response_t rawResponse(int status, const char* txt);
|
||||||
|
|
||||||
response_t fileResponse(const char* file);
|
response_t fileResponse(const char* file);
|
||||||
|
|
2
router.c
2
router.c
|
@ -107,7 +107,7 @@ int registerRoute(method_t method, const char* path, handle_t* handle) {
|
||||||
response_t routerHandler(ctx_t ctx) {
|
response_t routerHandler(ctx_t ctx) {
|
||||||
struct route* route = findRoute(ctx.method, ctx.path);
|
struct route* route = findRoute(ctx.method, ctx.path);
|
||||||
if (route == NULL) {
|
if (route == NULL) {
|
||||||
return rawResponse(404, "Not Found\n");
|
return errorResponse(404, "no route found");
|
||||||
}
|
}
|
||||||
|
|
||||||
return route->handle(ctx);
|
return route->handle(ctx);
|
||||||
|
|
Loading…
Reference in a new issue