@velox0/cerver 0.4.0 → 0.4.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/runtime/cerver.h CHANGED
@@ -6,6 +6,16 @@
6
6
  * the route dispatch interface.
7
7
  */
8
8
 
9
+ /*
10
+ * Feature test macros for POSIX/GNU APIs used by the runtime.
11
+ * Must be defined before any system headers.
12
+ */
13
+ #if defined(__linux__)
14
+ #ifndef _GNU_SOURCE
15
+ #define _GNU_SOURCE
16
+ #endif
17
+ #endif
18
+
9
19
  #ifndef CERVER_H
10
20
  #define CERVER_H
11
21
 
@@ -17,38 +27,40 @@
17
27
  /* Limits */
18
28
  /* ------------------------------------------------------------------ */
19
29
 
20
- #define CERVER_MAX_HEADERS 64
21
- #define CERVER_MAX_PARAMS 16
22
- #define CERVER_MAX_QUERY 32
23
- #define CERVER_MAX_PATH 2048
24
- #define CERVER_MAX_HEADER_VAL 4096
25
- #define CERVER_READ_BUF 8192
26
- #define CERVER_READ_BUF_MAX (1 << 20) /* 1 MB hard limit */
27
- #define CERVER_MAX_ROUTES 256
30
+ #define CERVER_MAX_HEADERS 64
31
+ #define CERVER_MAX_PARAMS 16
32
+ #define CERVER_MAX_QUERY 32
33
+ #define CERVER_MAX_PATH 2048
34
+ #define CERVER_MAX_HEADER_VAL 4096
35
+ #define CERVER_READ_BUF 8192
36
+ #define CERVER_READ_BUF_MAX (1 << 20) /* 1 MB hard limit */
37
+ #define CERVER_MAX_ROUTES 256
28
38
 
29
39
  /* Keep-alive settings */
30
- #define CERVER_KEEPALIVE_MAX 10000 /* max requests per connection */
31
- #define CERVER_KEEPALIVE_TIMEOUT 5 /* seconds idle between requests */
40
+ #define CERVER_KEEPALIVE_MAX 2000000000 /* max requests per connection */
41
+ #define CERVER_KEEPALIVE_TIMEOUT 5 /* seconds idle between requests */
42
+ #define CERVER_KEEPALIVE_MAX 2000000000 /* max requests per connection */
43
+ #define CERVER_KEEPALIVE_TIMEOUT 5 /* seconds idle between requests */
32
44
 
33
45
  /* Event loop tuning */
34
- #define CERVER_MAX_EVENTS 256
35
- #define CERVER_LISTEN_BACKLOG 4096
46
+ #define CERVER_MAX_EVENTS 256
47
+ #define CERVER_LISTEN_BACKLOG 4096
36
48
 
37
49
  /* Worker architecture */
38
- #define CERVER_THREAD_POOL_DEFAULT 4
39
- #define CERVER_TASK_QUEUE_SIZE 1024
50
+ #define CERVER_THREAD_POOL_DEFAULT 4
51
+ #define CERVER_TASK_QUEUE_SIZE 1024
40
52
 
41
53
  /* Stat cache for filesystem serving */
42
- #define CERVER_STAT_CACHE_SIZE 256
43
- #define CERVER_STAT_CACHE_TTL 60 /* seconds */
54
+ #define CERVER_STAT_CACHE_SIZE 256
55
+ #define CERVER_STAT_CACHE_TTL 60 /* seconds */
44
56
 
45
57
  /* ------------------------------------------------------------------ */
46
58
  /* Key-value pair (used for headers, query params, route params) */
47
59
  /* ------------------------------------------------------------------ */
48
60
 
49
61
  typedef struct {
50
- const char *key;
51
- const char *value;
62
+ const char* key;
63
+ const char* value;
52
64
  } cerver_kv_t;
53
65
 
54
66
  /* ------------------------------------------------------------------ */
