diff options
author | Valentin Bartenev <vbart@nginx.com> | 2020-08-13 02:46:54 +0300 |
---|---|---|
committer | Valentin Bartenev <vbart@nginx.com> | 2020-08-13 02:46:54 +0300 |
commit | 93146616cf56a94fc2979cb978c7b451c5592594 (patch) | |
tree | db840e75ef2c08731e699b4eb44641ad6639c2ca | |
parent | 21ac95f17e70f2f20fe8e2a99bbe9cc7328a6e62 (diff) | |
download | unit-93146616cf56a94fc2979cb978c7b451c5592594.tar.gz unit-93146616cf56a94fc2979cb978c7b451c5592594.tar.bz2 |
Basic variables support.
-rw-r--r-- | auto/sources | 2 | ||||
-rw-r--r-- | src/nxt_array.c | 2 | ||||
-rw-r--r-- | src/nxt_array.h | 8 | ||||
-rw-r--r-- | src/nxt_conf_validation.c | 21 | ||||
-rw-r--r-- | src/nxt_http.h | 12 | ||||
-rw-r--r-- | src/nxt_http_request.c | 15 | ||||
-rw-r--r-- | src/nxt_http_route.c | 207 | ||||
-rw-r--r-- | src/nxt_http_variables.c | 59 | ||||
-rw-r--r-- | src/nxt_main.h | 1 | ||||
-rw-r--r-- | src/nxt_mp.c | 14 | ||||
-rw-r--r-- | src/nxt_mp.h | 4 | ||||
-rw-r--r-- | src/nxt_router.c | 183 | ||||
-rw-r--r-- | src/nxt_router.h | 4 | ||||
-rw-r--r-- | src/nxt_runtime.c | 8 | ||||
-rw-r--r-- | src/nxt_runtime.h | 2 | ||||
-rw-r--r-- | src/nxt_upstream.c | 6 | ||||
-rw-r--r-- | src/nxt_var.c | 616 | ||||
-rw-r--r-- | src/nxt_var.h | 48 | ||||
-rw-r--r-- | src/test/nxt_lvlhsh_test.c | 18 |
19 files changed, 1086 insertions, 144 deletions
diff --git a/auto/sources b/auto/sources index 0dd2cbd6..a61577dc 100644 --- a/auto/sources +++ b/auto/sources @@ -31,6 +31,7 @@ NXT_LIB_SRCS=" \ src/nxt_utf8.c \ src/nxt_parse.c \ src/nxt_sprintf.c \ + src/nxt_var.c \ src/nxt_file_name.c \ src/nxt_log.c \ src/nxt_djb_hash.c \ @@ -91,6 +92,7 @@ NXT_LIB_SRCS=" \ src/nxt_http_static.c \ src/nxt_http_proxy.c \ src/nxt_http_chunk_parse.c \ + src/nxt_http_variables.c \ src/nxt_application.c \ src/nxt_external.c \ src/nxt_port_hash.c \ diff --git a/src/nxt_array.c b/src/nxt_array.c index 6fe9ad6a..1e13c22a 100644 --- a/src/nxt_array.c +++ b/src/nxt_array.c @@ -51,7 +51,7 @@ nxt_array_add(nxt_array_t *array) if (nalloc < 16) { /* Allocate new array twice larger than current. */ - new_alloc = nalloc * 2; + new_alloc = (nalloc == 0) ? 4 : nalloc * 2; } else { /* Allocate new array 1.5 times larger than current. */ diff --git a/src/nxt_array.h b/src/nxt_array.h index 5762ec27..8318fccd 100644 --- a/src/nxt_array.h +++ b/src/nxt_array.h @@ -18,6 +18,14 @@ typedef struct { } nxt_array_t; +nxt_inline void +nxt_array_init(nxt_array_t *array, nxt_mp_t *mp, size_t size) +{ + array->elts = nxt_pointer_to(array, sizeof(nxt_array_t)); + array->size = size; + array->mem_pool = mp; +} + NXT_EXPORT nxt_array_t *nxt_array_create(nxt_mp_t *mp, nxt_uint_t n, size_t size); NXT_EXPORT void nxt_array_destroy(nxt_array_t *array); diff --git a/src/nxt_conf_validation.c b/src/nxt_conf_validation.c index a5e0663f..b5530b85 100644 --- a/src/nxt_conf_validation.c +++ b/src/nxt_conf_validation.c @@ -64,6 +64,8 @@ static nxt_int_t nxt_conf_vldt_type(nxt_conf_validation_t *vldt, nxt_str_t *name, nxt_conf_value_t *value, nxt_conf_vldt_type_t type); static nxt_int_t nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...); +static nxt_int_t nxt_conf_vldt_var(nxt_conf_validation_t *vldt, + const char *option, nxt_str_t *value); static nxt_int_t nxt_conf_vldt_mtypes(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, void *data); @@ -1065,6 +1067,21 @@ nxt_conf_vldt_error(nxt_conf_validation_t *vldt, const char *fmt, ...) } +static nxt_int_t +nxt_conf_vldt_var(nxt_conf_validation_t *vldt, const char *option, + nxt_str_t *value) +{ + u_char error[NXT_MAX_ERROR_STR]; + + if (nxt_var_test(value, error) != NXT_OK) { + return nxt_conf_vldt_error(vldt, "%s in the \"%s\" value.", + error, option); + } + + return NXT_OK; +} + + typedef struct { nxt_mp_t *pool; nxt_str_t *type; @@ -1242,6 +1259,10 @@ nxt_conf_vldt_pass(nxt_conf_validation_t *vldt, nxt_conf_value_t *value, nxt_conf_get_string(value, &pass); + if (nxt_is_var(&pass)) { + return nxt_conf_vldt_var(vldt, "pass", &pass); + } + ret = nxt_http_pass_segments(vldt->pool, &pass, segments, 3); if (ret != NXT_OK) { diff --git a/src/nxt_http.h b/src/nxt_http.h index 6c84843f..08181520 100644 --- a/src/nxt_http.h +++ b/src/nxt_http.h @@ -164,6 +164,8 @@ struct nxt_http_request_s { nxt_timer_t timer; void *timer_data; + nxt_var_query_t *var_query; + void *req_rpc_data; nxt_http_peer_t *peer; @@ -202,6 +204,7 @@ struct nxt_http_action_s { nxt_upstream_t *upstream; uint32_t upstream_number; nxt_http_status_t return_code; + nxt_var_t *var; } u; nxt_str_t name; @@ -287,15 +290,16 @@ nxt_int_t nxt_http_routes_resolve(nxt_task_t *task, nxt_int_t nxt_http_pass_segments(nxt_mp_t *mp, nxt_str_t *pass, nxt_str_t *segments, nxt_uint_t n); nxt_http_action_t *nxt_http_pass_application(nxt_task_t *task, - nxt_router_temp_conf_t *tmcf, nxt_str_t *name); -void nxt_http_routes_cleanup(nxt_task_t *task, nxt_http_routes_t *routes); -void nxt_http_action_cleanup(nxt_task_t *task, nxt_http_action_t *action); + nxt_router_conf_t *rtcf, nxt_str_t *name); nxt_int_t nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_conf_value_t *conf); nxt_int_t nxt_upstreams_joint_create(nxt_router_temp_conf_t *tmcf, nxt_upstream_t ***upstream_joint); +void nxt_http_request_action(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_action_t *action); + nxt_http_action_t *nxt_http_return_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); @@ -309,7 +313,7 @@ nxt_str_t *nxt_http_static_mtypes_hash_find(nxt_lvlhsh_t *hash, nxt_http_action_t *nxt_http_application_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *action); -void nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, +nxt_int_t nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, nxt_http_action_t *action); nxt_http_action_t *nxt_upstream_proxy_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_upstream_t *upstream); diff --git a/src/nxt_http_request.c b/src/nxt_http_request.c index cc1ae17d..76fb3427 100644 --- a/src/nxt_http_request.c +++ b/src/nxt_http_request.c @@ -10,7 +10,7 @@ static nxt_int_t nxt_http_validate_host(nxt_str_t *host, nxt_mp_t *mp); static void nxt_http_request_start(nxt_task_t *task, void *obj, void *data); -static void nxt_http_request_action(nxt_task_t *task, void *obj, void *data); +static void nxt_http_request_ready(nxt_task_t *task, void *obj, void *data); static void nxt_http_request_proto_info(nxt_task_t *task, nxt_http_request_t *r); static void nxt_http_request_mem_buf_completion(nxt_task_t *task, void *obj, @@ -285,21 +285,28 @@ nxt_http_request_start(nxt_task_t *task, void *obj, void *data) static const nxt_http_request_state_t nxt_http_request_body_state nxt_aligned(64) = { - .ready_handler = nxt_http_request_action, + .ready_handler = nxt_http_request_ready, .error_handler = nxt_http_request_close_handler, }; static void -nxt_http_request_action(nxt_task_t *task, void *obj, void *data) +nxt_http_request_ready(nxt_task_t *task, void *obj, void *data) { nxt_http_action_t *action; nxt_http_request_t *r; r = obj; - action = r->conf->socket_conf->action; + nxt_http_request_action(task, r, action); +} + + +void +nxt_http_request_action(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_action_t *action) +{ if (nxt_fast_path(action != NULL)) { do { diff --git a/src/nxt_http_route.c b/src/nxt_http_route.c index ae745f11..346629c3 100644 --- a/src/nxt_http_route.c +++ b/src/nxt_http_route.c @@ -221,9 +221,16 @@ static nxt_int_t nxt_http_route_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_route_t *route); static nxt_int_t nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action); -static void nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name, +static nxt_http_action_t *nxt_http_action_pass_var(nxt_task_t *task, + nxt_http_request_t *r, nxt_http_action_t *action); +static void nxt_http_action_pass_var_ready(nxt_task_t *task, void *obj, + void *data); +static void nxt_http_action_pass_var_error(nxt_task_t *task, void *obj, + void *data); +static nxt_int_t nxt_http_pass_find(nxt_task_t *task, nxt_mp_t *mp, + nxt_router_conf_t *rtcf, nxt_http_action_t *action); +static nxt_int_t nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name, nxt_http_action_t *action); -static void nxt_http_route_cleanup(nxt_task_t *task, nxt_http_route_t *routes); static nxt_http_action_t *nxt_http_route_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *start); @@ -1353,10 +1360,8 @@ static nxt_int_t nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_http_action_t *action) { - nxt_str_t *targets; - nxt_int_t ret; - nxt_uint_t i; - nxt_str_t segments[3]; + nxt_var_t *var; + nxt_int_t ret; if (action->handler != NULL) { if (action->handler == nxt_http_static_handler @@ -1368,14 +1373,118 @@ nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, return NXT_OK; } - ret = nxt_http_pass_segments(tmcf->mem_pool, &action->name, segments, 3); + if (nxt_is_var(&action->name)) { + var = nxt_var_compile(&action->name, tmcf->router_conf->mem_pool); + if (nxt_slow_path(var == NULL)) { + return NXT_ERROR; + } + + action->u.var = var; + action->handler = nxt_http_action_pass_var; + return NXT_OK; + } + + ret = nxt_http_pass_find(task, tmcf->mem_pool, tmcf->router_conf, action); if (nxt_slow_path(ret != NXT_OK)) { return NXT_ERROR; } + return NXT_OK; +} + + +static nxt_http_action_t * +nxt_http_action_pass_var(nxt_task_t *task, nxt_http_request_t *r, + nxt_http_action_t *action) +{ + nxt_var_t *var; + nxt_int_t ret; + + ret = nxt_var_query_init(&r->var_query, r, r->mem_pool); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + + var = action->u.var; + + action = nxt_mp_get(r->mem_pool, sizeof(nxt_http_action_t)); + if (nxt_slow_path(action == NULL)) { + goto fail; + } + + nxt_var_query(task, r->var_query, var, &action->name); + nxt_var_query_resolve(task, r->var_query, action, + nxt_http_action_pass_var_ready, + nxt_http_action_pass_var_error); + return NULL; + +fail: + + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); + return NULL; +} + + +static void +nxt_http_action_pass_var_ready(nxt_task_t *task, void *obj, void *data) +{ + nxt_int_t ret; + nxt_router_conf_t *rtcf; + nxt_http_action_t *action; + nxt_http_status_t status; + nxt_http_request_t *r; + + r = obj; + action = data; + rtcf = r->conf->socket_conf->router_conf; + + nxt_debug(task, "http pass lookup: %V", &action->name); + + ret = nxt_http_pass_find(task, r->mem_pool, rtcf, action); + + if (ret != NXT_OK) { + status = (ret == NXT_DECLINED) ? NXT_HTTP_NOT_FOUND + : NXT_HTTP_INTERNAL_SERVER_ERROR; + + nxt_http_request_error(task, r, status); + return; + } + + nxt_http_request_action(task, r, action); +} + + +static void +nxt_http_action_pass_var_error(nxt_task_t *task, void *obj, void *data) +{ + nxt_http_request_t *r; + + r = obj; + + nxt_http_request_error(task, r, NXT_HTTP_INTERNAL_SERVER_ERROR); +} + + +static nxt_int_t +nxt_http_pass_find(nxt_task_t *task, nxt_mp_t *mp, nxt_router_conf_t *rtcf, + nxt_http_action_t *action) +{ + nxt_str_t *targets; + nxt_int_t ret; + nxt_uint_t i; + nxt_str_t segments[3]; + + ret = nxt_http_pass_segments(mp, &action->name, segments, 3); + if (nxt_slow_path(ret != NXT_OK)) { + return ret; + } + if (nxt_str_eq(&segments[0], "applications", 12)) { - nxt_router_listener_application(tmcf, &segments[1], action); - nxt_router_app_use(task, action->u.application, 1); + ret = nxt_router_listener_application(rtcf, &segments[1], action); + + if (ret != NXT_OK) { + return ret; + } if (segments[2].length != 0) { targets = action->u.application->targets; @@ -1388,14 +1497,20 @@ nxt_http_action_resolve(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, action->target = 0; } - } else if (nxt_str_eq(&segments[0], "upstreams", 9)) { - nxt_upstream_find(tmcf->router_conf->upstreams, &segments[1], action); + return NXT_OK; + } - } else if (nxt_str_eq(&segments[0], "routes", 6)) { - nxt_http_route_find(tmcf->router_conf->routes, &segments[1], action); + if (segments[2].length == 0) { + if (nxt_str_eq(&segments[0], "upstreams", 9)) { + return nxt_upstream_find(rtcf->upstreams, &segments[1], action); + } + + if (nxt_str_eq(&segments[0], "routes", 6)) { + return nxt_http_route_find(rtcf->routes, &segments[1], action); + } } - return NXT_OK; + return NXT_DECLINED; } @@ -1451,7 +1566,7 @@ nxt_http_pass_segments(nxt_mp_t *mp, nxt_str_t *pass, nxt_str_t *segments, } -static void +static nxt_int_t nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name, nxt_http_action_t *action) { @@ -1465,11 +1580,13 @@ nxt_http_route_find(nxt_http_routes_t *routes, nxt_str_t *name, action->u.route = *route; action->handler = nxt_http_route_handler; - return; + return NXT_OK; } route++; } + + return NXT_DECLINED; } @@ -1497,21 +1614,19 @@ nxt_http_action_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, /* COMPATIBILITY: listener application. */ nxt_http_action_t * -nxt_http_pass_application(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, +nxt_http_pass_application(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_str_t *name) { nxt_http_action_t *action; - action = nxt_mp_alloc(tmcf->router_conf->mem_pool, - sizeof(nxt_http_action_t)); + action = nxt_mp_alloc(rtcf->mem_pool, sizeof(nxt_http_action_t)); if (nxt_slow_path(action == NULL)) { return NULL; } action->name = *name; - nxt_router_listener_application(tmcf, name, action); - nxt_router_app_use(task, action->u.application, 1); + (void) nxt_router_listener_application(rtcf, name, action); action->target = 0; @@ -1519,56 +1634,6 @@ nxt_http_pass_application(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } -void -nxt_http_routes_cleanup(nxt_task_t *task, nxt_http_routes_t *routes) -{ - nxt_http_route_t **route, **end; - - if (routes != NULL) { - route = &routes->route[0]; - end = route + routes->items; - - while (route < end) { - nxt_http_route_cleanup(task, *route); - - route++; - } - } -} - - -static void -nxt_http_route_cleanup(nxt_task_t *task, nxt_http_route_t *route) -{ - nxt_http_route_match_t **match, **end; - - match = &route->match[0]; - end = match + route->items; - - while (match < end) { - nxt_http_action_cleanup(task, &(*match)->action); - - match++; - } -} - - -void -nxt_http_action_cleanup(nxt_task_t *task, nxt_http_action_t *action) -{ - if (action->handler == nxt_http_application_handler) { - nxt_router_app_use(task, action->u.application, -1); - return; - } - - if (action->handler == nxt_http_static_handler - && action->u.fallback != NULL) - { - nxt_http_action_cleanup(task, action->u.fallback); - } -} - - static nxt_http_action_t * nxt_http_route_handler(nxt_task_t *task, nxt_http_request_t *r, nxt_http_action_t *start) diff --git a/src/nxt_http_variables.c b/src/nxt_http_variables.c new file mode 100644 index 00000000..222d717c --- /dev/null +++ b/src/nxt_http_variables.c @@ -0,0 +1,59 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_router.h> +#include <nxt_http.h> + + +static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, + nxt_str_t *str, void *ctx); +static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, + nxt_str_t *str, void *ctx); + + +static nxt_var_decl_t nxt_http_vars[] = { + { nxt_string("method"), + &nxt_http_var_method, + 0 }, + + { nxt_string("uri"), + &nxt_http_var_uri, + 0 }, +}; + + +nxt_int_t +nxt_http_register_variables(void) +{ + return nxt_var_register(nxt_http_vars, nxt_nitems(nxt_http_vars)); +} + + +static nxt_int_t +nxt_http_var_method(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, + void *ctx) +{ + nxt_http_request_t *r; + + r = ctx; + + *str = *r->method; + + return NXT_OK; +} + + +static nxt_int_t +nxt_http_var_uri(nxt_task_t *task, nxt_var_query_t *query, nxt_str_t *str, + void *ctx) +{ + nxt_http_request_t *r; + + r = ctx; + + *str = *r->path; + + return NXT_OK; +} diff --git a/src/nxt_main.h b/src/nxt_main.h index 5914fbd1..7f812568 100644 --- a/src/nxt_main.h +++ b/src/nxt_main.h @@ -66,6 +66,7 @@ typedef uint16_t nxt_port_id_t; #include <nxt_sprintf.h> #include <nxt_parse.h> +#include <nxt_var.h> /* TODO: remove unused */ diff --git a/src/nxt_mp.c b/src/nxt_mp.c index 5c1a4d00..4eaa16d0 100644 --- a/src/nxt_mp.c +++ b/src/nxt_mp.c @@ -1059,3 +1059,17 @@ nxt_mp_cleanup(nxt_mp_t *mp, nxt_work_handler_t handler, return NXT_OK; } + + +void * +nxt_mp_lvlhsh_alloc(void *pool, size_t size) +{ + return nxt_mp_align(pool, size, size); +} + + +void +nxt_mp_lvlhsh_free(void *pool, void *p) +{ + nxt_mp_free(pool, p); +} diff --git a/src/nxt_mp.h b/src/nxt_mp.h index 53d1f011..a5aaabd1 100644 --- a/src/nxt_mp.h +++ b/src/nxt_mp.h @@ -112,4 +112,8 @@ NXT_EXPORT nxt_int_t nxt_mp_cleanup(nxt_mp_t *mp, nxt_work_handler_t handler, NXT_EXPORT void nxt_mp_thread_adopt(nxt_mp_t *mp); + +NXT_EXPORT void *nxt_mp_lvlhsh_alloc(void *pool, size_t size); +NXT_EXPORT void nxt_mp_lvlhsh_free(void *pool, void *p); + #endif /* _NXT_MP_H_INCLUDED_ */ diff --git a/src/nxt_router.c b/src/nxt_router.c index 0ccf6593..1318eeb4 100644 --- a/src/nxt_router.c +++ b/src/nxt_router.c @@ -93,7 +93,16 @@ static nxt_int_t nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, u_char *start, u_char *end); static nxt_int_t nxt_router_conf_process_static(nxt_task_t *task, nxt_router_conf_t *rtcf, nxt_conf_value_t *conf); + static nxt_app_t *nxt_router_app_find(nxt_queue_t *queue, nxt_str_t *name); +static nxt_int_t nxt_router_apps_hash_test(nxt_lvlhsh_query_t *lhq, void *data); +static nxt_int_t nxt_router_apps_hash_add(nxt_router_conf_t *rtcf, + nxt_app_t *app); +static nxt_app_t *nxt_router_apps_hash_get(nxt_router_conf_t *rtcf, + nxt_str_t *name); +static void nxt_router_apps_hash_use(nxt_task_t *task, nxt_router_conf_t *rtcf, + int i); + static nxt_int_t nxt_router_app_queue_init(nxt_task_t *task, nxt_port_t *port); static nxt_int_t nxt_router_port_queue_init(nxt_task_t *task, @@ -198,6 +207,7 @@ static nxt_int_t nxt_router_app_shared_port_send(nxt_task_t *task, static void nxt_router_app_port_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, void *data); +static void nxt_router_app_use(nxt_task_t *task, nxt_app_t *app, int i); static void nxt_router_app_unlink(nxt_task_t *task, nxt_app_t *app); static void nxt_router_app_port_release(nxt_task_t *task, nxt_port_t *port, @@ -954,6 +964,8 @@ nxt_router_conf_apply(nxt_task_t *task, void *obj, void *data) nxt_router_apps_sort(task, router, tmcf); + nxt_router_apps_hash_use(task, rtcf, 1); + nxt_router_engines_post(router, tmcf); nxt_queue_add(&router->sockets, &updating_sockets); @@ -1012,7 +1024,7 @@ nxt_router_conf_ready(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) nxt_debug(task, "rtcf %p: %D", rtcf, count); if (count == 0) { - nxt_http_routes_cleanup(task, rtcf->routes); + nxt_router_apps_hash_use(task, rtcf, -1); nxt_router_access_log_release(task, lock, rtcf->access_log); @@ -1057,16 +1069,6 @@ nxt_router_conf_error(nxt_task_t *task, nxt_router_temp_conf_t *tmcf) rtcf = tmcf->router_conf; - nxt_http_routes_cleanup(task, rtcf->routes); - - nxt_queue_each(skcf, &new_socket_confs, nxt_socket_conf_t, link) { - - if (skcf->action != NULL) { - nxt_http_action_cleanup(task, skcf->action); - } - - } nxt_queue_loop; - nxt_queue_each(app, &tmcf->apps, nxt_app_t, link) { nxt_router_app_unlink(task, app); @@ -1406,6 +1408,12 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_queue_remove(&prev->link); nxt_queue_insert_tail(&tmcf->previous, &prev->link); + + ret = nxt_router_apps_hash_add(tmcf->router_conf, prev); + if (nxt_slow_path(ret != NXT_OK)) { + goto fail; + } + continue; } @@ -1543,6 +1551,11 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, nxt_queue_insert_tail(&tmcf->apps, &app->link); + ret = nxt_router_apps_hash_add(tmcf->router_conf, app); + if (nxt_slow_path(ret != NXT_OK)) { + goto app_fail; + } + nxt_router_app_use(task, app, 1); app->joint = app_joint; @@ -1717,7 +1730,8 @@ nxt_router_conf_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, /* COMPATIBILITY: listener application. */ } else if (lscf.application.length > 0) { - skcf->action = nxt_http_pass_application(task, tmcf, + skcf->action = nxt_http_pass_application(task, + tmcf->router_conf, &lscf.application); } } @@ -1959,20 +1973,106 @@ nxt_router_port_queue_map(nxt_task_t *task, nxt_port_t *port, nxt_fd_t fd) } -void -nxt_router_listener_application(nxt_router_temp_conf_t *tmcf, nxt_str_t *name, +static const nxt_lvlhsh_proto_t nxt_router_apps_hash_proto nxt_aligned(64) = { + NXT_LVLHSH_DEFAULT, + nxt_router_apps_hash_test, + nxt_mp_lvlhsh_alloc, + nxt_mp_lvlhsh_free, +}; + + +static nxt_int_t +nxt_router_apps_hash_test(nxt_lvlhsh_query_t *lhq, void *data) +{ + nxt_app_t *app; + + app = data; + + return nxt_strstr_eq(&lhq->key, &app->name) ? NXT_OK : NXT_DECLINED; +} + + +static nxt_int_t +nxt_router_apps_hash_add(nxt_router_conf_t *rtcf, nxt_app_t *app) +{ + nxt_lvlhsh_query_t lhq; + + lhq.key_hash = nxt_djb_hash(app->name.start, app->name.length); + lhq.replace = 0; + lhq.key = app->name; + lhq.value = app; + lhq.proto = &nxt_router_apps_hash_proto; + lhq.pool = rtcf->mem_pool; + + switch (nxt_lvlhsh_insert(&rtcf->apps_hash, &lhq)) { + + case NXT_OK: + return NXT_OK; + + case NXT_DECLINED: + nxt_thread_log_alert("router app hash adding failed: " + "\"%V\" is already in hash", &lhq.key); + /* Fall through. */ + default: + return NXT_ERROR; + } +} + + +static nxt_app_t * +nxt_router_apps_hash_get(nxt_router_conf_t *rtcf, nxt_str_t *name) +{ + nxt_lvlhsh_query_t lhq; + + lhq.key_hash = nxt_djb_hash(name->start, name->length); + lhq.key = *name; + lhq.proto = &nxt_router_apps_hash_proto; + + if (nxt_lvlhsh_find(&rtcf->apps_hash, &lhq) != NXT_OK) { + return NULL; + } + + return lhq.value; +} + + +static void +nxt_router_apps_hash_use(nxt_task_t *task, nxt_router_conf_t *rtcf, int i) +{ + nxt_app_t *app; + nxt_lvlhsh_each_t lhe; + + nxt_lvlhsh_each_init(&lhe, &nxt_router_apps_hash_proto); + + for ( ;; ) { + app = nxt_lvlhsh_each(&rtcf->apps_hash, &lhe); + + if (app == NULL) { + break; + } + + nxt_router_app_use(task, app, i); + } +} + + + +nxt_int_t +nxt_router_listener_application(nxt_router_conf_t *rtcf, nxt_str_t *name, nxt_http_action_t *action) { nxt_app_t *app; - app = nxt_router_app_find(&tmcf->apps, name); + app = nxt_router_apps_hash_get(rtcf, name); if (app == NULL) { - app = nxt_router_app_find(&tmcf->previous, name); + return NXT_DECLINED; } action->u.application = app; action->handler = nxt_http_application_handler; + + return NXT_OK; } @@ -3201,24 +3301,18 @@ nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint) nxt_thread_spin_unlock(lock); - if (skcf != NULL) { - if (skcf->action != NULL) { - nxt_http_action_cleanup(task, skcf->action); - } - #if (NXT_TLS) - if (skcf->tls != NULL) { - task->thread->runtime->tls->server_free(task, skcf->tls); - } -#endif + if (skcf != NULL && skcf->tls != NULL) { + task->thread->runtime->tls->server_free(task, skcf->tls); } +#endif /* TODO remove engine->port */ if (rtcf != NULL) { nxt_debug(task, "old router conf is destroyed"); - nxt_http_routes_cleanup(task, rtcf->routes); + nxt_router_apps_hash_use(task, rtcf, -1); nxt_router_access_log_release(task, lock, rtcf->access_log); @@ -4126,24 +4220,6 @@ nxt_router_app_port_error(nxt_task_t *task, nxt_port_recv_msg_t *msg, } -void -nxt_router_app_use(nxt_task_t *task, nxt_app_t *app, int i) -{ - int c; - - c = nxt_atomic_fetch_add(&app->use_count, i); - - if (i < 0 && c == -i) { - - if (task->thread->engine != app->engine) { - nxt_event_engine_post(app->engine, &app->joint->free_app_work); - - } else { - nxt_router_free_app(task, app->joint, NULL); - } - } -} - nxt_inline nxt_port_t * nxt_router_app_get_port_for_quit(nxt_task_t *task, nxt_app_t *app) @@ -4184,6 +4260,25 @@ nxt_router_app_get_port_for_quit(nxt_task_t *task, nxt_app_t *app) static void +nxt_router_app_use(nxt_task_t *task, nxt_app_t *app, int i) +{ + int c; + + c = nxt_atomic_fetch_add(&app->use_count, i); + + if (i < 0 && c == -i) { + + if (task->thread->engine != app->engine) { + nxt_event_engine_post(app->engine, &app->joint->free_app_work); + + } else { + nxt_router_free_app(task, app->joint, NULL); + } + } +} + + +static void nxt_router_app_unlink(nxt_task_t *task, nxt_app_t *app) { nxt_debug(task, "app '%V' %p unlink", &app->name, app); diff --git a/src/nxt_router.h b/src/nxt_router.h index 0b1147f8..81b3538c 100644 --- a/src/nxt_router.h +++ b/src/nxt_router.h @@ -48,6 +48,7 @@ typedef struct { nxt_upstreams_t *upstreams; nxt_lvlhsh_t mtypes_hash; + nxt_lvlhsh_t apps_hash; nxt_router_access_log_t *access_log; } nxt_router_conf_t; @@ -221,9 +222,8 @@ struct nxt_router_access_log_s { void nxt_router_process_http_request(nxt_task_t *task, nxt_http_request_t *r, nxt_app_t *app); void nxt_router_app_port_close(nxt_task_t *task, nxt_port_t *port); -void nxt_router_listener_application(nxt_router_temp_conf_t *tmcf, +nxt_int_t nxt_router_listener_application(nxt_router_conf_t *rtcf, nxt_str_t *name, nxt_http_action_t *action); -void nxt_router_app_use(nxt_task_t *task, nxt_app_t *app, int i); void nxt_router_listen_event_release(nxt_task_t *task, nxt_listen_event_t *lev, nxt_socket_conf_joint_t *joint); void nxt_router_conf_release(nxt_task_t *task, nxt_socket_conf_joint_t *joint); diff --git a/src/nxt_runtime.c b/src/nxt_runtime.c index 5f4b3e58..435276a0 100644 --- a/src/nxt_runtime.c +++ b/src/nxt_runtime.c @@ -124,6 +124,14 @@ nxt_runtime_create(nxt_task_t *task) goto fail; } + if (nxt_slow_path(nxt_http_register_variables() != NXT_OK)) { + goto fail; + } + + if (nxt_slow_path(nxt_var_index_init() != NXT_OK)) { + goto fail; + } + nxt_work_queue_add(&task->thread->engine->fast_work_queue, nxt_runtime_start, task, rt, NULL); diff --git a/src/nxt_runtime.h b/src/nxt_runtime.h index d29b6b4d..0fb8c9a1 100644 --- a/src/nxt_runtime.h +++ b/src/nxt_runtime.h @@ -135,6 +135,8 @@ void nxt_cdecl nxt_log_time_handler(nxt_uint_t level, nxt_log_t *log, void nxt_stream_connection_init(nxt_task_t *task, void *obj, void *data); +nxt_int_t nxt_http_register_variables(void); + #define nxt_runtime_process_each(rt, process) \ do { \ diff --git a/src/nxt_upstream.c b/src/nxt_upstream.c index 66b6619a..c8ecbbe6 100644 --- a/src/nxt_upstream.c +++ b/src/nxt_upstream.c @@ -71,7 +71,7 @@ nxt_upstreams_create(nxt_task_t *task, nxt_router_temp_conf_t *tmcf, } -void +nxt_int_t nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, nxt_http_action_t *action) { @@ -86,9 +86,11 @@ nxt_upstream_find(nxt_upstreams_t *upstreams, nxt_str_t *name, action->u.upstream_number = i; action->handler = nxt_upstream_handler; - return; + return NXT_DECLINED; } } + + return NXT_OK; } diff --git a/src/nxt_var.c b/src/nxt_var.c new file mode 100644 index 00000000..2731fd09 --- /dev/null +++ b/src/nxt_var.c @@ -0,0 +1,616 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#include <nxt_main.h> + + +struct nxt_var_s { + size_t plain; + nxt_uint_t vars; + u_char data[]; + +/* + uint32_t indexes[vars]; + size_t positions[vars]; + u_char chars[plain]; +*/ +}; + + +typedef struct { + nxt_var_t *var; + nxt_str_t *value; +} nxt_var_value_t; + + +struct nxt_var_query_s { + nxt_array_t values; /* of nxt_var_value_t */ + nxt_array_t parts; /* of nxt_str_t * */ + + nxt_lvlhsh_t cache; + + nxt_str_t *spare; + nxt_uint_t waiting; + nxt_uint_t failed; /* 1 bit */ + + void *ctx; + void *data; + + nxt_work_handler_t ready; + nxt_work_handler_t error; +}; + + +#define nxt_var_indexes(var) ((uint32_t *) (var)->data) + +#define nxt_var_positions(var) \ + ((size_t *) ((var)->data + (var)->vars * sizeof(uint32_t))) + +#define nxt_var_plain_start(var) \ + ((var)->data + (var)->vars * (sizeof(uint32_t) + sizeof(size_t))) + + +static nxt_int_t nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data); +static nxt_var_decl_t *nxt_var_hash_find(nxt_str_t *name); + +static nxt_int_t nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data); +static nxt_str_t *nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index); +static nxt_int_t nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, + nxt_str_t *value, nxt_mp_t *mp); + +static u_char *nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part, + nxt_bool_t *is_var); + +static void nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query); + + +static const nxt_lvlhsh_proto_t nxt_var_hash_proto nxt_aligned(64) = { + NXT_LVLHSH_DEFAULT, + nxt_var_hash_test, + nxt_lvlhsh_alloc, + nxt_lvlhsh_free, +}; + +static const nxt_lvlhsh_proto_t nxt_var_cache_proto nxt_aligned(64) = { + NXT_LVLHSH_DEFAULT, + nxt_var_cache_test, + nxt_mp_lvlhsh_alloc, + nxt_mp_lvlhsh_free, +}; + + +static nxt_lvlhsh_t nxt_var_hash; +static uint32_t nxt_var_count; + +static nxt_var_handler_t *nxt_var_index; + + +static nxt_int_t +nxt_var_hash_test(nxt_lvlhsh_query_t *lhq, void *data) +{ + nxt_var_decl_t *decl; + + decl = data; + + return nxt_strstr_eq(&lhq->key, &decl->name) ? NXT_OK : NXT_DECLINED; +} + + +static nxt_var_decl_t * +nxt_var_hash_find(nxt_str_t *name) +{ + nxt_lvlhsh_query_t lhq; + + lhq.key_hash = nxt_djb_hash(name->start, name->length); + lhq.key = *name; + lhq.proto = &nxt_var_hash_proto; + + if (nxt_lvlhsh_find(&nxt_var_hash, &lhq) != NXT_OK) { + return NULL; + } + + return lhq.value; +} + + +static nxt_int_t +nxt_var_cache_test(nxt_lvlhsh_query_t *lhq, void *data) +{ + return NXT_OK; +} + + +static nxt_str_t * +nxt_var_cache_find(nxt_lvlhsh_t *lh, uint32_t index) +{ + nxt_lvlhsh_query_t lhq; + + lhq.key_hash = nxt_murmur_hash2_uint32(&index); + lhq.key.length = sizeof(uint32_t); + lhq.key.start = (u_char *) &index; + lhq.proto = &nxt_var_cache_proto; + + if (nxt_lvlhsh_find(lh, &lhq) != NXT_OK) { + return NULL; + } + + return lhq.value; +} + + +static nxt_int_t +nxt_var_cache_add(nxt_lvlhsh_t *lh, uint32_t index, nxt_str_t *value, + nxt_mp_t *mp) +{ + nxt_lvlhsh_query_t lhq; + + lhq.key_hash = nxt_murmur_hash2_uint32(&index); + lhq.replace = 0; + lhq.key.length = sizeof(uint32_t); + lhq.key.start = (u_char *) &index; + lhq.value = value; + lhq.proto = &nxt_var_cache_proto; + lhq.pool = mp; + + return nxt_lvlhsh_insert(lh, &lhq); +} + + +nxt_int_t +nxt_var_register(nxt_var_decl_t *decl, size_t n) +{ + nxt_uint_t i; + nxt_lvlhsh_query_t lhq; + + lhq.replace = 0; + lhq.proto = &nxt_var_hash_proto; + + for (i = 0; i < n; i++) { + lhq.key = decl[i].name; + lhq.key_hash = nxt_djb_hash(lhq.key.start, lhq.key.length); + lhq.value = &decl[i]; + + if (nxt_slow_path(nxt_lvlhsh_insert(&nxt_var_hash, &lhq) != NXT_OK)) { + return NXT_ERROR; + } + } + + nxt_var_count += n; + + return NXT_OK; +} + + +nxt_int_t +nxt_var_index_init(void) +{ + nxt_uint_t i; + nxt_var_decl_t *decl; + nxt_var_handler_t *index; + nxt_lvlhsh_each_t lhe; + + index = nxt_memalign(64, nxt_var_count * sizeof(nxt_var_handler_t)); + if (index == NULL) { + return NXT_ERROR; + } + + nxt_lvlhsh_each_init(&lhe, &nxt_var_hash_proto); + + for (i = 0; i < nxt_var_count; i++) { + decl = nxt_lvlhsh_each(&nxt_var_hash, &lhe); + decl->index = i; + index[i] = decl->handler; + } + + nxt_var_index = index; + + return NXT_OK; +} + + +nxt_var_t * +nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp) +{ + u_char *p, *end, *plain_pos; + size_t plain, size, *positions; + uint32_t *indexes; + nxt_var_t *var; + nxt_str_t part; + nxt_uint_t n; + nxt_bool_t is_var; + nxt_var_decl_t *decl; + + plain = 0; + n = 0; + + p = str->start; + end = p + str->length; + + while (p < end) { + p = nxt_var_next_part(p, end - p, &part, &is_var); + + if (nxt_slow_path(p == NULL)) { + return NULL; + } + + if (is_var) { + n++; + + } else { + plain += part.length; + } + } + + size = sizeof(nxt_var_t) + + n * (sizeof(nxt_var_handler_t) + sizeof (size_t)) + + plain; + + var = nxt_mp_get(mp, size); + if (nxt_slow_path(var == NULL)) { + return NULL; + } + + var->plain = plain; + var->vars = n; + + indexes = nxt_var_indexes(var); + positions = nxt_var_positions(var); + plain_pos = nxt_var_plain_start(var); + + plain = 0; + n = 0; + + p = str->start; + + while (p < end) { + p = nxt_var_next_part(p, end - p, &part, &is_var); + + if (is_var) { + decl = nxt_var_hash_find(&part); + + if (nxt_slow_path(decl == NULL)) { + return NULL; + } + + indexes[n] = decl->index; + positions[n] = plain; + + n++; + + } else { + plain_pos = nxt_cpymem(plain_pos, part.start, part.length); + plain += part.length; + } + } + + return var; +} + + +nxt_int_t +nxt_var_test(nxt_str_t *str, u_char *error) +{ + u_char *p, *end, *next; + nxt_str_t part; + nxt_bool_t is_var; + nxt_var_decl_t *decl; + + p = str->start; + end = p + str->length; + + while (p < end) { + next = nxt_var_next_part(p, end - p, &part, &is_var); + + if (next == NULL) { + nxt_sprintf(error, error + NXT_MAX_ERROR_STR, + "Invalid variable at position %uz%Z", p - str->start); + + return NXT_ERROR; + } + + if (is_var) { + decl = nxt_var_hash_find(&part); + + if (decl == NULL) { + nxt_sprintf(error, error + NXT_MAX_ERROR_STR, + "Unknown variable \"%V\"%Z", &part); + + return NXT_ERROR; + } + } + + p = next; + } + + return NXT_OK; +} + + +static u_char * +nxt_var_next_part(u_char *start, size_t length, nxt_str_t *part, + nxt_bool_t *is_var) +{ + u_char *p, *end, ch, c; + nxt_bool_t bracket; + + end = start + length; + + p = nxt_memchr(start, '$', length); + + if (p == start) { + *is_var = 1; + + p++; + + if (p == end) { + return NULL; + } + + if (*p == '{') { + bracket = 1; + + if (end - p < 2) { + return NULL; + } + + p++; + + } else { + bracket = 0; + } + + start = p; + + for ( ;; ) { + ch = *p; + + c = (u_char) (ch | 0x20); + if ((c < 'a' || c > 'z') && ch != '_') { + + if (bracket && ch != '}') { + return NULL; + } + + break; + } + + p++; + + if (p == end) { + if (bracket) { + return NULL; + } + + break; + } + } + + length = p - start; + end = p + bracket; + + } else { + *is_var = 0; + + if (p != NULL) { + length = p - start; + end = p; + } + } + + part->length = length; + part->start = start; + + return end; +} + + +nxt_int_t +nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, nxt_mp_t *mp) +{ + nxt_var_query_t *query; + + query = *query_p; + + if (*query_p == NULL) { + query = nxt_mp_zget(mp, sizeof(nxt_var_query_t)); + if (nxt_slow_path(query == NULL)) { + return NXT_ERROR; + } + + nxt_array_init(&query->values, mp, sizeof(nxt_var_value_t)); + nxt_array_init(&query->parts, mp, sizeof(nxt_str_t *)); + + } else { + nxt_array_reset(&query->values); + } + + query->ctx = ctx; + + *query_p = query; + + return NXT_OK; +} + + +void +nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, nxt_var_t *var, + nxt_str_t *str) +{ + uint32_t *indexes; + nxt_mp_t *mp; + nxt_str_t *value; + nxt_int_t ret; + nxt_uint_t i; + nxt_var_value_t *val; + + if (var->vars == 0) { + str->length = var->plain; + str->start = nxt_var_plain_start(var); + return; + } + + if (nxt_slow_path(query->failed)) { + return; + } + + mp = query->values.mem_pool; + indexes = nxt_var_indexes(var); + value = query->spare; + + for (i = 0; i < var->vars; i++) { + + if (value == NULL) { + value = nxt_mp_zget(mp, sizeof(nxt_str_t)); + if (nxt_slow_path(value == NULL)) { + goto fail; + } + } + + ret = nxt_var_cache_add(&query->cache, indexes[i], value, mp); + + if (ret != NXT_OK) { + if (nxt_slow_path(ret == NXT_ERROR)) { + goto fail; + } + + continue; /* NXT_DECLINED */ + } + + ret = nxt_var_index[indexes[i]](task, query, value, query->ctx); + + value = NULL; + + if (ret != NXT_OK) { + if (nxt_slow_path(ret != NXT_AGAIN)) { + goto fail; + } + + query->waiting++; + } + } + + query->spare = value; + + val = nxt_array_add(&query->values); + if (nxt_slow_path(val == NULL)) { + goto fail; + } + + val->var = var; + val->value = str; + + return; + +fail: + + query->failed = 1; +} + + +void +nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data, + nxt_work_handler_t ready, nxt_work_handler_t error) +{ + query->data = data; + query->ready = ready; + query->error = error; + + if (query->waiting == 0) { + nxt_var_query_finish(task, query); + } +} + + +void +nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query, + nxt_bool_t failed) +{ + query->failed |= failed; + + if (--query->waiting == 0) { + nxt_var_query_finish(task, query); + } +} + + +static void +nxt_var_query_finish(nxt_task_t *task, nxt_var_query_t *query) +{ + u_char *p, *src; + size_t length, plain, next, *positions; + uint32_t *indexes; + nxt_str_t *str, **part; + nxt_var_t *var; + nxt_uint_t i, j; + nxt_var_value_t *val; + + if (query->failed) { + goto done; + } + + val = query->values.elts; + + for (i = 0; i < query->values.nelts; i++) { + var = val[i].var; + + length = var->plain; + indexes = nxt_var_indexes(var); + + for (j = 0; j < var->vars; j++) { + str = nxt_var_cache_find(&query->cache, indexes[j]); + + nxt_assert(str != NULL); + + part = nxt_array_add(&query->parts); + + if (nxt_slow_path(part == NULL)) { + query->failed = 1; + goto done; + } + + *part = str; + + length += str->length; + } + + p = nxt_mp_nget(query->values.mem_pool, length); + if (nxt_slow_path(p == NULL)) { + query->failed = 1; + goto done; + } + + val[i].value->length = length; + val[i].value->start = p; + + part = query->parts.elts; + positions = nxt_var_positions(var); + src = nxt_var_plain_start(var); + + plain = 0; + + for (j = 0; j < var->vars; j++) { + next = positions[j]; + + if (next != plain) { + p = nxt_cpymem(p, &src[plain], next - plain); + plain = next; + } + + p = nxt_cpymem(p, part[j]->start, part[j]->length); + } + + if (plain != var->plain) { + nxt_memcpy(p, &src[plain], var->plain - plain); + } + + nxt_array_reset(&query->parts); + } + +done: + + nxt_work_queue_add(&task->thread->engine->fast_work_queue, + query->failed ? query->error : query->ready, + task, query->ctx, query->data); +} diff --git a/src/nxt_var.h b/src/nxt_var.h new file mode 100644 index 00000000..7e0a2a21 --- /dev/null +++ b/src/nxt_var.h @@ -0,0 +1,48 @@ + +/* + * Copyright (C) NGINX, Inc. + */ + +#ifndef _NXT_VAR_H_INCLUDED_ +#define _NXT_VAR_H_INCLUDED_ + + +typedef struct nxt_var_s nxt_var_t; +typedef struct nxt_var_query_s nxt_var_query_t; + + +typedef nxt_int_t (*nxt_var_handler_t)(nxt_task_t *task, + nxt_var_query_t *query, + nxt_str_t *str, + void *ctx); + +typedef struct { + nxt_str_t name; + nxt_var_handler_t handler; + uint32_t index; +} nxt_var_decl_t; + + +nxt_inline nxt_bool_t +nxt_is_var(nxt_str_t *str) +{ + return (nxt_memchr(str->start, '$', str->length) != NULL); +} + + +nxt_int_t nxt_var_register(nxt_var_decl_t *decl, size_t n); +nxt_int_t nxt_var_index_init(void); +nxt_var_t *nxt_var_compile(nxt_str_t *str, nxt_mp_t *mp); +nxt_int_t nxt_var_test(nxt_str_t *str, u_char *error); + +nxt_int_t nxt_var_query_init(nxt_var_query_t **query_p, void *ctx, + nxt_mp_t *mp); +void nxt_var_query(nxt_task_t *task, nxt_var_query_t *query, + nxt_var_t *var, nxt_str_t *str); +void nxt_var_query_resolve(nxt_task_t *task, nxt_var_query_t *query, void *data, + nxt_work_handler_t ready, nxt_work_handler_t error); +void nxt_var_query_handle(nxt_task_t *task, nxt_var_query_t *query, + nxt_bool_t failed); + + +#endif /* _NXT_VAR_H_INCLUDED_ */ diff --git a/src/test/nxt_lvlhsh_test.c b/src/test/nxt_lvlhsh_test.c index 2e1e0b20..baa6d0e1 100644 --- a/src/test/nxt_lvlhsh_test.c +++ b/src/test/nxt_lvlhsh_test.c @@ -19,20 +19,6 @@ nxt_lvlhsh_test_key_test(nxt_lvlhsh_query_t *lhq, void *data) } -static void * -nxt_lvlhsh_test_pool_alloc(void *pool, size_t size) -{ - return nxt_mp_align(pool, size, size); -} - - -static void -nxt_lvlhsh_test_pool_free(void *pool, void *p) -{ - nxt_mp_free(pool, p); -} - - static const nxt_lvlhsh_proto_t malloc_proto nxt_aligned(64) = { //NXT_LVLHSH_LARGE_MEMALIGN, NXT_LVLHSH_DEFAULT, @@ -44,8 +30,8 @@ static const nxt_lvlhsh_proto_t malloc_proto nxt_aligned(64) = { static const nxt_lvlhsh_proto_t pool_proto nxt_aligned(64) = { NXT_LVLHSH_LARGE_SLAB, nxt_lvlhsh_test_key_test, - nxt_lvlhsh_test_pool_alloc, - nxt_lvlhsh_test_pool_free, + nxt_mp_lvlhsh_alloc, + nxt_mp_lvlhsh_free, }; |