Skip to content

Commit c44d58c

Browse files
committed
improve listener type safety + fix HTTP header cache hashing + minorities
1 parent 1c627fe commit c44d58c

File tree

7 files changed

+150
-90
lines changed

7 files changed

+150
-90
lines changed

fio-stl.h

Lines changed: 55 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -35380,31 +35380,32 @@ typedef struct fio_io_listen_args {
3538035380
uint8_t hide_from_log;
3538135381
} fio_io_listen_args;
3538235382

35383+
typedef struct fio_listener_s fio_listener_s;
3538335384
/**
3538435385
* Sets up a network service on a listening socket.
3538535386
*
3538635387
* Returns a self-destructible listener handle on success or NULL on error.
3538735388
*/
35388-
SFUNC void *fio_io_listen(fio_io_listen_args args);
35389+
SFUNC fio_listener_s *fio_io_listen(fio_io_listen_args args);
3538935390
#define fio_io_listen(...) fio_io_listen((fio_io_listen_args){__VA_ARGS__})
3539035391

3539135392
/** Notifies a listener to stop listening. */
35392-
SFUNC void fio_io_listen_stop(void *listener);
35393+
SFUNC void fio_io_listen_stop(fio_listener_s *l);
3539335394

3539435395
/** Returns the listener's associated protocol. */
35395-
SFUNC fio_io_protocol_s *fio_io_listener_protocol(void *listener);
35396+
SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_listener_s *l);
3539635397

3539735398
/** Returns the listener's associated `udata`. */
35398-
SFUNC void *fio_io_listener_udata(void *listener);
35399+
SFUNC void *fio_io_listener_udata(fio_listener_s *l);
3539935400

3540035401
/** Sets the listener's associated `udata`, returning the old value. */
35401-
SFUNC void *fio_io_listener_udata_set(void *listener, void *new_udata);
35402+
SFUNC void *fio_io_listener_udata_set(fio_listener_s *l, void *new_udata);
3540235403

3540335404
/** Returns the URL on which the listener is listening. */
35404-
SFUNC fio_buf_info_s fio_io_listener_url(void *listener);
35405+
SFUNC fio_buf_info_s fio_io_listener_url(fio_listener_s *l);
3540535406

3540635407
/** Returns true if the listener protocol has an attached TLS context. */
35407-
SFUNC int fio_io_listener_is_tls(void *listener);
35408+
SFUNC int fio_io_listener_is_tls(fio_listener_s *l);
3540835409