@@ -56,34 +68,34 @@ typedef struct {
56
68
  /* ------------------------------------------------------------------ */
57
69
 
58
70
  typedef struct {
59
- /* HTTP method: "GET", "POST", etc. */
60
- char method[16];
71
+ /* HTTP method: "GET", "POST", etc. */
72
+ char method[16];
61
73
 
62
- /* Decoded path (no query string) */
63
- char path[CERVER_MAX_PATH];
74
+ /* Decoded path (no query string) */
75
+ char path[CERVER_MAX_PATH];
64
76
 
65
- /* Raw query string (after '?') */
66
- char query_string[CERVER_MAX_PATH];
77
+ /* Raw query string (after '?') */
78
+ char query_string[CERVER_MAX_PATH];
67
79
 
68
- /* Parsed query parameters */
69
- cerver_kv_t query[CERVER_MAX_QUERY];
70
- int query_count;
80
+ /* Parsed query parameters */
81
+ cerver_kv_t query[CERVER_MAX_QUERY];
82
+ int query_count;
71
83
 
72
- /* Route parameters (from dynamic segments like :key) */
73
- cerver_kv_t params[CERVER_MAX_PARAMS];
74
- int params_count;
84
+ /* Route parameters (from dynamic segments like :key) */
85
+ cerver_kv_t params[CERVER_MAX_PARAMS];
86
+ int params_count;
75
87
 
76
- /* Request headers */
77
- cerver_kv_t headers[CERVER_MAX_HEADERS];
78
- int header_count;
88
+ /* Request headers */
89
+ cerver_kv_t headers[CERVER_MAX_HEADERS];
90
+ int header_count;
79
91
 
80
- /* Request body (for POST) */
81
- const char *body;
82
- size_t body_len;
92
+ /* Request body (for POST) */
93
+ const char* body;
94
+ size_t body_len;
83
95
 
84
- /* Internal: raw buffer ownership (NULL if in-place parsing used) */
85
- char *_raw_buf;
86
- size_t _raw_len;
96
+ /* Internal: raw buffer ownership (NULL if in-place parsing used) */
97
+ char* _raw_buf;
98
+ size_t _raw_len;
87
99
  } cerver_request_t;
88
100
 
89
101
  /* ------------------------------------------------------------------ */
@@ -91,53 +103,53 @@ typedef struct {
91
103
  /* ------------------------------------------------------------------ */
92
104
 
93
105
  typedef struct {
94
- int status;
95
- const char *content_type;
106
+ int status;
107
+ const char* content_type;
96
108
 
97
- /* Response body — can be heap-allocated or static */
98
- const char *body;
99
- size_t body_len;
109
+ /* Response body — can be heap-allocated or static */
110
+ const char* body;
111
+ size_t body_len;
100
112
 
101
- /* Extra headers */
102
- cerver_kv_t headers[CERVER_MAX_HEADERS];
103
- int header_count;
113
+ /* Extra headers */
114
+ cerver_kv_t headers[CERVER_MAX_HEADERS];
115
+ int header_count;
104
116
 
105
- /* Internal flag: was body malloc'd? */
106
- int _body_owned;
117
+ /* Internal flag: was body malloc'd? */
118
+ int _body_owned;
107
119
 
108
- /* Keep-alive control: set to 1 to force close after response */
109
- int _force_close;
120
+ /* Keep-alive control: set to 1 to force close after response */
121
+ int _force_close;
110
122
  } cerver_response_t;
111
123
 
112
124
  /* Response helpers — called by generated handler code */
113
- void cerver_res_text(cerver_response_t *res, int status, const char *text);
114
- void cerver_res_json(cerver_response_t *res, int status, const char *json);
115
- void cerver_res_html(cerver_response_t *res, int status, const char *html);
116
- void cerver_res_file(cerver_response_t *res, int status, const char *mime,
117
- const unsigned char *data, size_t len);
118
- void cerver_res_header(cerver_response_t *res, const char *key, const char *val);
125
+ void cerver_res_text(cerver_response_t* res, int status, const char* text);
126
+ void cerver_res_json(cerver_response_t* res, int status, const char* json);
127
+ void cerver_res_html(cerver_response_t* res, int status, const char* html);
128
+ void cerver_res_file(cerver_response_t* res, int status, const char* mime,
129
+ const unsigned char* data, size_t len);
130
+ void cerver_res_header(cerver_response_t* res, const char* key, const char* val);
119
131
 
120
132
  /* ------------------------------------------------------------------ */
121
133
  /* Request helpers */
122
134
  /* ------------------------------------------------------------------ */
123
135
 
124
- const char *cerver_req_param(const cerver_request_t *req, const char *key);
125
- const char *cerver_req_query(const cerver_request_t *req, const char *key);
126
- const char *cerver_req_header(const cerver_request_t *req, const char *key);
136
+ const char* cerver_req_param(const cerver_request_t* req, const char* key);
137
+ const char* cerver_req_query(const cerver_request_t* req, const char* key);
138
+ const char* cerver_req_header(const cerver_request_t* req, const char* key);
127
139
 
128
140
  /* Check if client wants to close after this request */
129
- int cerver_req_wants_close(const cerver_request_t *req);
141
+ int cerver_req_wants_close(const cerver_request_t* req);
130
142
 
131
143
  /* ------------------------------------------------------------------ */
132
144
  /* Route definition */
133
145
  /* ------------------------------------------------------------------ */
134
146
 
135
- typedef void (*cerver_handler_fn)(cerver_request_t *req, cerver_response_t *res);
147
+ typedef void (*cerver_handler_fn)(cerver_request_t* req, cerver_response_t* res);
136
148
 
137
149
  typedef struct {
138
- const char *method; /* "GET", "POST" */
139
- const char *pattern; /* "/", "/art/:key", "/api/projects" */
140
- cerver_handler_fn handler;
150
+ const char* method; /* "GET", "POST" */
151
+ const char* pattern; /* "/", "/groups/:group_id", "/api/items" */
152
+ cerver_handler_fn handler;
141
153
  } cerver_route_t;
142
154
 
143
155
  /* ------------------------------------------------------------------ */
@@ -145,20 +157,20 @@ typedef struct {
145
157
  /* ------------------------------------------------------------------ */
146
158
 
147
159
  typedef struct {
148
- const char *path; /* e.g. "/index.html" */
149
- const char *mime_type; /* e.g. "text/html" */
150
- const unsigned char *data;
151
- size_t data_len;
152
-
153
- /* Pre-compressed variants (NULL if not available) */
154
- const unsigned char *data_gz;
155
- size_t data_gz_len;
156
- const unsigned char *data_br;
157
- size_t data_br_len;
158
-
159
- /* Pre-computed response header (NULL if not generated) */
160
- const char *prebuilt_header;
161
- size_t prebuilt_header_len;
160
+ const char* path; /* e.g. "/index.html" */
161
+ const char* mime_type; /* e.g. "text/html" */
162
+ const unsigned char* data;
163
+ size_t data_len;
164
+
165
+ /* Pre-compressed variants (NULL if not available) */
166
+ const unsigned char* data_gz;
167
+ size_t data_gz_len;
168
+ const unsigned char* data_br;
169
+ size_t data_br_len;
170
+
171
+ /* Pre-computed response header (NULL if not generated) */
172
+ const char* prebuilt_header;
173
+ size_t prebuilt_header_len;
162
174
  } cerver_asset_t;
163
175
 
164
176
  /* ------------------------------------------------------------------ */
@@ -166,23 +178,23 @@ typedef struct {
166
178
  /* ------------------------------------------------------------------ */
167
179
 
168
180
  typedef struct {
169
- char path[CERVER_MAX_PATH];
170
- size_t file_size;
171
- time_t mtime;
172
- time_t cached_at;
173
- int valid;
181
+ char path[CERVER_MAX_PATH];
182
+ size_t file_size;
183
+ time_t mtime;
184
+ time_t cached_at;
185
+ int valid;
174
186
  } cerver_stat_entry_t;
175
187
 
176
188
  typedef struct {
177
- cerver_stat_entry_t entries[CERVER_STAT_CACHE_SIZE];
178
- pthread_mutex_t lock;
189
+ cerver_stat_entry_t entries[CERVER_STAT_CACHE_SIZE];
190
+ pthread_mutex_t lock;
179
191
  } cerver_stat_cache_t;
180
192
 
181
193
  /* ------------------------------------------------------------------ */
182
194
  /* Generated dispatch (compile-time route optimization) */
183
195
  /* ------------------------------------------------------------------ */
184
196
 
185
- typedef cerver_handler_fn (*cerver_dispatch_fn)(cerver_request_t *req);
197
+ typedef cerver_handler_fn (*cerver_dispatch_fn)(cerver_request_t* req);
186
198
 
187
199
  /* ------------------------------------------------------------------ */
188
200
  /* Worker state (per-core event loop) */
@@ -191,11 +203,11 @@ typedef cerver_handler_fn (*cerver_dispatch_fn)(cerver_request_t *req);
191
203
  typedef struct cerver_server cerver_server_t;
192
204
 
193
205
  typedef struct {
194
- int id;
195
- int event_fd; /* kqueue or epoll fd */
196
- int listen_fd; /* per-worker on Linux, shared on macOS */
197
- cerver_server_t *srv;
198
- pthread_t thread;
206
+ int id;
207
+ int event_fd; /* kqueue or epoll fd */
208
+ int listen_fd; /* per-worker on Linux, shared on macOS */
209
+ cerver_server_t* srv;
210
+ pthread_t thread;
199
211
  } cerver_worker_t;
200
212
 
201
213
  /* ------------------------------------------------------------------ */
@@ -203,75 +215,73 @@ typedef struct {
203
215
  /* ------------------------------------------------------------------ */
204
216
 
205
217
  struct cerver_server {
206
- int port;
207
- int sock_fd;
208
- cerver_route_t *routes;
209
- int route_count;
210
- cerver_asset_t *assets;
211
- int asset_count;
212
- const char *public_dir; /* NULL if embedded mode */
213
- volatile int running;
214
-
215
- /* Generated dispatch override (faster than generic router) */
216
- cerver_dispatch_fn dispatch_override;
217
-
218
- /* Stat cache for filesystem serving */
219
- cerver_stat_cache_t stat_cache;
220
-
221
- /* Worker pool */
222
- int worker_count;
223
- cerver_worker_t *workers;
218
+ int port;
219
+ int sock_fd;
220
+ cerver_route_t* routes;
221
+ int route_count;
222
+ cerver_asset_t* assets;
223
+ int asset_count;
224
+ const char* public_dir; /* NULL if embedded mode */
225
+ volatile int running;
226
+
227
+ /* Generated dispatch override (faster than generic router) */
228
+ cerver_dispatch_fn dispatch_override;
229
+
230
+ /* Stat cache for filesystem serving */
231
+ cerver_stat_cache_t stat_cache;
232
+
233
+ /* Worker pool */
234
+ int worker_count;
235
+ cerver_worker_t* workers;
224
236
  };
225
237
 
226
238
  /* Server lifecycle */
227
- int cerver_init(cerver_server_t *srv, int port, int threads);
228
- int cerver_add_routes(cerver_server_t *srv, cerver_route_t *routes, int count);
229
- int cerver_set_assets(cerver_server_t *srv, cerver_asset_t *assets, int count);
230
- void cerver_set_public_dir(cerver_server_t *srv, const char *dir);
231
- void cerver_set_dispatch(cerver_server_t *srv, cerver_dispatch_fn fn);
232
- int cerver_listen(cerver_server_t *srv);
233
- void cerver_shutdown(cerver_server_t *srv);
239
+ int cerver_init(cerver_server_t* srv, int port, int threads);
240
+ int cerver_add_routes(cerver_server_t* srv, cerver_route_t* routes, int count);
241
+ int cerver_set_assets(cerver_server_t* srv, cerver_asset_t* assets, int count);
242
+ void cerver_set_public_dir(cerver_server_t* srv, const char* dir);
243
+ void cerver_set_dispatch(cerver_server_t* srv, cerver_dispatch_fn fn);
244
+ int cerver_listen(cerver_server_t* srv);
245
+ void cerver_shutdown(cerver_server_t* srv);
234
246
 
235
247
  /* ------------------------------------------------------------------ */
236
248
  /* HTTP parser (internal) */
237
249
  /* ------------------------------------------------------------------ */
238
250
 
239
- int cerver_parse_request(const char *raw, size_t len, cerver_request_t *req);
251
+ int cerver_parse_request(const char* raw, size_t len, cerver_request_t* req);
240
252
 
241
253
  /* ------------------------------------------------------------------ */
242
254
  /* HTTP writer (internal) */
243
255
  /* ------------------------------------------------------------------ */
244
256
 
245
- int cerver_write_response(int fd, const cerver_response_t *res, int keepalive);
257
+ int cerver_write_response(int fd, const cerver_response_t* res, int keepalive);
246
258
 
247
259
  /* ------------------------------------------------------------------ */
248
260
  /* Router (internal) */
249
261
  /* ------------------------------------------------------------------ */
250
262
 
251
- int cerver_route_match(const cerver_route_t *route, cerver_request_t *req);
252
- cerver_handler_fn cerver_dispatch(cerver_server_t *srv, cerver_request_t *req);
263
+ int cerver_route_match(const cerver_route_t* route, cerver_request_t* req);
264
+ cerver_handler_fn cerver_dispatch(cerver_server_t* srv, cerver_request_t* req);
253
265
 
254
266
  /* ------------------------------------------------------------------ */
255
267
  /* MIME (internal) */
256
268
  /* ------------------------------------------------------------------ */
257
269
 
258
- const char *cerver_mime_from_path(const char *path);
270
+ const char* cerver_mime_from_path(const char* path);
259
271
 
260
272
  /* ------------------------------------------------------------------ */
261
273
  /* Static file serving (internal) */
262
274
  /* ------------------------------------------------------------------ */
263
275
 
264
- int cerver_serve_static(cerver_server_t *srv, cerver_request_t *req,
265
- cerver_response_t *res);
276
+ int cerver_serve_static(cerver_server_t* srv, cerver_request_t* req, cerver_response_t* res);
266
277
 
267
278
  /* ------------------------------------------------------------------ */
268
279
  /* Stat cache (internal) */
269
280
  /* ------------------------------------------------------------------ */
270
281
 
271
- void cerver_stat_cache_init(cerver_stat_cache_t *cache);
272
- int cerver_stat_cache_lookup(cerver_stat_cache_t *cache, const char *path,
273
- size_t *file_size);
274
- void cerver_stat_cache_store(cerver_stat_cache_t *cache, const char *path,
275
- size_t file_size, time_t mtime);
282
+ void cerver_stat_cache_init(cerver_stat_cache_t* cache);
283
+ int cerver_stat_cache_lookup(cerver_stat_cache_t* cache, const char* path, size_t* file_size);
284
+ void cerver_stat_cache_store(cerver_stat_cache_t* cache, const char* path, size_t file_size,
285
+ time_t mtime);
276
286
 
277
287
  #endif /* CERVER_H */