Fix web struct handling.

Typedef to handle different versions of libmicrohttpd.
Add getStructIndex().
Fix small print() mem leak.
This commit is contained in:
Sage Vaillancourt 2022-03-18 11:23:19 -04:00 committed by Sage Vaillancourt
parent b4584fa377
commit ee8eaf2d28
5 changed files with 91 additions and 58 deletions

View File

@ -301,3 +301,13 @@ struct Environment defaultEnv()
return e; return e;
} }
int getStructIndex(struct Environment* env, const char* name)
{
for (int i = 0; i < env->structCount; i++) {
if (strcmp(name, env->structDefs[i].name) == 0) {
return i;
}
}
return -1;
}

View File

@ -39,4 +39,6 @@ struct Environment defaultEnv();
struct StructDef getStructDef(struct Environment* env, const char* name); struct StructDef getStructDef(struct Environment* env, const char* name);
int getStructIndex(struct Environment* env, const char* name);
#endif #endif

View File

@ -46,7 +46,7 @@ stuff, when you think about it."
(htmlize p2))) (htmlize p2)))
)))) ))))
(def revealer (fn (x) (cat "x: " x))) (def revealer (fn (x) (cat "" x)))
(get "/" homepage) (get "/" homepage)
(get "/x" revealer) (get "/x" revealer)

View File

@ -682,9 +682,11 @@ Object charAt(Object string, Object at, struct Environment* ignore)
Object print(Object p, Object ignore, struct Environment* env) Object print(Object p, Object ignore, struct Environment* env)
{ {
p = cloneObject(p); Object c = cloneObject(p);
p = eval(&p, env); Object e = eval(&c, env);
_printObj(&p, 0); _printObj(&e, 0);
cleanObject(&c);
cleanObject(&e);
return numberObject(0); return numberObject(0);
} }

127
src/web.c
View File

@ -15,11 +15,14 @@
#include "web.h" #include "web.h"
#include "pebblisp.h" #include "pebblisp.h"
struct StructDef query = { #ifdef _MHD_FLAGS_ENUM
.fieldCount = 1, typedef enum MHD_Result HttpResult;
.name = "", #else
.names = {""} typedef int HttpResult;
}; #endif
int requestDefinition = -1;
int routeCount = 0; int routeCount = 0;
struct Route routes[10]; struct Route routes[10];
@ -41,9 +44,9 @@ int methodMatches(const char* method, struct Route* route)
} }
} }
static int static HttpResult
print_out_key (void *queryParamsV, enum MHD_ValueKind kind, const char *key, print_out_key(void *queryParamsV, enum MHD_ValueKind kind, const char *key,
const char *value) const char *value)
{ {
(void) kind; /* Unused. Silent compiler warning. */ (void) kind; /* Unused. Silent compiler warning. */
Object* queryParams = queryParamsV; Object* queryParams = queryParamsV;
@ -55,67 +58,83 @@ print_out_key (void *queryParamsV, enum MHD_ValueKind kind, const char *key,
return MHD_YES; return MHD_YES;
} }
//static enum MHD_Result static HttpResult
static int
answer_to_connection(void *cls, struct MHD_Connection *connection, answer_to_connection(void *cls, struct MHD_Connection *connection,
const char *url, const char *method, const char *url, const char *method,
const char *version, const char *upload_data, const char *version, const char *upload_data,
size_t *upload_data_size, void **con_cls) size_t *upload_data_size, void **con_cls)
{ {
const char *page = NULL; char *page = NULL;
printf("%s URL: '%s' :: ", method, url); printf("%s URL: '%s' :: ", method, url);
printf("version: %s\n", version); printf("version: %s\n", version);
printf("upload_data: %s\n", upload_data); printf("upload_data: %s\n", upload_data);
for (int i = 0; i < routeCount; i++) { for (int i = 0; i < routeCount; i++) {
if (methodMatches(method, &routes[i]) && strcmp(url, routes[i].path) == 0) { if (methodMatches(method, &routes[i]) && strcmp(url, routes[i].path) == 0) {
Object queryParams = listObject(); Object queryParams = listObject();
MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, print_out_key, &queryParams); MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, print_out_key, &queryParams);
//page = routes[i].routeAction(url);
Object lambdaList = listObject(); Object res = structObject(requestDefinition);
nf_addToList(&lambdaList, queryParams); res.structObject->fields[0] = queryParams;
Object route = cloneObject(routes[i].routeAction); Object route = cloneObject(routes[i].routeAction);
Object result = listEvalLambda(&route, &lambdaList, routes[i].env);
page = result.string; Object result = listEvalLambda(&route, &res, routes[i].env);
break; cleanObject(&res);
page = result.string;
break;
}
} }
}
if (!page) { if (!page) {
printf("no route found!\n"); printf("no route found!\n");
page = "<html><body><h1>404, Dumbass.</h1></body></html>"; page = "<html><body><h1>404, Dumbass.</h1></body></html>";
} }
struct MHD_Response *response; struct MHD_Response *response;
//enum MHD_Result ret; HttpResult ret;
int ret; (void) cls; /* Unused. Silent compiler warning. */
(void) cls; /* Unused. Silent compiler warning. */ (void) url; /* Unused. Silent compiler warning. */
(void) url; /* Unused. Silent compiler warning. */ (void) method; /* Unused. Silent compiler warning. */
(void) method; /* Unused. Silent compiler warning. */ (void) version; /* Unused. Silent compiler warning. */
(void) version; /* Unused. Silent compiler warning. */ (void) upload_data; /* Unused. Silent compiler warning. */
(void) upload_data; /* Unused. Silent compiler warning. */ (void) upload_data_size; /* Unused. Silent compiler warning. */
(void) upload_data_size; /* Unused. Silent compiler warning. */ (void) con_cls; /* Unused. Silent compiler warning. */
(void) con_cls; /* Unused. Silent compiler warning. */
response = response =
MHD_create_response_from_buffer(strlen(page), (void *) page, MHD_create_response_from_buffer(strlen(page), (void *) page,
MHD_RESPMEM_PERSISTENT); MHD_RESPMEM_PERSISTENT);
ret = MHD_queue_response(connection, MHD_HTTP_OK, response); ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
MHD_destroy_response(response); MHD_destroy_response(response);
return ret; // if (needsFree) {
// free(page);
// }
return ret;
}
int initialized = 0;
void initialize()
{
if (!initialized) {
Object o = parseEval("(struct Request (queryParams))", global());
cleanObject(&o);
requestDefinition = getStructIndex(global(), "Request");
}
initialized = 1;
} }
int start(int port) int start(int port)
{ {
struct MHD_Daemon *daemon = MHD_start_daemon( initialize();
MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD, struct MHD_Daemon *daemon = MHD_start_daemon(
port, NULL, NULL, &answer_to_connection, NULL, MHD_OPTION_END); MHD_USE_AUTO | MHD_USE_INTERNAL_POLLING_THREAD,
port, NULL, NULL, &answer_to_connection, NULL, MHD_OPTION_END);
if (NULL == daemon) if (NULL == daemon)
return 1; return 1;
// (void) getchar(); // (void) getchar();
// MHD_stop_daemon(daemon); // MHD_stop_daemon(daemon);
return 0; return 0;
} }