@@ -35380,32 +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 ;
35383+ typedef struct fio_io_listener_s fio_io_listener_s ;
3538435384/**
3538535385 * Sets up a network service on a listening socket.
3538635386 *
3538735387 * Returns a self-destructible listener handle on success or NULL on error.
3538835388 */
35389- SFUNC fio_listener_s *fio_io_listen(fio_io_listen_args args);
35389+ SFUNC fio_io_listener_s *fio_io_listen(fio_io_listen_args args);
3539035390#define fio_io_listen(...) fio_io_listen((fio_io_listen_args){__VA_ARGS__})
3539135391
3539235392/** Notifies a listener to stop listening. */
35393- SFUNC void fio_io_listen_stop(fio_listener_s *l);
35393+ SFUNC void fio_io_listen_stop(fio_io_listener_s *l);
3539435394
3539535395/** Returns the listener's associated protocol. */
35396- SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_listener_s *l);
35396+ SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_io_listener_s *l);
3539735397
3539835398/** Returns the listener's associated `udata`. */
35399- SFUNC void *fio_io_listener_udata(fio_listener_s *l);
35399+ SFUNC void *fio_io_listener_udata(fio_io_listener_s *l);
3540035400
3540135401/** Sets the listener's associated `udata`, returning the old value. */
35402- SFUNC void *fio_io_listener_udata_set(fio_listener_s *l, void *new_udata);
35402+ SFUNC void *fio_io_listener_udata_set(fio_io_listener_s *l, void *new_udata);
3540335403
3540435404/** Returns the URL on which the listener is listening. */
35405- SFUNC fio_buf_info_s fio_io_listener_url(fio_listener_s *l);
35405+ SFUNC fio_buf_info_s fio_io_listener_url(fio_io_listener_s *l);
3540635406
3540735407/** Returns true if the listener protocol has an attached TLS context. */
35408- SFUNC int fio_io_listener_is_tls(fio_listener_s *l);
35408+ SFUNC int fio_io_listener_is_tls(fio_io_listener_s *l);
3540935409
3541035410/* *****************************************************************************
3541135411Connecting as a Client
@@ -38260,37 +38260,37 @@ static void fio___io_listen_free(void *l_) {
3826038260 FIO_MEM_FREE_(l, sizeof(*l) + l->url_len + 1);
3826138261}
3826238262
38263- SFUNC void fio_io_listen_stop(fio_listener_s *listener) {
38263+ SFUNC void fio_io_listen_stop(fio_io_listener_s *listener) {
3826438264 if (listener)
3826538265 fio___io_listen_free((fio___io_listen_s *)listener);
3826638266}
3826738267
3826838268/** Returns the URL on which the listener is listening. */
38269- SFUNC fio_buf_info_s fio_io_listener_url(fio_listener_s *listener) {
38269+ SFUNC fio_buf_info_s fio_io_listener_url(fio_io_listener_s *listener) {
3827038270 fio___io_listen_s *l = (fio___io_listen_s *)listener;
3827138271 return FIO_BUF_INFO2(l->url, l->url_len);
3827238272}
3827338273
3827438274/** Returns true if the listener protocol has an attached TLS context. */
38275- SFUNC int fio_io_listener_is_tls(fio_listener_s *listener) {
38275+ SFUNC int fio_io_listener_is_tls(fio_io_listener_s *listener) {
3827638276 fio___io_listen_s *l = (fio___io_listen_s *)listener;
3827738277 return !!l->tls_ctx;
3827838278}
3827938279
3828038280/** Returns the listener's associated protocol. */
38281- SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_listener_s *listener) {
38281+ SFUNC fio_io_protocol_s *fio_io_listener_protocol(fio_io_listener_s *listener) {
3828238282 fio___io_listen_s *l = (fio___io_listen_s *)listener;
3828338283 return l->protocol;
3828438284}
3828538285
3828638286/** Returns the listener's associated `udata`. */
38287- SFUNC void *fio_io_listener_udata(fio_listener_s *listener) {
38287+ SFUNC void *fio_io_listener_udata(fio_io_listener_s *listener) {
3828838288 fio___io_listen_s *l = (fio___io_listen_s *)listener;
3828938289 return l->udata;
3829038290}
3829138291
3829238292/** Sets the listener's associated `udata`, returning the old value. */
38293- SFUNC void *fio_io_listener_udata_set(fio_listener_s *listener,
38293+ SFUNC void *fio_io_listener_udata_set(fio_io_listener_s *listener,
3829438294 void *new_udata) {
3829538295 void *old;
3829638296 fio___io_listen_s *l = (fio___io_listen_s *)listener;
@@ -38389,18 +38389,19 @@ int fio_io_listen___(void); /* IDE marker */
3838938389 *
3839038390 * See the `fio_listen` Macro for details.
3839138391 */
38392- SFUNC fio_listener_s *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
38392+ SFUNC fio_io_listener_s *fio_io_listen
38393+ FIO_NOOP(struct fio_io_listen_args args) {
3839338394 fio___io_listen_s *l = NULL;
3839438395 void *built_tls = NULL;
3839538396 int should_free_tls = !args.tls;
3839638397 FIO_STR_INFO_TMP_VAR(url_alt, 2048);
3839738398 if (!args.protocol) {
3839838399 FIO_LOG_ERROR("fio_io_listen requires a protocol to be assigned.");
38399- return (fio_listener_s *)l;
38400+ return (fio_io_listener_s *)l;
3840038401 }
3840138402 if (args.on_root && !fio_io_is_master()) {
3840238403 FIO_LOG_ERROR("fio_io_listen called with `on_root` by a non-root worker.");
38403- return (fio_listener_s *)l;
38404+ return (fio_io_listener_s *)l;
3840438405 }
3840538406 if (!args.url) {
3840638407 args.url = getenv("ADDRESS");
@@ -38473,7 +38474,7 @@ SFUNC fio_listener_s *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
3847338474 l->fd = fio_sock_open2(l->url, FIO_SOCK_SERVER | FIO_SOCK_TCP);
3847438475 if (l->fd == -1) {
3847538476 fio___io_listen_free(l);
38476- return (fio_listener_s *)(l = NULL);
38477+ return (fio_io_listener_s *)(l = NULL);
3847738478 }
3847838479 if (fio_io_is_running()) {
3847938480 fio_io_defer(fio___io_listen_attach_task_deferred, l, NULL);
@@ -38484,7 +38485,7 @@ SFUNC fio_listener_s *fio_io_listen FIO_NOOP(struct fio_io_listen_args args) {
3848438485 (void *)l);
3848538486 }
3848638487 fio_state_callback_add(FIO_CALL_AT_EXIT, fio___io_listen_free, l);
38487- return (fio_listener_s *)l;
38488+ return (fio_io_listener_s *)l;
3848838489}
3848938490
3849038491/* *****************************************************************************
@@ -47173,7 +47174,7 @@ SFUNC int fio_http_route FIO_NOOP(fio_http_listener_s *l,
4717347174 goto invalid_listener_error;
4717447175 p = FIO_PTR_FROM_FIELD(fio___http_protocol_s,
4717547176 state[FIO___HTTP_PROTOCOL_ACCEPT].protocol,
47176- fio_io_listener_protocol((fio_listener_s *)l));
47177+ fio_io_listener_protocol((fio_io_listener_s *)l));
4717747178 r = &p->router;
4717847179 if (!u || !u[0]) {
4717947180 url = "/";
@@ -47245,9 +47246,13 @@ SFUNC int fio_http_route FIO_NOOP(fio_http_listener_s *l,
4724547246 s.public_folder = FIO_STR_INFO2((char *)s.tls, s.public_folder.len);
4724647247 s.public_folder.buf[s.public_folder.len] = 0;
4724747248 }
47248- /* make sure we're not leaking memory when overwriting */
47249- if (r->s.tls && (char *)r->s.tls == r->s.public_folder.buf)
47250- FIO_MEM_FREE_(r->s.tls, r->s.public_folder.len + 1);
47249+ /* make sure we're not leaking memory when overwriting an existing route */
47250+ if (r->s.on_http) {
47251+ if (r->s.on_stop != p->settings.on_stop || r->s.udata != p->settings.udata)
47252+ r->s.on_stop(&r->s);
47253+ if (r->s.tls && (char *)r->s.tls == r->s.public_folder.buf)
47254+ FIO_MEM_FREE_(r->s.tls, r->s.public_folder.len + 1);
47255+ }
4725147256 r->s = s;
4725247257 return err;
4725347258
@@ -47276,6 +47281,8 @@ FIO_SFUNC fio_http_settings_s *fio___http_route_settings(
4727647281 uint8_t *pos = (uint8_t *)path->buf;
4727747282 const uint8_t *n = pos;
4727847283 pos += (*pos == (uint8_t)'/');
47284+ if (!*pos)
47285+ return r;
4727947286 for (uint8_t c, hi, lo;
4728047287 route && ((c = *pos) >= (sizeof(*r) / sizeof(void *)));
4728147288 ++pos) {
@@ -47284,8 +47291,7 @@ FIO_SFUNC fio_http_settings_s *fio___http_route_settings(
4728447291 r = &route->s;
4728547292 n = pos;
4728647293 } else if (c == (uint8_t)'%' && (hi = fio_c2i(pos[1])) < 16) {
47287- /* decrypt route? */
47288- if ((lo = fio_c2i(pos[2])) < 16) {
47294+ if ((lo = fio_c2i(pos[2])) < 16) { /* decrypt route */
4728947295 c = (hi << 4) | lo;
4729047296 pos += 2;
4729147297 if (c < (sizeof(*r) / sizeof(void *)))
@@ -47348,7 +47354,7 @@ SFUNC fio_http_settings_s *fio_http_route_settings(fio_http_listener_s *l,
4734847354 return r;
4734947355 p = FIO_PTR_FROM_FIELD(fio___http_protocol_s,
4735047356 state[FIO___HTTP_PROTOCOL_ACCEPT].protocol,
47351- fio_io_listener_protocol((fio_listener_s *)l));
47357+ fio_io_listener_protocol((fio_io_listener_s *)l));
4735247358 r = fio___http_route_settings(&p->router, &path);
4735347359 return r;
4735447360}
@@ -47681,7 +47687,7 @@ SFUNC fio_http_settings_s *fio_http_listener_settings(fio_http_listener_s *l) {
4768147687 fio___http_protocol_s *p =
4768247688 FIO_PTR_FROM_FIELD(fio___http_protocol_s,
4768347689 state[FIO___HTTP_PROTOCOL_ACCEPT].protocol,
47684- fio_io_listener_protocol((fio_listener_s *)l));
47690+ fio_io_listener_protocol((fio_io_listener_s *)l));
4768547691 return &p->settings;
4768647692}
4768747693
0 commit comments