3540935410
/* *****************************************************************************
3541035411
Connecting as a Client
@@ -38259,37 +38260,38 @@ static void fio___io_listen_free(void *l_) {
3825938260
FIO_MEM_FREE_(l, sizeof(*l) + l->url_len + 1);
3826038261
}
3826138262

38262-
SFUNC void fio_io_listen_stop(void *listener) {
38263+
SFUNC void fio_io_listen_stop(fio_listener_s *listener) {
3826338264
if (listener)
38264-
fio___io_listen_free(listener);
38265+
fio___io_listen_free((fio___io_listen_s *)listener);
3826538266
}
3826638267

3826738268
/** Returns the URL on which the listener is listening. */
38268-
SFUNC fio_buf_info_s fio_io_listener_url(void *listener) {
38269+
SFUNC fio_buf_info_s fio_io_listener_url(fio_listener_s *listener) {
3826938270
fio___io_listen_s *l = (fio___io_listen_s *)listener;
3827038271
return FIO_BUF_INFO2(l->url, l->url_len);
3827138272
}
3827238273

3827338274
/** Returns true if the listener protocol has an attached TLS context. */
38274-
SFUNC int fio_io_listener_is_tls(void *listener) {
38275+
SFUNC int fio_io_listener_is_tls(fio_listener_s *listener) {
3827538276
fio___io_listen_s *l = (fio___io_listen_s *)listener;
3827638277
return !!l->tls_ctx;
3827738278
}
3827838279

3827938280
/** Returns the listener's associated protocol. */
38280-
SFUNC fio_io_protocol_s *fio_io_listener_protocol(void *listener) {
38281+
SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_listener_s *listener) {
3828138282
fio___io_listen_s *l = (fio___io_listen_s *)listener;
3828238283
return l->protocol;
3828338284
}
3828438285

3828538286
/** Returns the listener's associated `udata`. */
38286-
SFUNC void *fio_io_listener_udata(void *listener) {
38287+
SFUNC void *fio_io_listener_udata(fio_listener_s *listener) {
3828738288
fio___io_listen_s *l = (fio___io_listen_s *)listener;
3828838289
return l->udata;
3828938290
}
3829038291

3829138292
/** Sets the listener's associated `udata`, returning the old value. */
38292-
SFUNC void *fio_io_listener_udata_set(void *listener, void *new_udata) {
38293+
SFUNC void *fio_io_listener_udata_set(fio_listener_s *listener,
38294+
void *new_udata) {
3829338295
void *old;
3829438296
fio___io_listen_s *l = (fio___io_listen_s *)listener;
3829538297
old = l->udata;
@@ -38387,18 +38389,18 @@ int fio_io_listen___(void); /* IDE marker */
3838738389
*
3838838390
* See the `fio_listen` Macro for details.
3838938391
*/
38390-
SFUNC void *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
38392+
SFUNC fio_listener_s *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
3839138393
fio___io_listen_s *l = NULL;
3839238394
void *built_tls = NULL;
3839338395
int should_free_tls = !args.tls;
3839438396
FIO_STR_INFO_TMP_VAR(url_alt, 2048);
3839538397
if (!args.protocol) {
3839638398
FIO_LOG_ERROR("fio_io_listen requires a protocol to be assigned.");
38397-
return l;
38399+
return (fio_listener_s *)l;
3839838400
}
3839938401
if (args.on_root && !fio_io_is_master()) {
3840038402
FIO_LOG_ERROR("fio_io_listen called with `on_root` by a non-root worker.");
38401-
return l;
38403+
return (fio_listener_s *)l;
3840238404
}
3840338405
if (!args.url) {
3840438406
args.url = getenv("ADDRESS");
@@ -38422,7 +38424,7 @@ SFUNC void *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
3842238424
size_t port = fio_atomic_add(&port_counter, 1);
3842338425
if (port == 3000 && getenv("PORT")) {
3842438426
char *port_env = getenv("PORT");
38425-
port = fio_atol10(&port_env);
38427+
port = fio_atol(&port_env);
3842638428
if (!port | (port > 65535ULL))
3842738429
port = 3000;
3842838430
}
@@ -38471,7 +38473,7 @@ SFUNC void *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
3847138473
l->fd = fio_sock_open2(l->url, FIO_SOCK_SERVER | FIO_SOCK_TCP);
3847238474
if (l->fd == -1) {
3847338475
fio___io_listen_free(l);
38474-
return (l = NULL);
38476+
return (fio_listener_s *)(l = NULL);
3847538477
}
3847638478
if (fio_io_is_running()) {
3847738479
fio_io_defer(fio___io_listen_attach_task_deferred, l, NULL);
@@ -38482,7 +38484,7 @@ SFUNC void *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
3848238484
(void *)l);
3848338485
}
3848438486
fio_state_callback_add(FIO_CALL_AT_EXIT, fio___io_listen_free, l);
38485-
return l;
38487+
return (fio_listener_s *)l;
3848638488
}
3848738489

3848838490
/* *****************************************************************************
@@ -42787,17 +42789,17 @@ SFUNC fio_str_info_s fio_http_log_time(uint64_t now_in_seconds) {
4278742789
Helpers - fio_keystr_s memory allocation callbacks
4278842790
***************************************************************************** */
4278942791

42790-
FIO_LEAK_COUNTER_DEF(http___keystr_allocator)
42792+
FIO_LEAK_COUNTER_DEF(fio___http_keystr_allocator)
4279142793

4279242794
FIO_SFUNC void fio___http_keystr_free(void *ptr, size_t len) {
4279342795
if (!ptr)
4279442796
return;
42795-
FIO_LEAK_COUNTER_ON_FREE(http___keystr_allocator);
42797+
FIO_LEAK_COUNTER_ON_FREE(fio___http_keystr_allocator);
4279642798
FIO_MEM_FREE_(ptr, len);
4279742799
(void)len; /* if unused */
4279842800
}
4279942801
FIO_SFUNC void *fio___http_keystr_alloc(size_t capa) {
42800-
FIO_LEAK_COUNTER_ON_ALLOC(http___keystr_allocator);
42802+
FIO_LEAK_COUNTER_ON_ALLOC(fio___http_keystr_allocator);
4280142803
return FIO_MEM_REALLOC_(NULL, 0, capa, 0);
4280242804
}
4280342805

@@ -42917,10 +42919,10 @@ static uint32_t FIO___HTTP_STATIC_CACHE_IMAP[FIO___HTTP_STATIC_CACHE_CAPA];
4291742919

4291842920
static uint64_t fio___http_str_cached_hash(char *str, size_t len) {
4291942921
/* use low-case hash specific for the HTTP handle (change resilient) */
42920-
const fio_u256 primes = fio_u256_init64(FIO_U64_HASH_PRIME1,
42921-
FIO_U64_HASH_PRIME2,
42922-
FIO_U64_HASH_PRIME3,
42923-
FIO_U64_HASH_PRIME4);
42922+
const fio_u256 primes = fio_u256_init64(((uint64_t)0x84B56B93C869EA0F),
42923+
((uint64_t)0x613A19F5CB0D98D5),
42924+
((uint64_t)0x48644F7B3959621F),
42925+
((uint64_t)0x39664DEECA23D825));
4292442926
uint64_t hash = 0;
4292542927
if (len > 32)
4292642928
return hash;
@@ -43457,8 +43459,9 @@ Simple Property Set / Get
4345743459
SFUNC fio_str_info_s fio_http_##property##_set(fio_http_s *h, \
4345843460
fio_str_info_s value) { \
4345943461
FIO_ASSERT_DEBUG(h, "NULL HTTP handler!"); \
43460-
fio_keystr_destroy(&h->property, fio___http_keystr_free); \
43462+
fio_keystr_s old = h->property; /* delay destroy in case of copy/edit. */ \
4346143463
h->property = fio_keystr_init(value, fio___http_keystr_alloc); \
43464+
fio_keystr_destroy(&old, fio___http_keystr_free); \
4346243465
return fio_keystr_info(&h->property); \
4346343466
}
4346443467

@@ -46654,8 +46657,6 @@ typedef struct fio_http_settings_s {
4665446657
void (*on_http)(fio_http_s *h);
4665546658
/** Called when a request / response cycle is finished with no Upgrade. */
4665646659
void (*on_finish)(fio_http_s *h);
46657-
/** (optional) the callback to be performed when the HTTP service closes. */
46658-
void (*on_stop)(struct fio_http_settings_s *settings);
4665946660

4666046661
/** Authenticate EventSource (SSE) requests, return non-zero to deny.*/
4666146662
int (*on_authenticate_sse)(fio_http_s *h);
@@ -46682,8 +46683,12 @@ typedef struct fio_http_settings_s {
4668246683
/** Called after a WebSocket / SSE connection is closed (for cleanup). */
4668346684
void (*on_close)(fio_http_s *h);
4668446685

46686+
/** (optional) the callback to be performed when the HTTP service closes. */
46687+
void (*on_stop)(struct fio_http_settings_s *settings);
46688+
4668546689
/** Default opaque user data for HTTP handles (fio_http_s). */
4668646690
void *udata;
46691+
4668746692
/** Optional SSL/TLS support. */
4668846693
fio_io_functions_s *tls_io_func;
4668946694
/** Optional SSL/TLS support. */
@@ -46766,15 +46771,19 @@ typedef struct fio_http_settings_s {
4676646771
uint8_t log;
4676746772
} fio_http_settings_s;
4676846773

46774+
/* a pointer safety type */
46775+
typedef struct fio_http_listener_s fio_http_listener_s;
46776+
4676946777
/** Listens to HTTP / WebSockets / SSE connections on `url`. */
46770-
SFUNC void *fio_http_listen(const char *url, fio_http_settings_s settings);
46778+
SFUNC fio_http_listener_s *fio_http_listen(const char *url,
46779+
fio_http_settings_s settings);
4677146780

4677246781
/** Listens to HTTP / WebSockets / SSE connections on `url`. */
4677346782
#define fio_http_listen(url, ...) \
4677446783
fio_http_listen(url, (fio_http_settings_s){__VA_ARGS__})
4677546784

4677646785
/** Returns the a pointer to the HTTP settings associated with the listener. */
46777-
SFUNC fio_http_settings_s *fio_http_listener_settings(void *listener);
46786+
SFUNC fio_http_settings_s *fio_http_listener_settings(fio_http_listener_s *l);
4677846787

4677946788
/** Allows all clients to connect (bypasses authentication). */
4678046789
SFUNC int FIO_HTTP_AUTHENTICATE_ALLOW(fio_http_s *h);
@@ -47379,11 +47388,21 @@ static void fio___http_listen_on_stop(fio_io_protocol_s *p, void *u) {
4737947388
}
4738047389

4738147390
void fio_http_listen___(void); /* IDE marker */
47382-
SFUNC void *fio_http_listen FIO_NOOP(const char *url, fio_http_settings_s s) {
47391+
SFUNC fio_http_listener_s *fio_http_listen FIO_NOOP(const char *url,
47392+
fio_http_settings_s s) {
4738347393
http_settings_validate(&s, 0);
47394+
if (url) {
47395+
fio_url_s u = fio_url_parse(url, FIO_STRLEN(url));
47396+
if (u.path.len)
47397+
FIO_LOG_WARNING(
47398+
"HTTP listener is always at the root (home folder).\n\t"
47399+
" Ignoring the path set in the listening instruction: %.*s",
47400+
(int)u.path.len,
47401+
u.path.buf);
47402+
}
4738447403
fio___http_protocol_s *p = fio___http_protocol_new(s.public_folder.len + 1);
4738547404
fio___http_protocol_init(p, url, s, 0);
47386-
void *listener =
47405+
fio_http_listener_s *listener = (fio_http_listener_s *)
4738747406
fio_io_listen(.url = url,
4738847407
.protocol = &p->state[FIO___HTTP_PROTOCOL_ACCEPT].protocol,
4738947408
.tls = s.tls,
@@ -47394,11 +47413,11 @@ SFUNC void *fio_http_listen FIO_NOOP(const char *url, fio_http_settings_s s) {
4739447413
}
4739547414

4739647415
/** Returns the a pointer to the HTTP settings associated with the listener. */
47397-
SFUNC fio_http_settings_s *fio_http_listener_settings(void *listener) {
47416+
SFUNC fio_http_settings_s *fio_http_listener_settings(fio_http_listener_s *l) {
4739847417
fio___http_protocol_s *p =
4739947418
FIO_PTR_FROM_FIELD(fio___http_protocol_s,
4740047419
state[FIO___HTTP_PROTOCOL_ACCEPT].protocol,
47401-
fio_io_listener_protocol(listener));
47420+
fio_io_listener_protocol((fio_listener_s *)l));
4740247421
return &p->settings;
4740347422
}
4740447423
/* *****************************************************************************

fio-stl.md

Lines changed: 20 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -11694,10 +11694,12 @@ Returns a listener handle (same as `fio_srv_listen`). Listening can be stopped u
1169411694

1169511695
```c
1169611696
typedef struct fio_http_settings_s {
11697+
/** Called before body uploads, when a client sends an `Expect` header. */
11698+
void (*pre_http_body)(fio_http_s *h);
1169711699
/** Callback for HTTP requests (server) or responses (client). */
1169811700
void (*on_http)(fio_http_s *h);
11699-
/** (optional) the callback to be performed when the HTTP service closes. */
11700-
void (*on_finish)(struct fio_http_settings_s *settings);
11701+
/** Called when a request / response cycle is finished with no Upgrade. */
11702+
void (*on_finish)(fio_http_s *h);
1170111703

1170211704
/** Authenticate EventSource (SSE) requests, return non-zero to deny.*/
1170311705
int (*on_authenticate_sse)(fio_http_s *h);
@@ -11724,14 +11726,18 @@ typedef struct fio_http_settings_s {
1172411726
/** Called after a WebSocket / SSE connection is closed (for cleanup). */
1172511727
void (*on_close)(fio_http_s *h);
1172611728

11729+
/** (optional) the callback to be performed when the HTTP service closes. */
11730+
void (*on_stop)(struct fio_http_settings_s *settings);
11731+
1172711732
/** Default opaque user data for HTTP handles (fio_http_s). */
1172811733
void *udata;
11734+
1172911735
/** Optional SSL/TLS support. */
1173011736
fio_io_functions_s *tls_io_func;
1173111737
/** Optional SSL/TLS support. */
11732-
fio_tls_s *tls;
11738+
fio_io_tls_s *tls;
1173311739
/** Optional HTTP task queue (for multi-threading HTTP responses) */
11734-
fio_srv_async_s *queue;
11740+
fio_io_async_s *queue;
1173511741
/**
1173611742
* A public folder for file transfers - allows to circumvent any application
1173711743
* layer logic and simply serve static files.
@@ -11740,7 +11746,8 @@ typedef struct fio_http_settings_s {
1174011746
*/
1174111747
fio_str_info_s public_folder;
1174211748
/**
11743-
* The max-age value (in seconds) for caching static files send from `public_folder`.
11749+
* The max-age value (in seconds) for caching static files send from
11750+
* `public_folder`.
1174411751
*
1174511752
* Defaults to 0 (not sent).
1174611753
*/
@@ -11782,16 +11789,20 @@ typedef struct fio_http_settings_s {
1178211789
*/
1178311790
uint8_t timeout;
1178411791
/**
11785-
* Timeout for the WebSocket connections, a ping will be sent whenever the
11786-
* timeout is reached. Defaults to FIO_HTTP_DEFAULT_TIMEOUT_LONG seconds.
11792+
* Timeout for the WebSocket connections in seconds. Defaults to
11793+
* FIO_HTTP_DEFAULT_TIMEOUT_LONG seconds.
11794+
*
11795+
* A ping will be sent whenever the timeout is reached.
1178711796
*
1178811797
* Connections are only closed when a ping cannot be sent (the network layer
1178911798
* fails). Pongs are ignored.
1179011799
*/
1179111800
uint8_t ws_timeout;
1179211801
/**
11793-
* Timeout for EventSource (SSE) connections, a ping will be sent whenever the
11794-
* timeout is reached. Defaults to FIO_HTTP_DEFAULT_TIMEOUT_LONG seconds.
11802+
* Timeout for EventSource (SSE) connections in seconds. Defaults to
11803+
* FIO_HTTP_DEFAULT_TIMEOUT_LONG seconds.
11804+
*
11805+
* A ping will be sent whenever the timeout is reached.
1179511806
*
1179611807
* Connections are only closed when a ping cannot be sent (the network layer
1179711808
* fails).

fio-stl/400 io api.h

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -181,31 +181,32 @@ typedef struct fio_io_listen_args {
181181
uint8_t hide_from_log;
182182
} fio_io_listen_args;
183183

184+
typedef struct fio_listener_s fio_listener_s;
184185
/**
185186
* Sets up a network service on a listening socket.
186187
*
187188
* Returns a self-destructible listener handle on success or NULL on error.
188189
*/
189-
SFUNC void *fio_io_listen(fio_io_listen_args args);
190+
SFUNC fio_listener_s *fio_io_listen(fio_io_listen_args args);
190191
#define fio_io_listen(...) fio_io_listen((fio_io_listen_args){__VA_ARGS__})
191192

192193
/** Notifies a listener to stop listening. */
193-
SFUNC void fio_io_listen_stop(void *listener);
194+
SFUNC void fio_io_listen_stop(fio_listener_s *l);
194195

195196
/** Returns the listener's associated protocol. */
196-
SFUNC fio_io_protocol_s *fio_io_listener_protocol(void *listener);
197+
SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_listener_s *l);
197198

198199
/** Returns the listener's associated `udata`. */
199-
SFUNC void *fio_io_listener_udata(void *listener);
200+
SFUNC void *fio_io_listener_udata(fio_listener_s *l);
200201

201202
/** Sets the listener's associated `udata`, returning the old value. */
202-
SFUNC void *fio_io_listener_udata_set(void *listener, void *new_udata);
203+
SFUNC void *fio_io_listener_udata_set(fio_listener_s *l, void *new_udata);
203204

204205
/** Returns the URL on which the listener is listening. */
205-
SFUNC fio_buf_info_s fio_io_listener_url(void *listener);
206+
SFUNC fio_buf_info_s fio_io_listener_url(fio_listener_s *l);
206207

207208
/** Returns true if the listener protocol has an attached TLS context. */
208-
SFUNC int fio_io_listener_is_tls(void *listener);
209+
SFUNC int fio_io_listener_is_tls(fio_listener_s *l);
209210

210211
/* *****************************************************************************
211212
Connecting as a Client

0 commit comments

Comments
 (0)