added support for middlewares

This commit is contained in:
overflowerror 2021-05-26 21:11:20 +02:00
parent 6e5b928bae
commit c84a75a09e
6 changed files with 56 additions and 18 deletions

View file

@ -17,7 +17,11 @@ response_t foobar(ctx_t ctx) {
return fileResponse("demo/foobar.txt");
}
GET("/user", user);
response_t authenticate(ctx_t ctx) {
return next();
}
GET("/user", authenticate, user);
response_t user(ctx_t ctx) {
user_t user = {
.username = "overflowerror",

View file

@ -10,16 +10,16 @@
#define _CAT(a, b, c, d) a ## b ## c ## d
#define _CAT2(a, b, c, d) _CAT(a, b, c, d)
#define CONTROLLER(m, p, f) handle_t f; __attribute__((constructor)) static void _CAT2(_register_route_, f, _, __LINE__) () { if (registerRoute(m, p, &f) < 0) { fprintf(stderr, "ERROR: couldn't add route %s %s (%s): already registered\n", #m, p, #f); }; }
#define CONTROLLER(m, p, ...) handle_t __VA_ARGS__; __attribute__((constructor)) static void _CAT2(_register_route_, f, _, __LINE__) () { if (registerRoute(m, p, __VA_ARGS__, NULL) < 0) { fprintf(stderr, "ERROR: couldn't add route %s %s (%s): already registered\n", #m, p, #__VA_ARGS__); }; }
#define GET(p, f) CONTROLLER(HTTP_GET, p, f)
#define POST(p, f) CONTROLLER(HTTP_POST, p, f)
#define HEAD(p, f) CONTROLLER(HTTP_HEAD, p, f)
#define PUT(p, f) CONTROLLER(HTTP_PUT, p, f)
#define DELETE(p, f) CONTROLLER(HTTP_DELETE, p, f)
#define TRACE(p, f) CONTROLLER(HTTP_TRACE, p, f)
#define OPTION(p, f) CONTROLLER(HTTP_OPTIONS, p, f)
#define CONNECT(p, f) CONTROLLER(HTTP_CONNECT, p, f)
#define PATCH(p, f) CONTROLLER(HTTP_PATCH, p, f)
#define GET(p, ...) CONTROLLER(HTTP_GET, p, __VA_ARGS__)
#define POST(p, ...) CONTROLLER(HTTP_POST, p, __VA_ARGS__)
#define HEAD(p, ...) CONTROLLER(HTTP_HEAD, p, __VA_ARGS__)
#define PUT(p, ...) CONTROLLER(HTTP_PUT, p, __VA_ARGS__)
#define DELETE(p, ...) CONTROLLER(HTTP_DELETE, p, __VA_ARGS__)
#define TRACE(p, ...) CONTROLLER(HTTP_TRACE, p, __VA_ARGS__)
#define OPTION(p, ...) CONTROLLER(HTTP_OPTIONS, p, __VA_ARGS__)
#define CONNECT(p, ...) CONTROLLER(HTTP_CONNECT, p, __VA_ARGS__)
#define PATCH(p, ...) CONTROLLER(HTTP_PATCH, p, __VA_ARGS__)
#endif

View file

@ -252,3 +252,9 @@ response_t templateResponse(int status, const char* name, ...) {
return response;
}
response_t next() {
response_t response = emptyResponse();
response.status = NEXT_RESPONSE_STATUS;
return response;
}

View file

@ -8,6 +8,8 @@
#include "common.h"
#define NEXT_RESPONSE_STATUS (0)
typedef struct {
method_t method;
const char* path;
@ -33,6 +35,8 @@ void setDefaultErrorFormat(errorformat_t format);
response_t emptyResponse();
response_t next();
response_t statusResponse(int status, const char* message);
response_t errorResponse(int status, const char* message);

View file

@ -2,16 +2,18 @@
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <stdarg.h>
#include "router.h"
#define MAX_ROUTES (128)
#define MAX_HANDLERS (8)
struct route {
method_t method;
const char* path;
handle_t* handle;
handle_t* handlers[MAX_HANDLERS + 1];
} routes[MAX_ROUTES];
int n = 0;
@ -86,7 +88,7 @@ struct route* reverseFindRoute(method_t method, const char* path) {
return NULL;
}
int registerRoute(method_t method, const char* path, handle_t* handle) {
int registerRoute(method_t method, const char* path, ...) {
if (n >= MAX_ROUTES) {
return -1;
}
@ -95,12 +97,27 @@ int registerRoute(method_t method, const char* path, handle_t* handle) {
return -2;
}
routes[n++] = (struct route) {
struct route route = {
method: method,
path: path,
handle: handle
path: path
};
va_list argptr;
va_start(argptr, path);
int i;
for(i = 0; i < MAX_HANDLERS; i++) {
route.handlers[i] = va_arg(argptr, handle_t*);
if (route.handlers[i] == NULL) {
break;
}
}
route.handlers[i] = NULL;
va_end(argptr);
routes[n++] = route;
return 0;
}
@ -110,5 +127,12 @@ response_t routerHandler(ctx_t ctx) {
return errorResponse(404, "no route found");
}
return route->handle(ctx);
for(int i = 0; route->handlers[i] != NULL; i++) {
response_t response = route->handlers[i](ctx);
if (response.status != NEXT_RESPONSE_STATUS) {
return response;
}
}
return errorResponse(500, "no handler produced valid response");
}

View file

@ -3,7 +3,7 @@
#include "handler.h"
int registerRoute(method_t method, const char* path, handle_t handle);
int registerRoute(method_t method, const char* path, ...);
response_t routerHandler(ctx_t ctx);