Add comments
This commit is contained in:
@@ -50,8 +50,10 @@
|
||||
#define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_BLOWFISH_NOINCLUDE
|
||||
/* Just to make sure the prototypes match the actual definitions */
|
||||
#include "crypt_blowfish.h"
|
||||
#endif // CRYPT_BLOWFISH_NOINCLUDE
|
||||
|
||||
#ifdef __i386__
|
||||
#define BF_ASM 1
|
||||
|
||||
@@ -3,7 +3,10 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef WL_NOINCLUDE
|
||||
#include "wl.h"
|
||||
#endif // WL_NOINCLUDE
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// BASIC
|
||||
|
||||
@@ -35,12 +35,14 @@ header.save("cweb.h")
|
||||
|
||||
source = Amalgamator()
|
||||
source.append_text("#include \"cweb.h\"\n")
|
||||
source.append_text("#define WL_NOINCLUDE\n")
|
||||
source.append_text("#define HTTP_NOINCLUDE\n")
|
||||
source.append_file("3p/wl.h")
|
||||
source.append_text("#define CRYPT_BLOWFISH_NOINCLUDE")
|
||||
source.append_file("3p/chttp.h")
|
||||
source.append_file("3p/chttp.c")
|
||||
source.append_file("3p/crypt_blowfish.h")
|
||||
source.append_file("3p/crypt_blowfish.c")
|
||||
source.append_file("3p/wl.h")
|
||||
source.append_file("3p/wl.c")
|
||||
source.append_file("src/main.c")
|
||||
source.save("cweb.c")
|
||||
|
||||
@@ -1,101 +1,7 @@
|
||||
#include "cweb.h"
|
||||
#define WL_NOINCLUDE
|
||||
#define HTTP_NOINCLUDE
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3p/wl.h
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct WL_Runtime WL_Runtime;
|
||||
typedef struct WL_Compiler WL_Compiler;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
} WL_String;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
int cur;
|
||||
} WL_Arena;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
} WL_Program;
|
||||
|
||||
typedef enum {
|
||||
WL_ADD_ERROR,
|
||||
WL_ADD_AGAIN,
|
||||
WL_ADD_LINK,
|
||||
} WL_AddResultType;
|
||||
|
||||
typedef struct {
|
||||
WL_AddResultType type;
|
||||
WL_String path;
|
||||
} WL_AddResult;
|
||||
|
||||
typedef enum {
|
||||
WL_EVAL_NONE,
|
||||
WL_EVAL_DONE,
|
||||
WL_EVAL_ERROR,
|
||||
WL_EVAL_OUTPUT,
|
||||
WL_EVAL_SYSVAR,
|
||||
WL_EVAL_SYSCALL,
|
||||
} WL_EvalResultType;
|
||||
|
||||
typedef struct {
|
||||
WL_EvalResultType type;
|
||||
WL_String str;
|
||||
} WL_EvalResult;
|
||||
|
||||
WL_Compiler* wl_compiler_init (WL_Arena *arena);
|
||||
WL_AddResult wl_compiler_add (WL_Compiler *compiler, WL_String content);
|
||||
int wl_compiler_link (WL_Compiler *compiler, WL_Program *program);
|
||||
WL_String wl_compiler_error (WL_Compiler *compiler);
|
||||
int wl_dump_ast (WL_Compiler *compiler, char *dst, int cap);
|
||||
void wl_dump_program (WL_Program program);
|
||||
|
||||
WL_Runtime* wl_runtime_init (WL_Arena *arena, WL_Program program);
|
||||
WL_EvalResult wl_runtime_eval (WL_Runtime *rt);
|
||||
WL_String wl_runtime_error (WL_Runtime *rt);
|
||||
void wl_runtime_dump (WL_Runtime *rt);
|
||||
|
||||
bool wl_streq (WL_String a, char *b, int blen);
|
||||
int wl_arg_count (WL_Runtime *rt);
|
||||
bool wl_arg_none (WL_Runtime *rt, int idx);
|
||||
bool wl_arg_bool (WL_Runtime *rt, int idx, bool *x);
|
||||
bool wl_arg_s64 (WL_Runtime *rt, int idx, int64_t *x);
|
||||
bool wl_arg_f64 (WL_Runtime *rt, int idx, double *x);
|
||||
bool wl_arg_str (WL_Runtime *rt, int idx, WL_String *x);
|
||||
bool wl_arg_array (WL_Runtime *rt, int idx);
|
||||
bool wl_arg_map (WL_Runtime *rt, int idx);
|
||||
bool wl_peek_none (WL_Runtime *rt, int off);
|
||||
bool wl_peek_bool (WL_Runtime *rt, int off, bool *x);
|
||||
bool wl_peek_s64 (WL_Runtime *rt, int off, int64_t *x);
|
||||
bool wl_peek_f64 (WL_Runtime *rt, int off, double *x);
|
||||
bool wl_peek_str (WL_Runtime *rt, int off, WL_String *x);
|
||||
bool wl_pop_any (WL_Runtime *rt);
|
||||
bool wl_pop_none (WL_Runtime *rt);
|
||||
bool wl_pop_bool (WL_Runtime *rt, bool *x);
|
||||
bool wl_pop_s64 (WL_Runtime *rt, int64_t *x);
|
||||
bool wl_pop_f64 (WL_Runtime *rt, double *x);
|
||||
bool wl_pop_str (WL_Runtime *rt, WL_String *x);
|
||||
void wl_push_none (WL_Runtime *rt);
|
||||
void wl_push_true (WL_Runtime *rt);
|
||||
void wl_push_false (WL_Runtime *rt);
|
||||
void wl_push_s64 (WL_Runtime *rt, int64_t x);
|
||||
void wl_push_f64 (WL_Runtime *rt, double x);
|
||||
void wl_push_str (WL_Runtime *rt, WL_String x);
|
||||
void wl_push_array (WL_Runtime *rt, int cap);
|
||||
void wl_push_map (WL_Runtime *rt, int cap);
|
||||
void wl_push_arg (WL_Runtime *rt, int idx);
|
||||
void wl_insert (WL_Runtime *rt);
|
||||
void wl_append (WL_Runtime *rt);
|
||||
|
||||
#define CRYPT_BLOWFISH_NOINCLUDE
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3p/chttp.h
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -6284,8 +6190,10 @@ extern char *_crypt_gensalt_blowfish_rn(const char *prefix,
|
||||
#define __set_errno(val) errno = (val)
|
||||
#endif
|
||||
|
||||
#ifndef CRYPT_BLOWFISH_NOINCLUDE
|
||||
/* Just to make sure the prototypes match the actual definitions */
|
||||
#include "crypt_blowfish.h"
|
||||
#endif // CRYPT_BLOWFISH_NOINCLUDE
|
||||
|
||||
#ifdef __i386__
|
||||
#define BF_ASM 1
|
||||
@@ -7140,6 +7048,101 @@ char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
|
||||
return output;
|
||||
}
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3p/wl.h
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
typedef struct WL_Runtime WL_Runtime;
|
||||
typedef struct WL_Compiler WL_Compiler;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
} WL_String;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
int cur;
|
||||
} WL_Arena;
|
||||
|
||||
typedef struct {
|
||||
char *ptr;
|
||||
int len;
|
||||
} WL_Program;
|
||||
|
||||
typedef enum {
|
||||
WL_ADD_ERROR,
|
||||
WL_ADD_AGAIN,
|
||||
WL_ADD_LINK,
|
||||
} WL_AddResultType;
|
||||
|
||||
typedef struct {
|
||||
WL_AddResultType type;
|
||||
WL_String path;
|
||||
} WL_AddResult;
|
||||
|
||||
typedef enum {
|
||||
WL_EVAL_NONE,
|
||||
WL_EVAL_DONE,
|
||||
WL_EVAL_ERROR,
|
||||
WL_EVAL_OUTPUT,
|
||||
WL_EVAL_SYSVAR,
|
||||
WL_EVAL_SYSCALL,
|
||||
} WL_EvalResultType;
|
||||
|
||||
typedef struct {
|
||||
WL_EvalResultType type;
|
||||
WL_String str;
|
||||
} WL_EvalResult;
|
||||
|
||||
WL_Compiler* wl_compiler_init (WL_Arena *arena);
|
||||
WL_AddResult wl_compiler_add (WL_Compiler *compiler, WL_String content);
|
||||
int wl_compiler_link (WL_Compiler *compiler, WL_Program *program);
|
||||
WL_String wl_compiler_error (WL_Compiler *compiler);
|
||||
int wl_dump_ast (WL_Compiler *compiler, char *dst, int cap);
|
||||
void wl_dump_program (WL_Program program);
|
||||
|
||||
WL_Runtime* wl_runtime_init (WL_Arena *arena, WL_Program program);
|
||||
WL_EvalResult wl_runtime_eval (WL_Runtime *rt);
|
||||
WL_String wl_runtime_error (WL_Runtime *rt);
|
||||
void wl_runtime_dump (WL_Runtime *rt);
|
||||
|
||||
bool wl_streq (WL_String a, char *b, int blen);
|
||||
int wl_arg_count (WL_Runtime *rt);
|
||||
bool wl_arg_none (WL_Runtime *rt, int idx);
|
||||
bool wl_arg_bool (WL_Runtime *rt, int idx, bool *x);
|
||||
bool wl_arg_s64 (WL_Runtime *rt, int idx, int64_t *x);
|
||||
bool wl_arg_f64 (WL_Runtime *rt, int idx, double *x);
|
||||
bool wl_arg_str (WL_Runtime *rt, int idx, WL_String *x);
|
||||
bool wl_arg_array (WL_Runtime *rt, int idx);
|
||||
bool wl_arg_map (WL_Runtime *rt, int idx);
|
||||
bool wl_peek_none (WL_Runtime *rt, int off);
|
||||
bool wl_peek_bool (WL_Runtime *rt, int off, bool *x);
|
||||
bool wl_peek_s64 (WL_Runtime *rt, int off, int64_t *x);
|
||||
bool wl_peek_f64 (WL_Runtime *rt, int off, double *x);
|
||||
bool wl_peek_str (WL_Runtime *rt, int off, WL_String *x);
|
||||
bool wl_pop_any (WL_Runtime *rt);
|
||||
bool wl_pop_none (WL_Runtime *rt);
|
||||
bool wl_pop_bool (WL_Runtime *rt, bool *x);
|
||||
bool wl_pop_s64 (WL_Runtime *rt, int64_t *x);
|
||||
bool wl_pop_f64 (WL_Runtime *rt, double *x);
|
||||
bool wl_pop_str (WL_Runtime *rt, WL_String *x);
|
||||
void wl_push_none (WL_Runtime *rt);
|
||||
void wl_push_true (WL_Runtime *rt);
|
||||
void wl_push_false (WL_Runtime *rt);
|
||||
void wl_push_s64 (WL_Runtime *rt, int64_t x);
|
||||
void wl_push_f64 (WL_Runtime *rt, double x);
|
||||
void wl_push_str (WL_Runtime *rt, WL_String x);
|
||||
void wl_push_array (WL_Runtime *rt, int cap);
|
||||
void wl_push_map (WL_Runtime *rt, int cap);
|
||||
void wl_push_arg (WL_Runtime *rt, int idx);
|
||||
void wl_insert (WL_Runtime *rt);
|
||||
void wl_append (WL_Runtime *rt);
|
||||
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
// 3p/wl.c
|
||||
////////////////////////////////////////////////////////////////////////////////////////
|
||||
@@ -7149,7 +7152,10 @@ char *_crypt_gensalt_blowfish_rn(const char *prefix, unsigned long count,
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
|
||||
#ifndef WL_NOINCLUDE
|
||||
#include "wl.h"
|
||||
#endif // WL_NOINCLUDE
|
||||
|
||||
/////////////////////////////////////////////////////////////////////////
|
||||
// BASIC
|
||||
@@ -13795,12 +13801,13 @@ CWEB_Request *cweb_wait(CWEB *cweb)
|
||||
CWEB_Request *req = &cweb->req;
|
||||
|
||||
int ret = http_server_wait(cweb->server, &req->req, &req->builder);
|
||||
if (ret < 0) return -1;
|
||||
if (ret < 0) return NULL;
|
||||
|
||||
HTTP_String sess_token = http_get_cookie(req->req, HTTP_STR("sess_token"));
|
||||
|
||||
req->arena = (WL_Arena) { cweb->pool, cweb->pool_cap, 0 };
|
||||
|
||||
req->just_created_session = false;
|
||||
req->sess = http_get_cookie(req->req, HTTP_STR("sess_token"));
|
||||
req->sess = (CWEB_String) { sess_token.ptr, sess_token.len };
|
||||
if (find_session(cweb->session_storage, req->sess, &req->csrf, &req->user_id) < 0) {
|
||||
req->user_id = -1;
|
||||
req->sess = (CWEB_String) { NULL, 0 };
|
||||
@@ -13978,31 +13985,23 @@ static void evaluate_format(StaticOutputBuffer *out, CWEB_String format, CWEB_VA
|
||||
}
|
||||
}
|
||||
|
||||
static CWEB_String evaluate_format_for_request_impl(CWEB_Request *req, CWEB_String format, CWEB_VArgs args)
|
||||
CWEB_String cweb_format_impl(CWEB_Request *req, char *fmt, CWEB_VArgs args)
|
||||
{
|
||||
StaticOutputBuffer out = {
|
||||
.dst = req->arena.ptr + req->arena.cur,
|
||||
.cap = req->arena.len - req->arena.cur,
|
||||
.len = 0
|
||||
};
|
||||
evaluate_format(&out, format, args);
|
||||
evaluate_format(&out, (CWEB_String) { fmt, strlen(fmt) }, args);
|
||||
if (out.len > req->arena.len - req->arena.cur)
|
||||
return (CWEB_String) { NULL, 0 };
|
||||
req->arena.cur += out.len;
|
||||
return (CWEB_String) { out.dst, out.len };
|
||||
}
|
||||
#define evaluate_format_for_request(req, format, ...) evaluate_format_for_request_impl((req), (format), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
void cweb_respond_redirect_impl(CWEB_Request *req, CWEB_String target_format, CWEB_VArgs args)
|
||||
void cweb_respond_redirect_impl(CWEB_Request *req, CWEB_String target)
|
||||
{
|
||||
CWEB_String target = evaluate_format_for_request_impl(req, target_format, args);
|
||||
if (target.len == 0) {
|
||||
http_response_builder_status(req->builder, 500);
|
||||
http_response_builder_done(req->builder);
|
||||
return;
|
||||
}
|
||||
|
||||
CWEB_String location_header = evaluate_format_for_request(req, CWEB_STR("Location: {}"), target);
|
||||
CWEB_String location_header = cweb_format(req, "Location: {}", target);
|
||||
if (location_header.len == 0) {
|
||||
http_response_builder_status(req->builder, 500);
|
||||
http_response_builder_done(req->builder);
|
||||
|
||||
@@ -249,11 +249,12 @@ int cweb_get_param_i(CWEB_Request *req, CWEB_String name);
|
||||
//////////////////////////////////////
|
||||
// Response
|
||||
|
||||
void cweb_respond_basic(CWEB_Request *req, int status, CWEB_String content);
|
||||
void cweb_respond_redirect_impl(CWEB_Request *req, CWEB_String target_format, CWEB_VArgs args);
|
||||
void cweb_respond_template(CWEB_Request *req, int status, CWEB_String template_file, int resource_id);
|
||||
CWEB_String cweb_format_impl(CWEB_Request *req, char *fmt, CWEB_VArgs args);
|
||||
#define cweb_format(req, fmt, ...) cweb_format_impl((req), (fmt), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
#define cweb_respond_redirect(req, format, ...) cweb_respond_redirect_impl((req), (format), CWEB_VARGS(__VA_ARGS__))
|
||||
void cweb_respond_basic(CWEB_Request *req, int status, CWEB_String content);
|
||||
void cweb_respond_redirect(CWEB_Request *req, CWEB_String target);
|
||||
void cweb_respond_template(CWEB_Request *req, int status, CWEB_String template_file, int resource_id);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Database
|
||||
|
||||
+2
-2
@@ -259,7 +259,7 @@ static void endpoint_api_post(CWEB *cweb, CWEB_Request *req)
|
||||
}
|
||||
int post_id = (int) insert_id;
|
||||
|
||||
cweb_respond_redirect(req, CWEB_STR("/post?id={}"), post_id);
|
||||
cweb_respond_redirect(req, cweb_format(req, "/post?id={}", post_id));
|
||||
}
|
||||
|
||||
static void endpoint_api_comment(CWEB *cweb, CWEB_Request *req)
|
||||
@@ -294,7 +294,7 @@ static void endpoint_api_comment(CWEB *cweb, CWEB_Request *req)
|
||||
return;
|
||||
}
|
||||
|
||||
cweb_respond_redirect(req, CWEB_STR("/post?id={}"), parent_post);
|
||||
cweb_respond_redirect(req, cweb_format(req, "/post?id={}", parent_post));
|
||||
}
|
||||
|
||||
static void endpoint_index(CWEB *cweb, CWEB_Request *req)
|
||||
|
||||
+22
-15
@@ -836,7 +836,11 @@ bool cweb_match_endpoint(CWEB_Request *req, CWEB_String str)
|
||||
|
||||
CWEB_String cweb_get_param_s(CWEB_Request *req, CWEB_String name)
|
||||
{
|
||||
HTTP_String res = http_get_param(req->req->body,
|
||||
HTTP_String src = req->req->url.query;
|
||||
if (req->req->method == HTTP_METHOD_POST)
|
||||
src = req->req->body;
|
||||
|
||||
HTTP_String res = http_get_param(src,
|
||||
(HTTP_String) { name.ptr, name.len },
|
||||
req->arena.ptr + req->arena.cur,
|
||||
req->arena.len - req->arena.cur
|
||||
@@ -848,7 +852,11 @@ CWEB_String cweb_get_param_s(CWEB_Request *req, CWEB_String name)
|
||||
|
||||
int cweb_get_param_i(CWEB_Request *req, CWEB_String name)
|
||||
{
|
||||
return http_get_param_i(req->req->body, (HTTP_String) { name.ptr, name.len });
|
||||
HTTP_String src = req->req->url.query;
|
||||
if (req->req->method == HTTP_METHOD_POST)
|
||||
src = req->req->body;
|
||||
|
||||
return http_get_param_i(src, (HTTP_String) { name.ptr, name.len });
|
||||
}
|
||||
|
||||
static int set_auth_cookie_if_necessary(CWEB_Request *req)
|
||||
@@ -997,31 +1005,23 @@ static void evaluate_format(StaticOutputBuffer *out, CWEB_String format, CWEB_VA
|
||||
}
|
||||
}
|
||||
|
||||
static CWEB_String evaluate_format_for_request_impl(CWEB_Request *req, CWEB_String format, CWEB_VArgs args)
|
||||
CWEB_String cweb_format_impl(CWEB_Request *req, char *fmt, CWEB_VArgs args)
|
||||
{
|
||||
StaticOutputBuffer out = {
|
||||
.dst = req->arena.ptr + req->arena.cur,
|
||||
.cap = req->arena.len - req->arena.cur,
|
||||
.len = 0
|
||||
};
|
||||
evaluate_format(&out, format, args);
|
||||
evaluate_format(&out, (CWEB_String) { fmt, strlen(fmt) }, args);
|
||||
if (out.len > req->arena.len - req->arena.cur)
|
||||
return (CWEB_String) { NULL, 0 };
|
||||
req->arena.cur += out.len;
|
||||
return (CWEB_String) { out.dst, out.len };
|
||||
}
|
||||
#define evaluate_format_for_request(req, format, ...) evaluate_format_for_request_impl((req), (format), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
void cweb_respond_redirect_impl(CWEB_Request *req, CWEB_String target_format, CWEB_VArgs args)
|
||||
void cweb_respond_redirect(CWEB_Request *req, CWEB_String target)
|
||||
{
|
||||
CWEB_String target = evaluate_format_for_request_impl(req, target_format, args);
|
||||
if (target.len == 0) {
|
||||
http_response_builder_status(req->builder, 500);
|
||||
http_response_builder_done(req->builder);
|
||||
return;
|
||||
}
|
||||
|
||||
CWEB_String location_header = evaluate_format_for_request(req, CWEB_STR("Location: {}"), target);
|
||||
CWEB_String location_header = cweb_format(req, "Location: {}", target);
|
||||
if (location_header.len == 0) {
|
||||
http_response_builder_status(req->builder, 500);
|
||||
http_response_builder_done(req->builder);
|
||||
@@ -1342,7 +1342,7 @@ static int query_routine(WL_Runtime *rt, SQLiteCache *dbcache)
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void push_sysvar(WL_Runtime *rt, WL_String name, SQLiteCache *dbcache, HTTP_String csrf, int user_id, int resource_id)
|
||||
static void push_sysvar(WL_Runtime *rt, WL_String name, SQLiteCache *dbcache, CWEB_String csrf, int user_id, int resource_id)
|
||||
{
|
||||
(void) dbcache;
|
||||
|
||||
@@ -1410,6 +1410,13 @@ static int get_or_create_program(TemplateCache *cache, WL_String path, WL_Arena
|
||||
void cweb_respond_template(CWEB_Request *req, int status, CWEB_String template_file, int resource_id)
|
||||
{
|
||||
http_response_builder_status(req->builder, status);
|
||||
int ret = set_auth_cookie_if_necessary(req);
|
||||
if (ret < 0) {
|
||||
http_response_builder_undo(req->builder);
|
||||
http_response_builder_status(req->builder, -ret);
|
||||
http_response_builder_done(req->builder);
|
||||
return;
|
||||
}
|
||||
|
||||
WL_Program program;
|
||||
int ret = get_or_create_program(req->cweb->tpcache, template_file, &req->arena, &program);
|
||||
|
||||
+50
-23
@@ -221,49 +221,76 @@ void cweb_free(CWEB *cweb);
|
||||
|
||||
int cweb_enable_database(CWEB *cweb, CWEB_String file);
|
||||
|
||||
// Pause execution until a request is available.
|
||||
// TODO: When does this function return NULL?
|
||||
CWEB_Request *cweb_wait(CWEB *cweb);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Session
|
||||
// Returns true iff the request matches the specified endpoint
|
||||
bool cweb_match_endpoint(CWEB_Request *req, CWEB_String str);
|
||||
|
||||
// Returns the CSRF token associated to the current session
|
||||
CWEB_String cweb_get_session_csrf(CWEB_Request *req);
|
||||
|
||||
// Returns the user ID for the current session, or -1 if there is no session
|
||||
int cweb_get_session_user_id(CWEB_Request *req);
|
||||
|
||||
// Sets the user ID for the current session (it must be a positive integer).
|
||||
// If the ID is -1, the session is deleted.
|
||||
int cweb_set_session_user_id(CWEB_Request *req, int user_id);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Request
|
||||
|
||||
bool cweb_match_endpoint(CWEB_Request *req, CWEB_String str);
|
||||
// Returns the request parameter with the specified name
|
||||
// If the request uses POST, the parameter is taken from the body,
|
||||
// else it's taken from the URL. If the parameter is not present,
|
||||
// an empty string is returned.
|
||||
CWEB_String cweb_get_param_s(CWEB_Request *req, CWEB_String name);
|
||||
|
||||
// Like cweb_get_param_s, but also parser the argument as an integer.
|
||||
// If parsing fails or the parameter is missing, -1 is returned.
|
||||
int cweb_get_param_i(CWEB_Request *req, CWEB_String name);
|
||||
|
||||
//////////////////////////////////////
|
||||
// Response
|
||||
// Create a string by evaluating a format. Memory is allocated from the arena of the request.
|
||||
// If the arena is full, an empty string is returned.
|
||||
CWEB_String cweb_format_impl(CWEB_Request *req, char *fmt, CWEB_VArgs args);
|
||||
|
||||
// Helper
|
||||
#define cweb_format(req, fmt, ...) cweb_format_impl((req), (fmt), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
// Responds to the specified request with the given status code and content
|
||||
void cweb_respond_basic(CWEB_Request *req, int status, CWEB_String content);
|
||||
void cweb_respond_redirect_impl(CWEB_Request *req, CWEB_String target_format, CWEB_VArgs args);
|
||||
|
||||
// Responds to the request by redirecting the client to the given target
|
||||
void cweb_respond_redirect(CWEB_Request *req, CWEB_String target);
|
||||
|
||||
// Responds to the request by evaluating a WL template file
|
||||
void cweb_respond_template(CWEB_Request *req, int status, CWEB_String template_file, int resource_id);
|
||||
|
||||
#define cweb_respond_redirect(req, format, ...) cweb_respond_redirect_impl((req), (format), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////
|
||||
// Database
|
||||
|
||||
typedef struct {
|
||||
void *handle;
|
||||
} CWEB_QueryResult;
|
||||
|
||||
// Evaluates an SQL INSERT statement and returns the ID of the last inserted row. On error -1 is returned
|
||||
int64_t cweb_database_insert_impl(CWEB *cweb, const char *fmt, CWEB_VArgs args);
|
||||
CWEB_QueryResult cweb_database_select_impl(CWEB *cweb, const char *fmt, CWEB_VArgs args);
|
||||
int cweb_next_query_row_impl(CWEB_QueryResult *res, CWEB_VArgs args);
|
||||
void cweb_free_query_result(CWEB_QueryResult *res);
|
||||
|
||||
// Helper
|
||||
#define cweb_database_insert(cweb, fmt, ...) cweb_database_insert_impl((cweb), (fmt), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
// Iterator over database rows
|
||||
typedef struct { void *handle; } CWEB_QueryResult;
|
||||
|
||||
// Evaluates an SQL SELECT statement, returning a scanner over the returned rows.
|
||||
// You don't have to check for errors with this function
|
||||
CWEB_QueryResult cweb_database_select_impl(CWEB *cweb, const char *fmt, CWEB_VArgs args);
|
||||
|
||||
// Helper
|
||||
#define cweb_database_select(cweb, fmt, ...) cweb_database_select_impl((cweb), (fmt), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
// Returns the next row from the query result iterator.
|
||||
int cweb_next_query_row_impl(CWEB_QueryResult *res, CWEB_VArgs args);
|
||||
|
||||
// Helper
|
||||
#define cweb_next_query_row(res, ...) cweb_next_query_row_impl((res), CWEB_VARGS(__VA_ARGS__))
|
||||
|
||||
//////////////////////////////////////
|
||||
// Password
|
||||
// Frees the result of a database query
|
||||
void cweb_free_query_result(CWEB_QueryResult *res);
|
||||
|
||||
// Calculates the bcrypt hash of the specified password
|
||||
int cweb_hash_password(char *pass, int passlen, int cost, CWEB_PasswordHash *hash);
|
||||
|
||||
// Checks whether the password matches the given hash
|
||||
int cweb_check_password(char *pass, int passlen, CWEB_PasswordHash hash);
|
||||
|
||||
@@ -1,22 +0,0 @@
|
||||
// Helper macros
|
||||
#define __CWEB_HELPER_DISPATCH_N(_0, _1, _2, _3, _4, _5, _6, _7, _8, _9, _10, _11, _12, _13, _14, _15, _16, N, ...) N
|
||||
#define __CWEB_HELPER_CONCAT_0(A, B) A ## B
|
||||
#define __CWEB_HELPER_CONCAT_1(A, B) __CWEB_HELPER_CONCAT_0(A, B)
|
||||
#define __CWEB_HELPER_ARG(a) (a)
|
||||
#define __CWEB_HELPER_ARGS_0() (CWEB_VArgs) { 0 }
|
||||
#define __CWEB_HELPER_ARGS_1(a) (CWEB_VArgs) { 1, __CWEB_HELPER_ARG(a) }
|
||||
#define __CWEB_HELPER_ARGS_2(a, b) (CWEB_VArgs) { 2, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b) }
|
||||
#define __CWEB_HELPER_ARGS_3(a, b, c) (CWEB_VArgs) { 3, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c) }
|
||||
#define __CWEB_HELPER_ARGS_4(a, b, c, d) (CWEB_VArgs) { 4, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d) }
|
||||
#define __CWEB_HELPER_ARGS_5(a, b, c, d, e) (CWEB_VArgs) { 5, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e) }
|
||||
#define __CWEB_HELPER_ARGS_6(a, b, c, d, e, f) (CWEB_VArgs) { 6, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e), __CWEB_HELPER_ARG(f) }
|
||||
#define __CWEB_HELPER_ARGS_7(a, b, c, d, e, f, g) (CWEB_VArgs) { 7, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e), __CWEB_HELPER_ARG(f), __CWEB_HELPER_ARG(g) }
|
||||
#define __CWEB_HELPER_ARGS_8(a, b, c, d, e, f, g, h) (CWEB_VArgs) { 8, __CWEB_HELPER_ARG(a), __CWEB_HELPER_ARG(b), __CWEB_HELPER_ARG(c), __CWEB_HELPER_ARG(d), __CWEB_HELPER_ARG(e), __CWEB_HELPER_ARG(f), __CWEB_HELPER_ARG(g), __CWEB_HELPER_ARG(h) }
|
||||
#define __CWEB_COUNT_ARGS(...) __CWEB_HELPER_DISPATCH_N(DUMMY, ##__VA_ARGS__, 16, 15, 14, 13, 12, 11, 10, 9, 8, 7, 6, 5, 4, 3, 2, 1, 0)
|
||||
|
||||
#define CWEB_ARGS(...) __CWEB_HELPER_CONCAT_1(__CWEB_HELPER_ARGS_, __CWEB_COUNT_ARGS(__VA_ARGS__))(__VA_ARGS__)
|
||||
|
||||
CWEB_ARGS()
|
||||
CWEB_ARGS(1)
|
||||
CWEB_ARGS(1, 2)
|
||||
CWEB_ARGS(1, 2, 3)
|
||||
Reference in New Issue
Block a user