xref: /unit/src/nxt_http_variables.c (revision 2654:639dde26c5dd)
11563Svbart@nginx.com 
21563Svbart@nginx.com /*
31563Svbart@nginx.com  * Copyright (C) NGINX, Inc.
41563Svbart@nginx.com  */
51563Svbart@nginx.com 
61563Svbart@nginx.com #include <nxt_router.h>
71563Svbart@nginx.com #include <nxt_http.h>
82505Sz.hong@f5.com #include <nxt_h1proto.h>
91563Svbart@nginx.com 
101563Svbart@nginx.com 
112158Sandrew@digital-domain.net static nxt_int_t nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str,
122504Sz.hong@f5.com     void *ctx, void *data);
132214Sz.hong@f5.com static nxt_int_t nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str,
142504Sz.hong@f5.com     void *ctx, void *data);
152124Sz.hong@f5.com static nxt_int_t nxt_http_var_method(nxt_task_t *task, nxt_str_t *str,
162504Sz.hong@f5.com     void *ctx, void *data);
172124Sz.hong@f5.com static nxt_int_t nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str,
182504Sz.hong@f5.com     void *ctx, void *data);
192147Sz.hong@f5.com static nxt_int_t nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx,
202504Sz.hong@f5.com     void *data);
212147Sz.hong@f5.com static nxt_int_t nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx,
222504Sz.hong@f5.com     void *data);
232149Sz.hong@f5.com static nxt_int_t nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str,
242504Sz.hong@f5.com     void *ctx, void *data);
252149Sz.hong@f5.com static nxt_int_t nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str,
262504Sz.hong@f5.com     void *ctx, void *data);
272149Sz.hong@f5.com static u_char *nxt_http_log_date(u_char *buf, nxt_realtime_t *now,
282149Sz.hong@f5.com     struct tm *tm, size_t size, const char *format);
292149Sz.hong@f5.com static nxt_int_t nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str,
302504Sz.hong@f5.com     void *ctx, void *data);
312590Szelenkov@nginx.com static nxt_int_t nxt_http_var_request_id(nxt_task_t *task, nxt_str_t *str,
322590Szelenkov@nginx.com     void *ctx, void *data);
332149Sz.hong@f5.com static nxt_int_t nxt_http_var_status(nxt_task_t *task, nxt_str_t *str,
342504Sz.hong@f5.com     void *ctx, void *data);
352149Sz.hong@f5.com static nxt_int_t nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str,
362504Sz.hong@f5.com     void *ctx, void *data);
372149Sz.hong@f5.com static nxt_int_t nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str,
382504Sz.hong@f5.com     void *ctx, void *data);
392149Sz.hong@f5.com static nxt_int_t nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str,
402504Sz.hong@f5.com     void *ctx, void *data);
412505Sz.hong@f5.com static nxt_int_t nxt_http_var_response_connection(nxt_task_t *task,
422505Sz.hong@f5.com     nxt_str_t *str, void *ctx, void *data);
432505Sz.hong@f5.com static nxt_int_t nxt_http_var_response_content_length(nxt_task_t *task,
442505Sz.hong@f5.com     nxt_str_t *str, void *ctx, void *data);
452505Sz.hong@f5.com static nxt_int_t nxt_http_var_response_transfer_encoding(nxt_task_t *task,
462505Sz.hong@f5.com     nxt_str_t *str, void *ctx, void *data);
472147Sz.hong@f5.com static nxt_int_t nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx,
482504Sz.hong@f5.com     void *data);
492147Sz.hong@f5.com static nxt_int_t nxt_http_var_header(nxt_task_t *task, nxt_str_t *str,
502504Sz.hong@f5.com     void *ctx, void *data);
512147Sz.hong@f5.com static nxt_int_t nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str,
522504Sz.hong@f5.com     void *ctx, void *data);
532505Sz.hong@f5.com static nxt_int_t nxt_http_var_response_header(nxt_task_t *task, nxt_str_t *str,
542505Sz.hong@f5.com     void *ctx, void *data);
551563Svbart@nginx.com 
561563Svbart@nginx.com 
571563Svbart@nginx.com static nxt_var_decl_t  nxt_http_vars[] = {
582147Sz.hong@f5.com     {
592158Sandrew@digital-domain.net         .name = nxt_string("dollar"),
602158Sandrew@digital-domain.net         .handler = nxt_http_var_dollar,
612489Sz.hong@f5.com         .cacheable = 1,
622158Sandrew@digital-domain.net     }, {
632214Sz.hong@f5.com         .name = nxt_string("request_time"),
642214Sz.hong@f5.com         .handler = nxt_http_var_request_time,
652489Sz.hong@f5.com         .cacheable = 1,
662214Sz.hong@f5.com     }, {
672147Sz.hong@f5.com         .name = nxt_string("method"),
682147Sz.hong@f5.com         .handler = nxt_http_var_method,
692489Sz.hong@f5.com         .cacheable = 1,
702147Sz.hong@f5.com     }, {
712147Sz.hong@f5.com         .name = nxt_string("request_uri"),
722147Sz.hong@f5.com         .handler = nxt_http_var_request_uri,
732489Sz.hong@f5.com         .cacheable = 1,
742147Sz.hong@f5.com     }, {
752147Sz.hong@f5.com         .name = nxt_string("uri"),
762147Sz.hong@f5.com         .handler = nxt_http_var_uri,
772489Sz.hong@f5.com         .cacheable = 0,
782147Sz.hong@f5.com     }, {
792147Sz.hong@f5.com         .name = nxt_string("host"),
802147Sz.hong@f5.com         .handler = nxt_http_var_host,
812489Sz.hong@f5.com         .cacheable = 1,
822147Sz.hong@f5.com     }, {
832149Sz.hong@f5.com         .name = nxt_string("remote_addr"),
842149Sz.hong@f5.com         .handler = nxt_http_var_remote_addr,
852489Sz.hong@f5.com         .cacheable = 1,
862149Sz.hong@f5.com     }, {
872149Sz.hong@f5.com         .name = nxt_string("time_local"),
882149Sz.hong@f5.com         .handler = nxt_http_var_time_local,
892489Sz.hong@f5.com         .cacheable = 1,
902149Sz.hong@f5.com     }, {
912149Sz.hong@f5.com         .name = nxt_string("request_line"),
922149Sz.hong@f5.com         .handler = nxt_http_var_request_line,
932489Sz.hong@f5.com         .cacheable = 1,
942149Sz.hong@f5.com     }, {
952590Szelenkov@nginx.com         .name = nxt_string("request_id"),
962590Szelenkov@nginx.com         .handler = nxt_http_var_request_id,
972590Szelenkov@nginx.com         .cacheable = 1,
982590Szelenkov@nginx.com     }, {
992149Sz.hong@f5.com         .name = nxt_string("status"),
1002149Sz.hong@f5.com         .handler = nxt_http_var_status,
1012489Sz.hong@f5.com         .cacheable = 1,
1022149Sz.hong@f5.com     }, {
1032149Sz.hong@f5.com         .name = nxt_string("body_bytes_sent"),
1042149Sz.hong@f5.com         .handler = nxt_http_var_body_bytes_sent,
1052489Sz.hong@f5.com         .cacheable = 1,
1062149Sz.hong@f5.com     }, {
1072149Sz.hong@f5.com         .name = nxt_string("header_referer"),
1082149Sz.hong@f5.com         .handler = nxt_http_var_referer,
1092489Sz.hong@f5.com         .cacheable = 1,
1102149Sz.hong@f5.com     }, {
1112505Sz.hong@f5.com         .name = nxt_string("response_header_connection"),
1122505Sz.hong@f5.com         .handler = nxt_http_var_response_connection,
1132505Sz.hong@f5.com         .cacheable = 1,
1142505Sz.hong@f5.com     }, {
1152505Sz.hong@f5.com         .name = nxt_string("response_header_content_length"),
1162505Sz.hong@f5.com         .handler = nxt_http_var_response_content_length,
1172505Sz.hong@f5.com         .cacheable = 1,
1182505Sz.hong@f5.com     }, {
1192505Sz.hong@f5.com         .name = nxt_string("response_header_transfer_encoding"),
1202505Sz.hong@f5.com         .handler = nxt_http_var_response_transfer_encoding,
1212505Sz.hong@f5.com         .cacheable = 1,
1222505Sz.hong@f5.com     }, {
1232149Sz.hong@f5.com         .name = nxt_string("header_user_agent"),
1242149Sz.hong@f5.com         .handler = nxt_http_var_user_agent,
1252489Sz.hong@f5.com         .cacheable = 1,
1262147Sz.hong@f5.com     },
1271563Svbart@nginx.com };
1281563Svbart@nginx.com 
1291563Svbart@nginx.com 
1301563Svbart@nginx.com nxt_int_t
nxt_http_register_variables(void)1311563Svbart@nginx.com nxt_http_register_variables(void)
1321563Svbart@nginx.com {
1331563Svbart@nginx.com     return nxt_var_register(nxt_http_vars, nxt_nitems(nxt_http_vars));
1341563Svbart@nginx.com }
1351563Svbart@nginx.com 
1361563Svbart@nginx.com 
1372504Sz.hong@f5.com nxt_int_t
nxt_http_unknown_var_ref(nxt_mp_t * mp,nxt_var_ref_t * ref,nxt_str_t * name)138*2654Sz.hong@f5.com nxt_http_unknown_var_ref(nxt_mp_t *mp, nxt_var_ref_t *ref, nxt_str_t *name)
1392504Sz.hong@f5.com {
1402504Sz.hong@f5.com     int64_t    hash;
1412505Sz.hong@f5.com     nxt_str_t  str, *lower;
1422505Sz.hong@f5.com 
1432505Sz.hong@f5.com     if (nxt_str_start(name, "response_header_", 16)) {
1442505Sz.hong@f5.com         ref->handler = nxt_http_var_response_header;
1452512Sz.hong@f5.com         ref->cacheable = 0;
1462505Sz.hong@f5.com 
1472505Sz.hong@f5.com         str.start = name->start + 16;
1482505Sz.hong@f5.com         str.length = name->length - 16;
1492505Sz.hong@f5.com 
1502505Sz.hong@f5.com         if (str.length == 0) {
1512505Sz.hong@f5.com             return NXT_ERROR;
1522505Sz.hong@f5.com         }
1532505Sz.hong@f5.com 
154*2654Sz.hong@f5.com         lower = nxt_str_alloc(mp, str.length);
1552505Sz.hong@f5.com         if (nxt_slow_path(lower == NULL)) {
1562505Sz.hong@f5.com             return NXT_ERROR;
1572505Sz.hong@f5.com         }
1582505Sz.hong@f5.com 
1592505Sz.hong@f5.com         nxt_memcpy_lowcase(lower->start, str.start, str.length);
1602505Sz.hong@f5.com 
1612505Sz.hong@f5.com         ref->data = lower;
1622505Sz.hong@f5.com 
1632505Sz.hong@f5.com         return NXT_OK;
1642505Sz.hong@f5.com     }
1652504Sz.hong@f5.com 
1662504Sz.hong@f5.com     if (nxt_str_start(name, "header_", 7)) {
1672504Sz.hong@f5.com         ref->handler = nxt_http_var_header;
1682504Sz.hong@f5.com         ref->cacheable = 1;
1692504Sz.hong@f5.com 
1702504Sz.hong@f5.com         str.start = name->start + 7;
1712504Sz.hong@f5.com         str.length = name->length - 7;
1722504Sz.hong@f5.com 
1732504Sz.hong@f5.com         if (str.length == 0) {
1742504Sz.hong@f5.com             return NXT_ERROR;
1752504Sz.hong@f5.com         }
1762504Sz.hong@f5.com 
177*2654Sz.hong@f5.com         hash = nxt_http_header_hash(mp, &str);
1782504Sz.hong@f5.com         if (nxt_slow_path(hash == -1)) {
1792504Sz.hong@f5.com             return NXT_ERROR;
1802504Sz.hong@f5.com         }
1812504Sz.hong@f5.com 
1822504Sz.hong@f5.com     } else if (nxt_str_start(name, "arg_", 4)) {
1832504Sz.hong@f5.com         ref->handler = nxt_http_var_arg;
1842504Sz.hong@f5.com         ref->cacheable = 1;
1852504Sz.hong@f5.com 
1862504Sz.hong@f5.com         str.start = name->start + 4;
1872504Sz.hong@f5.com         str.length = name->length - 4;
1882504Sz.hong@f5.com 
1892504Sz.hong@f5.com         if (str.length == 0) {
1902504Sz.hong@f5.com             return NXT_ERROR;
1912504Sz.hong@f5.com         }
1922504Sz.hong@f5.com 
193*2654Sz.hong@f5.com         hash = nxt_http_argument_hash(mp, &str);
1942504Sz.hong@f5.com         if (nxt_slow_path(hash == -1)) {
1952504Sz.hong@f5.com             return NXT_ERROR;
1962504Sz.hong@f5.com         }
1972504Sz.hong@f5.com 
1982504Sz.hong@f5.com     } else if (nxt_str_start(name, "cookie_", 7)) {
1992504Sz.hong@f5.com         ref->handler = nxt_http_var_cookie;
2002504Sz.hong@f5.com         ref->cacheable = 1;
2012504Sz.hong@f5.com 
2022504Sz.hong@f5.com         str.start = name->start + 7;
2032504Sz.hong@f5.com         str.length = name->length - 7;
2042504Sz.hong@f5.com 
2052504Sz.hong@f5.com         if (str.length == 0) {
2062504Sz.hong@f5.com             return NXT_ERROR;
2072504Sz.hong@f5.com         }
2082504Sz.hong@f5.com 
209*2654Sz.hong@f5.com         hash = nxt_http_cookie_hash(mp, &str);
2102504Sz.hong@f5.com         if (nxt_slow_path(hash == -1)) {
2112504Sz.hong@f5.com             return NXT_ERROR;
2122504Sz.hong@f5.com         }
2132504Sz.hong@f5.com 
2142504Sz.hong@f5.com     } else {
2152504Sz.hong@f5.com         return NXT_ERROR;
2162504Sz.hong@f5.com     }
2172504Sz.hong@f5.com 
218*2654Sz.hong@f5.com     ref->data = nxt_var_field_new(mp, &str, (uint32_t) hash);
2192504Sz.hong@f5.com     if (nxt_slow_path(ref->data == NULL)) {
2202504Sz.hong@f5.com         return NXT_ERROR;
2212504Sz.hong@f5.com     }
2222504Sz.hong@f5.com 
2232504Sz.hong@f5.com     return NXT_OK;
2242504Sz.hong@f5.com }
2252504Sz.hong@f5.com 
2262504Sz.hong@f5.com 
2271563Svbart@nginx.com static nxt_int_t
nxt_http_var_dollar(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)2282504Sz.hong@f5.com nxt_http_var_dollar(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
2292158Sandrew@digital-domain.net {
2302158Sandrew@digital-domain.net     nxt_str_set(str, "$");
2312158Sandrew@digital-domain.net 
2322158Sandrew@digital-domain.net     return NXT_OK;
2332158Sandrew@digital-domain.net }
2342158Sandrew@digital-domain.net 
2352158Sandrew@digital-domain.net 
2362158Sandrew@digital-domain.net static nxt_int_t
nxt_http_var_request_time(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)2372214Sz.hong@f5.com nxt_http_var_request_time(nxt_task_t *task, nxt_str_t *str, void *ctx,
2382504Sz.hong@f5.com     void *data)
2392214Sz.hong@f5.com {
2402214Sz.hong@f5.com     u_char              *p;
2412214Sz.hong@f5.com     nxt_msec_t          ms;
2422214Sz.hong@f5.com     nxt_nsec_t          now;
2432214Sz.hong@f5.com     nxt_http_request_t  *r;
2442214Sz.hong@f5.com 
2452214Sz.hong@f5.com     r = ctx;
2462214Sz.hong@f5.com 
2472214Sz.hong@f5.com     now = nxt_thread_monotonic_time(task->thread);
2482214Sz.hong@f5.com     ms = (now - r->start_time) / 1000000;
2492214Sz.hong@f5.com 
2502214Sz.hong@f5.com     str->start = nxt_mp_nget(r->mem_pool, NXT_TIME_T_LEN + 4);
2512214Sz.hong@f5.com     if (nxt_slow_path(str->start == NULL)) {
2522214Sz.hong@f5.com         return NXT_ERROR;
2532214Sz.hong@f5.com     }
2542214Sz.hong@f5.com 
2552214Sz.hong@f5.com     p = nxt_sprintf(str->start, str->start + NXT_TIME_T_LEN, "%T.%03M",
2562214Sz.hong@f5.com                     (nxt_time_t) ms / 1000, ms % 1000);
2572214Sz.hong@f5.com 
2582214Sz.hong@f5.com     str->length = p - str->start;
2592214Sz.hong@f5.com 
2602214Sz.hong@f5.com     return NXT_OK;
2612214Sz.hong@f5.com }
2622214Sz.hong@f5.com 
2632214Sz.hong@f5.com 
2642214Sz.hong@f5.com static nxt_int_t
nxt_http_var_method(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)2652504Sz.hong@f5.com nxt_http_var_method(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
2661563Svbart@nginx.com {
2671563Svbart@nginx.com     nxt_http_request_t  *r;
2681563Svbart@nginx.com 
2691563Svbart@nginx.com     r = ctx;
2701563Svbart@nginx.com 
2711563Svbart@nginx.com     *str = *r->method;
2721563Svbart@nginx.com 
2731563Svbart@nginx.com     return NXT_OK;
2741563Svbart@nginx.com }
2751563Svbart@nginx.com 
2761563Svbart@nginx.com 
2771563Svbart@nginx.com static nxt_int_t
nxt_http_var_request_uri(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)2782147Sz.hong@f5.com nxt_http_var_request_uri(nxt_task_t *task, nxt_str_t *str, void *ctx,
2792504Sz.hong@f5.com     void *data)
2802110Salx.manpages@gmail.com {
2812110Salx.manpages@gmail.com     nxt_http_request_t  *r;
2822110Salx.manpages@gmail.com 
2832110Salx.manpages@gmail.com     r = ctx;
2842110Salx.manpages@gmail.com 
2852110Salx.manpages@gmail.com     *str = r->target;
2862110Salx.manpages@gmail.com 
2872110Salx.manpages@gmail.com     return NXT_OK;
2882110Salx.manpages@gmail.com }
2892110Salx.manpages@gmail.com 
2902110Salx.manpages@gmail.com 
2912110Salx.manpages@gmail.com static nxt_int_t
nxt_http_var_uri(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)2922504Sz.hong@f5.com nxt_http_var_uri(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
2931563Svbart@nginx.com {
2941563Svbart@nginx.com     nxt_http_request_t  *r;
2951563Svbart@nginx.com 
2961563Svbart@nginx.com     r = ctx;
2971563Svbart@nginx.com 
2981563Svbart@nginx.com     *str = *r->path;
2991563Svbart@nginx.com 
3001563Svbart@nginx.com     return NXT_OK;
3011563Svbart@nginx.com }
3021587Svbart@nginx.com 
3031587Svbart@nginx.com 
3041587Svbart@nginx.com static nxt_int_t
nxt_http_var_host(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)3052504Sz.hong@f5.com nxt_http_var_host(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
3061587Svbart@nginx.com {
3071587Svbart@nginx.com     nxt_http_request_t  *r;
3081587Svbart@nginx.com 
3091587Svbart@nginx.com     r = ctx;
3101587Svbart@nginx.com 
3111587Svbart@nginx.com     *str = r->host;
3121587Svbart@nginx.com 
3131587Svbart@nginx.com     return NXT_OK;
3141587Svbart@nginx.com }
3152147Sz.hong@f5.com 
3162147Sz.hong@f5.com 
3172147Sz.hong@f5.com static nxt_int_t
nxt_http_var_remote_addr(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)3182149Sz.hong@f5.com nxt_http_var_remote_addr(nxt_task_t *task, nxt_str_t *str, void *ctx,
3192504Sz.hong@f5.com     void *data)
3202149Sz.hong@f5.com {
3212149Sz.hong@f5.com     nxt_http_request_t  *r;
3222149Sz.hong@f5.com 
3232149Sz.hong@f5.com     r = ctx;
3242149Sz.hong@f5.com 
3252149Sz.hong@f5.com     str->length = r->remote->address_length;
3262149Sz.hong@f5.com     str->start = nxt_sockaddr_address(r->remote);
3272149Sz.hong@f5.com 
3282149Sz.hong@f5.com     return NXT_OK;
3292149Sz.hong@f5.com }
3302149Sz.hong@f5.com 
3312149Sz.hong@f5.com 
3322149Sz.hong@f5.com static nxt_int_t
nxt_http_var_time_local(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)3332504Sz.hong@f5.com nxt_http_var_time_local(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
3342149Sz.hong@f5.com {
3352149Sz.hong@f5.com     nxt_http_request_t  *r;
3362149Sz.hong@f5.com 
3372149Sz.hong@f5.com     static nxt_time_string_t  date_cache = {
3382149Sz.hong@f5.com         (nxt_atomic_uint_t) -1,
3392149Sz.hong@f5.com         nxt_http_log_date,
3402149Sz.hong@f5.com         "%02d/%s/%4d:%02d:%02d:%02d %c%02d%02d",
3412149Sz.hong@f5.com         nxt_length("31/Dec/1986:19:40:00 +0300"),
3422149Sz.hong@f5.com         NXT_THREAD_TIME_LOCAL,
3432149Sz.hong@f5.com         NXT_THREAD_TIME_SEC,
3442149Sz.hong@f5.com     };
3452149Sz.hong@f5.com 
3462149Sz.hong@f5.com     r = ctx;
3472149Sz.hong@f5.com 
3482149Sz.hong@f5.com     str->length = date_cache.size;
3492149Sz.hong@f5.com 
3502149Sz.hong@f5.com     str->start = nxt_mp_nget(r->mem_pool, str->length);
3512149Sz.hong@f5.com     if (nxt_slow_path(str->start == NULL)) {
3522149Sz.hong@f5.com         return NXT_ERROR;
3532149Sz.hong@f5.com     }
3542149Sz.hong@f5.com 
3552149Sz.hong@f5.com     str->length = nxt_thread_time_string(task->thread, &date_cache, str->start)
3562149Sz.hong@f5.com                   - str->start;
3572149Sz.hong@f5.com 
3582149Sz.hong@f5.com     return NXT_OK;
3592149Sz.hong@f5.com }
3602149Sz.hong@f5.com 
3612149Sz.hong@f5.com 
3622149Sz.hong@f5.com static u_char *
nxt_http_log_date(u_char * buf,nxt_realtime_t * now,struct tm * tm,size_t size,const char * format)3632149Sz.hong@f5.com nxt_http_log_date(u_char *buf, nxt_realtime_t *now, struct tm *tm,
3642149Sz.hong@f5.com     size_t size, const char *format)
3652149Sz.hong@f5.com {
3662149Sz.hong@f5.com     u_char  sign;
3672149Sz.hong@f5.com     time_t  gmtoff;
3682149Sz.hong@f5.com 
3692149Sz.hong@f5.com     static const char  *month[] = { "Jan", "Feb", "Mar", "Apr", "May", "Jun",
3702149Sz.hong@f5.com                                     "Jul", "Aug", "Sep", "Oct", "Nov", "Dec" };
3712149Sz.hong@f5.com 
3722149Sz.hong@f5.com     gmtoff = nxt_timezone(tm) / 60;
3732149Sz.hong@f5.com 
3742149Sz.hong@f5.com     if (gmtoff < 0) {
3752149Sz.hong@f5.com         gmtoff = -gmtoff;
3762149Sz.hong@f5.com         sign = '-';
3772149Sz.hong@f5.com 
3782149Sz.hong@f5.com     } else {
3792149Sz.hong@f5.com         sign = '+';
3802149Sz.hong@f5.com     }
3812149Sz.hong@f5.com 
3822149Sz.hong@f5.com     return nxt_sprintf(buf, buf + size, format,
3832149Sz.hong@f5.com                        tm->tm_mday, month[tm->tm_mon], tm->tm_year + 1900,
3842149Sz.hong@f5.com                        tm->tm_hour, tm->tm_min, tm->tm_sec,
3852149Sz.hong@f5.com                        sign, gmtoff / 60, gmtoff % 60);
3862149Sz.hong@f5.com }
3872149Sz.hong@f5.com 
3882149Sz.hong@f5.com 
3892149Sz.hong@f5.com static nxt_int_t
nxt_http_var_request_line(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)3902149Sz.hong@f5.com nxt_http_var_request_line(nxt_task_t *task, nxt_str_t *str, void *ctx,
3912504Sz.hong@f5.com     void *data)
3922149Sz.hong@f5.com {
3932149Sz.hong@f5.com     nxt_http_request_t  *r;
3942149Sz.hong@f5.com 
3952149Sz.hong@f5.com     r = ctx;
3962149Sz.hong@f5.com 
3972430Salx@nginx.com     *str = r->request_line;
3982149Sz.hong@f5.com 
3992149Sz.hong@f5.com     return NXT_OK;
4002149Sz.hong@f5.com }
4012149Sz.hong@f5.com 
4022149Sz.hong@f5.com 
4032149Sz.hong@f5.com static nxt_int_t
nxt_http_var_request_id(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)4042590Szelenkov@nginx.com nxt_http_var_request_id(nxt_task_t *task, nxt_str_t *str, void *ctx,
4052590Szelenkov@nginx.com     void *data)
4062590Szelenkov@nginx.com {
4072590Szelenkov@nginx.com     nxt_random_t        *rand;
4082590Szelenkov@nginx.com     nxt_http_request_t  *r;
4092590Szelenkov@nginx.com 
4102590Szelenkov@nginx.com     r = ctx;
4112590Szelenkov@nginx.com 
4122590Szelenkov@nginx.com     str->start = nxt_mp_nget(r->mem_pool, 32);
4132590Szelenkov@nginx.com     if (nxt_slow_path(str->start == NULL)) {
4142590Szelenkov@nginx.com         return NXT_ERROR;
4152590Szelenkov@nginx.com     }
4162590Szelenkov@nginx.com 
4172590Szelenkov@nginx.com     str->length = 32;
4182590Szelenkov@nginx.com 
4192590Szelenkov@nginx.com     rand = &task->thread->random;
4202590Szelenkov@nginx.com 
4212590Szelenkov@nginx.com     (void) nxt_sprintf(str->start, str->start + 32, "%08xD%08xD%08xD%08xD",
4222590Szelenkov@nginx.com                        nxt_random(rand), nxt_random(rand),
4232590Szelenkov@nginx.com                        nxt_random(rand), nxt_random(rand));
4242590Szelenkov@nginx.com 
4252590Szelenkov@nginx.com     return NXT_OK;
4262590Szelenkov@nginx.com }
4272590Szelenkov@nginx.com 
4282590Szelenkov@nginx.com 
4292590Szelenkov@nginx.com static nxt_int_t
nxt_http_var_body_bytes_sent(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)4302149Sz.hong@f5.com nxt_http_var_body_bytes_sent(nxt_task_t *task, nxt_str_t *str, void *ctx,
4312504Sz.hong@f5.com     void *data)
4322149Sz.hong@f5.com {
4332505Sz.hong@f5.com     u_char              *p;
4342149Sz.hong@f5.com     nxt_off_t           bytes;
4352149Sz.hong@f5.com     nxt_http_request_t  *r;
4362149Sz.hong@f5.com 
4372149Sz.hong@f5.com     r = ctx;
4382149Sz.hong@f5.com 
4392149Sz.hong@f5.com     str->start = nxt_mp_nget(r->mem_pool, NXT_OFF_T_LEN);
4402149Sz.hong@f5.com     if (nxt_slow_path(str->start == NULL)) {
4412149Sz.hong@f5.com         return NXT_ERROR;
4422149Sz.hong@f5.com     }
4432149Sz.hong@f5.com 
4442149Sz.hong@f5.com     bytes = nxt_http_proto[r->protocol].body_bytes_sent(task, r->proto);
4452149Sz.hong@f5.com 
4462505Sz.hong@f5.com     p = nxt_sprintf(str->start, str->start + NXT_OFF_T_LEN, "%O", bytes);
4472505Sz.hong@f5.com 
4482505Sz.hong@f5.com     str->length = p - str->start;
4492149Sz.hong@f5.com 
4502149Sz.hong@f5.com     return NXT_OK;
4512149Sz.hong@f5.com }
4522149Sz.hong@f5.com 
4532149Sz.hong@f5.com 
4542149Sz.hong@f5.com static nxt_int_t
nxt_http_var_status(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)4552504Sz.hong@f5.com nxt_http_var_status(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
4562149Sz.hong@f5.com {
4572149Sz.hong@f5.com     nxt_http_request_t  *r;
4582149Sz.hong@f5.com 
4592149Sz.hong@f5.com     r = ctx;
4602149Sz.hong@f5.com 
4612149Sz.hong@f5.com     str->start = nxt_mp_nget(r->mem_pool, 3);
4622149Sz.hong@f5.com     if (nxt_slow_path(str->start == NULL)) {
4632149Sz.hong@f5.com         return NXT_ERROR;
4642149Sz.hong@f5.com     }
4652149Sz.hong@f5.com 
4662591Szelenkov@nginx.com     (void) nxt_sprintf(str->start, str->start + 3, "%03d", r->status);
4672505Sz.hong@f5.com 
4682591Szelenkov@nginx.com     str->length = 3;
4692149Sz.hong@f5.com 
4702149Sz.hong@f5.com     return NXT_OK;
4712149Sz.hong@f5.com }
4722149Sz.hong@f5.com 
4732149Sz.hong@f5.com 
4742149Sz.hong@f5.com static nxt_int_t
nxt_http_var_referer(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)4752504Sz.hong@f5.com nxt_http_var_referer(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
4762149Sz.hong@f5.com {
4772149Sz.hong@f5.com     nxt_http_request_t  *r;
4782149Sz.hong@f5.com 
4792149Sz.hong@f5.com     r = ctx;
4802149Sz.hong@f5.com 
4812149Sz.hong@f5.com     if (r->referer != NULL) {
4822149Sz.hong@f5.com         str->start = r->referer->value;
4832149Sz.hong@f5.com         str->length = r->referer->value_length;
4842149Sz.hong@f5.com 
4852149Sz.hong@f5.com     } else {
4862149Sz.hong@f5.com         nxt_str_null(str);
4872149Sz.hong@f5.com     }
4882149Sz.hong@f5.com 
4892149Sz.hong@f5.com     return NXT_OK;
4902149Sz.hong@f5.com }
4912149Sz.hong@f5.com 
4922149Sz.hong@f5.com 
4932149Sz.hong@f5.com static nxt_int_t
nxt_http_var_user_agent(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)4942504Sz.hong@f5.com nxt_http_var_user_agent(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
4952149Sz.hong@f5.com {
4962149Sz.hong@f5.com     nxt_http_request_t  *r;
4972149Sz.hong@f5.com 
4982149Sz.hong@f5.com     r = ctx;
4992149Sz.hong@f5.com 
5002149Sz.hong@f5.com     if (r->user_agent != NULL) {
5012149Sz.hong@f5.com         str->start = r->user_agent->value;
5022149Sz.hong@f5.com         str->length = r->user_agent->value_length;
5032149Sz.hong@f5.com 
5042149Sz.hong@f5.com     } else {
5052149Sz.hong@f5.com         nxt_str_null(str);
5062149Sz.hong@f5.com     }
5072149Sz.hong@f5.com 
5082149Sz.hong@f5.com     return NXT_OK;
5092149Sz.hong@f5.com }
5102149Sz.hong@f5.com 
5112149Sz.hong@f5.com 
5122149Sz.hong@f5.com static nxt_int_t
nxt_http_var_response_connection(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)5132505Sz.hong@f5.com nxt_http_var_response_connection(nxt_task_t *task, nxt_str_t *str, void *ctx,
5142505Sz.hong@f5.com     void *data)
5152505Sz.hong@f5.com {
5162505Sz.hong@f5.com     nxt_int_t           conn;
5172505Sz.hong@f5.com     nxt_bool_t          http11;
5182505Sz.hong@f5.com     nxt_h1proto_t       *h1p;
5192505Sz.hong@f5.com     nxt_http_request_t  *r;
5202505Sz.hong@f5.com 
5212505Sz.hong@f5.com     static const nxt_str_t  connection[3] = {
5222505Sz.hong@f5.com         nxt_string("close"),
5232505Sz.hong@f5.com         nxt_string("keep-alive"),
5242505Sz.hong@f5.com         nxt_string("Upgrade"),
5252505Sz.hong@f5.com     };
5262505Sz.hong@f5.com 
5272505Sz.hong@f5.com     r = ctx;
5282505Sz.hong@f5.com     h1p = r->proto.h1;
5292505Sz.hong@f5.com 
5302505Sz.hong@f5.com     conn = -1;
5312505Sz.hong@f5.com 
5322505Sz.hong@f5.com     if (r->websocket_handshake && r->status == NXT_HTTP_SWITCHING_PROTOCOLS) {
5332505Sz.hong@f5.com         conn = 2;
5342505Sz.hong@f5.com 
5352505Sz.hong@f5.com     } else {
5362505Sz.hong@f5.com         http11 = nxt_h1p_is_http11(h1p);
5372505Sz.hong@f5.com 
5382505Sz.hong@f5.com         if (http11 ^ h1p->keepalive) {
5392505Sz.hong@f5.com             conn = h1p->keepalive;
5402505Sz.hong@f5.com         }
5412505Sz.hong@f5.com     }
5422505Sz.hong@f5.com 
5432505Sz.hong@f5.com     if (conn >= 0) {
5442505Sz.hong@f5.com         *str = connection[conn];
5452505Sz.hong@f5.com 
5462505Sz.hong@f5.com     } else {
5472505Sz.hong@f5.com         nxt_str_null(str);
5482505Sz.hong@f5.com     }
5492505Sz.hong@f5.com 
5502505Sz.hong@f5.com     return NXT_OK;
5512505Sz.hong@f5.com }
5522505Sz.hong@f5.com 
5532505Sz.hong@f5.com 
5542505Sz.hong@f5.com static nxt_int_t
nxt_http_var_response_content_length(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)5552505Sz.hong@f5.com nxt_http_var_response_content_length(nxt_task_t *task, nxt_str_t *str,
5562505Sz.hong@f5.com     void *ctx, void *data)
5572505Sz.hong@f5.com {
5582505Sz.hong@f5.com     u_char              *p;
5592505Sz.hong@f5.com     nxt_http_request_t  *r;
5602505Sz.hong@f5.com 
5612505Sz.hong@f5.com     r = ctx;
5622505Sz.hong@f5.com 
5632505Sz.hong@f5.com     if (r->resp.content_length != NULL) {
5642505Sz.hong@f5.com         str->length = r->resp.content_length->value_length;
5652505Sz.hong@f5.com         str->start = r->resp.content_length->value;
5662505Sz.hong@f5.com 
5672505Sz.hong@f5.com         return NXT_OK;
5682505Sz.hong@f5.com     }
5692505Sz.hong@f5.com 
5702505Sz.hong@f5.com     if (r->resp.content_length_n >= 0) {
5712505Sz.hong@f5.com         str->start = nxt_mp_nget(r->mem_pool, NXT_OFF_T_LEN);
5722505Sz.hong@f5.com         if (str->start == NULL) {
5732505Sz.hong@f5.com             return NXT_ERROR;
5742505Sz.hong@f5.com         }
5752505Sz.hong@f5.com 
5762505Sz.hong@f5.com         p = nxt_sprintf(str->start, str->start + NXT_OFF_T_LEN,
5772505Sz.hong@f5.com                         "%O", r->resp.content_length_n);
5782505Sz.hong@f5.com 
5792505Sz.hong@f5.com         str->length = p - str->start;
5802505Sz.hong@f5.com 
5812505Sz.hong@f5.com         return NXT_OK;
5822505Sz.hong@f5.com     }
5832505Sz.hong@f5.com 
5842505Sz.hong@f5.com     nxt_str_null(str);
5852505Sz.hong@f5.com 
5862505Sz.hong@f5.com     return NXT_OK;
5872505Sz.hong@f5.com }
5882505Sz.hong@f5.com 
5892505Sz.hong@f5.com 
5902505Sz.hong@f5.com static nxt_int_t
nxt_http_var_response_transfer_encoding(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)5912505Sz.hong@f5.com nxt_http_var_response_transfer_encoding(nxt_task_t *task, nxt_str_t *str,
5922505Sz.hong@f5.com     void *ctx, void *data)
5932505Sz.hong@f5.com {
5942505Sz.hong@f5.com     nxt_http_request_t  *r;
5952505Sz.hong@f5.com 
5962505Sz.hong@f5.com     r = ctx;
5972505Sz.hong@f5.com 
5982505Sz.hong@f5.com     if (r->proto.h1->chunked) {
5992505Sz.hong@f5.com         nxt_str_set(str, "chunked");
6002505Sz.hong@f5.com 
6012505Sz.hong@f5.com     } else {
6022505Sz.hong@f5.com         nxt_str_null(str);
6032505Sz.hong@f5.com     }
6042505Sz.hong@f5.com 
6052505Sz.hong@f5.com     return NXT_OK;
6062505Sz.hong@f5.com }
6072505Sz.hong@f5.com 
6082505Sz.hong@f5.com 
6092505Sz.hong@f5.com static nxt_int_t
nxt_http_var_arg(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)6102504Sz.hong@f5.com nxt_http_var_arg(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
6112147Sz.hong@f5.com {
6122147Sz.hong@f5.com     nxt_array_t            *args;
6132147Sz.hong@f5.com     nxt_var_field_t        *vf;
6142147Sz.hong@f5.com     nxt_http_request_t     *r;
6152147Sz.hong@f5.com     nxt_http_name_value_t  *nv, *start;
6162147Sz.hong@f5.com 
6172147Sz.hong@f5.com     r = ctx;
6182504Sz.hong@f5.com     vf = data;
6192147Sz.hong@f5.com 
6202147Sz.hong@f5.com     args = nxt_http_arguments_parse(r);
6212147Sz.hong@f5.com     if (nxt_slow_path(args == NULL)) {
6222147Sz.hong@f5.com         return NXT_ERROR;
6232147Sz.hong@f5.com     }
6242147Sz.hong@f5.com 
6252147Sz.hong@f5.com     start = args->elts;
6262147Sz.hong@f5.com     nv = start + args->nelts - 1;
6272147Sz.hong@f5.com 
6282147Sz.hong@f5.com     while (nv >= start) {
6292147Sz.hong@f5.com 
6302147Sz.hong@f5.com         if (vf->hash == nv->hash
6312147Sz.hong@f5.com             && vf->name.length == nv->name_length
6322231Salx@nginx.com             && memcmp(vf->name.start, nv->name, nv->name_length) == 0)
6332147Sz.hong@f5.com         {
6342147Sz.hong@f5.com             str->start = nv->value;
6352147Sz.hong@f5.com             str->length = nv->value_length;
6362147Sz.hong@f5.com 
6372147Sz.hong@f5.com             return NXT_OK;
6382147Sz.hong@f5.com         }
6392147Sz.hong@f5.com 
6402147Sz.hong@f5.com         nv--;
6412147Sz.hong@f5.com     }
6422147Sz.hong@f5.com 
6432147Sz.hong@f5.com     nxt_str_null(str);
6442147Sz.hong@f5.com 
6452147Sz.hong@f5.com     return NXT_OK;
6462147Sz.hong@f5.com }
6472147Sz.hong@f5.com 
6482147Sz.hong@f5.com 
6492147Sz.hong@f5.com static nxt_int_t
nxt_http_var_header(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)6502504Sz.hong@f5.com nxt_http_var_header(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
6512147Sz.hong@f5.com {
6522147Sz.hong@f5.com     nxt_var_field_t     *vf;
6532147Sz.hong@f5.com     nxt_http_field_t    *f;
6542147Sz.hong@f5.com     nxt_http_request_t  *r;
6552147Sz.hong@f5.com 
6562147Sz.hong@f5.com     r = ctx;
6572504Sz.hong@f5.com     vf = data;
6582147Sz.hong@f5.com 
6592147Sz.hong@f5.com     nxt_list_each(f, r->fields) {
6602147Sz.hong@f5.com 
6612147Sz.hong@f5.com         if (vf->hash == f->hash
6622147Sz.hong@f5.com             && vf->name.length == f->name_length
6632147Sz.hong@f5.com             && nxt_strncasecmp(vf->name.start, f->name, f->name_length) == 0)
6642147Sz.hong@f5.com         {
6652147Sz.hong@f5.com             str->start = f->value;
6662147Sz.hong@f5.com             str->length = f->value_length;
6672147Sz.hong@f5.com 
6682147Sz.hong@f5.com             return NXT_OK;
6692147Sz.hong@f5.com         }
6702147Sz.hong@f5.com 
6712147Sz.hong@f5.com     } nxt_list_loop;
6722147Sz.hong@f5.com 
6732147Sz.hong@f5.com     nxt_str_null(str);
6742147Sz.hong@f5.com 
6752147Sz.hong@f5.com     return NXT_OK;
6762147Sz.hong@f5.com }
6772147Sz.hong@f5.com 
6782147Sz.hong@f5.com 
6792147Sz.hong@f5.com static nxt_int_t
nxt_http_var_cookie(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)6802504Sz.hong@f5.com nxt_http_var_cookie(nxt_task_t *task, nxt_str_t *str, void *ctx, void *data)
6812147Sz.hong@f5.com {
6822147Sz.hong@f5.com     nxt_array_t            *cookies;
6832147Sz.hong@f5.com     nxt_var_field_t        *vf;
6842147Sz.hong@f5.com     nxt_http_request_t     *r;
6852147Sz.hong@f5.com     nxt_http_name_value_t  *nv, *end;
6862147Sz.hong@f5.com 
6872147Sz.hong@f5.com     r = ctx;
6882504Sz.hong@f5.com     vf = data;
6892147Sz.hong@f5.com 
6902147Sz.hong@f5.com     cookies = nxt_http_cookies_parse(r);
6912147Sz.hong@f5.com     if (nxt_slow_path(cookies == NULL)) {
6922147Sz.hong@f5.com         return NXT_ERROR;
6932147Sz.hong@f5.com     }
6942147Sz.hong@f5.com 
6952147Sz.hong@f5.com     nv = cookies->elts;
6962147Sz.hong@f5.com     end = nv + cookies->nelts;
6972147Sz.hong@f5.com 
6982147Sz.hong@f5.com     while (nv < end) {
6992147Sz.hong@f5.com 
7002147Sz.hong@f5.com         if (vf->hash == nv->hash
7012147Sz.hong@f5.com             && vf->name.length == nv->name_length
7022231Salx@nginx.com             && memcmp(vf->name.start, nv->name, nv->name_length) == 0)
7032147Sz.hong@f5.com         {
7042147Sz.hong@f5.com             str->start = nv->value;
7052147Sz.hong@f5.com             str->length = nv->value_length;
7062147Sz.hong@f5.com 
7072147Sz.hong@f5.com             return NXT_OK;
7082147Sz.hong@f5.com         }
7092147Sz.hong@f5.com 
7102147Sz.hong@f5.com         nv++;
7112147Sz.hong@f5.com     }
7122147Sz.hong@f5.com 
7132147Sz.hong@f5.com     nxt_str_null(str);
7142147Sz.hong@f5.com 
7152147Sz.hong@f5.com     return NXT_OK;
7162147Sz.hong@f5.com }
7172505Sz.hong@f5.com 
7182505Sz.hong@f5.com 
7192505Sz.hong@f5.com static int
nxt_http_field_name_cmp(nxt_str_t * name,nxt_http_field_t * field)7202505Sz.hong@f5.com nxt_http_field_name_cmp(nxt_str_t *name, nxt_http_field_t *field)
7212505Sz.hong@f5.com {
7222505Sz.hong@f5.com     size_t  i;
7232505Sz.hong@f5.com     u_char  c1, c2;
7242505Sz.hong@f5.com 
7252505Sz.hong@f5.com     if (name->length != field->name_length) {
7262505Sz.hong@f5.com         return 1;
7272505Sz.hong@f5.com     }
7282505Sz.hong@f5.com 
7292505Sz.hong@f5.com     for (i = 0; i < name->length; i++) {
7302505Sz.hong@f5.com         c1 = name->start[i];
7312505Sz.hong@f5.com         c2 = field->name[i];
7322505Sz.hong@f5.com 
7332505Sz.hong@f5.com         if (c2 >= 'A' && c2 <= 'Z') {
7342505Sz.hong@f5.com             c2 |= 0x20;
7352505Sz.hong@f5.com 
7362505Sz.hong@f5.com         } else if (c2 == '-') {
7372505Sz.hong@f5.com             c2 = '_';
7382505Sz.hong@f5.com         }
7392505Sz.hong@f5.com 
7402505Sz.hong@f5.com         if (c1 != c2) {
7412505Sz.hong@f5.com             return 1;
7422505Sz.hong@f5.com         }
7432505Sz.hong@f5.com     }
7442505Sz.hong@f5.com 
7452505Sz.hong@f5.com     return 0;
7462505Sz.hong@f5.com }
7472505Sz.hong@f5.com 
7482505Sz.hong@f5.com 
7492505Sz.hong@f5.com static nxt_int_t
nxt_http_var_response_header(nxt_task_t * task,nxt_str_t * str,void * ctx,void * data)7502505Sz.hong@f5.com nxt_http_var_response_header(nxt_task_t *task, nxt_str_t *str, void *ctx,
7512505Sz.hong@f5.com     void *data)
7522505Sz.hong@f5.com {
7532505Sz.hong@f5.com     nxt_str_t           *name;
7542505Sz.hong@f5.com     nxt_http_field_t    *f;
7552505Sz.hong@f5.com     nxt_http_request_t  *r;
7562505Sz.hong@f5.com 
7572505Sz.hong@f5.com     r = ctx;
7582505Sz.hong@f5.com     name = data;
7592505Sz.hong@f5.com 
7602505Sz.hong@f5.com     nxt_list_each(f, r->resp.fields) {
7612505Sz.hong@f5.com 
7622505Sz.hong@f5.com         if (f->skip) {
7632505Sz.hong@f5.com             continue;
7642505Sz.hong@f5.com         }
7652505Sz.hong@f5.com 
7662505Sz.hong@f5.com         if (nxt_http_field_name_cmp(name, f) == 0) {
7672505Sz.hong@f5.com             str->start = f->value;
7682505Sz.hong@f5.com             str->length = f->value_length;
7692505Sz.hong@f5.com 
7702505Sz.hong@f5.com             return NXT_OK;
7712505Sz.hong@f5.com         }
7722505Sz.hong@f5.com 
7732505Sz.hong@f5.com     } nxt_list_loop;
7742505Sz.hong@f5.com 
7752505Sz.hong@f5.com     nxt_str_null(str);
7762505Sz.hong@f5.com 
7772505Sz.hong@f5.com     return NXT_OK;
7782505Sz.hong@f5.com }
779