static char *
ngx_http_set_iconv_conf_handler(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ndk_set_var_t                filter;
    ngx_str_t                   *value, s[3];

    max_iconv_bufs = 256;

    filter.type = NDK_SET_VAR_MULTI_VALUE;
    filter.func = ngx_http_set_iconv_handler;
    filter.size = 3;

    /* set_iconv $dst $src from= to= */
    value = cf->args->elts;
    value++;
    s[0] = value[1];

    s[1] = value[2];
    if (ngx_strncasecmp((u_char *) "from=", s[1].data, sizeof("from=") - 1)
        != 0)
    {
        return NGX_CONF_ERROR;
    }
    s[1].data += sizeof("from=") - 1;
    s[1].len -= (sizeof("from=") - 1);

    s[2] = value[3];
    if (ngx_strncasecmp((u_char *) "to=", s[2].data, sizeof("to=") - 1) != 0) {
        return NGX_CONF_ERROR;
    }
    s[2].data += sizeof("to=") - 1;
    s[2].len -= (sizeof("to=") - 1);

    return ndk_set_var_multi_value_core(cf, value, s, &filter);
}
char *
ngx_http_lua_set_by_lua(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t           *args;
    ngx_str_t            target;
    ndk_set_var_t        filter;

    /*
     * args[0] = "set_by_lua"
     * args[1] = target variable name
     * args[2] = lua script to be executed
     * args[3..] = real params
     * */
    args = cf->args->elts;
    target = args[1];

    /*  prevent variable appearing in Lua inline script/file path */

#if 0
    if (ngx_http_lua_has_inline_var(&args[2])) {
        ngx_conf_log_error(NGX_LOG_ERR, cf, 0,
                "Lua inline script or file path should not has inline variable: %V",
                &args[2]);
        return NGX_CONF_ERROR;
    }
#endif

    filter.type = NDK_SET_VAR_MULTI_VALUE_DATA;
    filter.func = cmd->post;
    filter.size = cf->args->nelts - 2;    /*  get number of real params + 1 (lua script) */
    filter.data = (void*)filter.size;

    return ndk_set_var_multi_value_core(cf, &target, &args[2], &filter);
}
char *
ndk_set_var_multi_value (ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t               *value;
    ndk_set_var_t      *filter;

    value = cf->args->elts;
    value++;

    filter = (ndk_set_var_t *) cmd->post;

    return  ndk_set_var_multi_value_core (cf, value, value + 1, filter);
}
char *
ngx_http_set_if_empty(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t               *value;
    ndk_set_var_t            filter;

    value = cf->args->elts;

    filter.type = NDK_SET_VAR_MULTI_VALUE;
    filter.func = ngx_http_set_misc_set_if_empty;
    filter.size = 2;
    filter.data = NULL;

    return  ndk_set_var_multi_value_core(cf, &value[1], &value[1], &filter);
}
char *
ngx_http_lua_set_by_lua_file(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    u_char              *p;
    ngx_str_t           *value;
    ngx_str_t            target;
    ndk_set_var_t        filter;

    ngx_http_lua_set_var_data_t     *filter_data;

    /*
     * value[0] = "set_by_lua_file"
     * value[1] = target variable name
     * value[2] = lua script file path to be executed
     * value[3..] = real params
     * */
    value = cf->args->elts;
    target = value[1];

    filter.type = NDK_SET_VAR_MULTI_VALUE_DATA;
    filter.func = cmd->post;
    filter.size = cf->args->nelts - 2;    /*  get number of real params and
                                              lua script */

    filter_data = ngx_palloc(cf->pool, sizeof(ngx_http_lua_set_var_data_t));
    if (filter_data == NULL) {
        return NGX_CONF_ERROR;
    }

    filter_data->size = filter.size;

    p = ngx_palloc(cf->pool, NGX_HTTP_LUA_FILE_KEY_LEN + 1);
    if (p == NULL) {
        return NGX_CONF_ERROR;
    }

    filter_data->key = p;

    p = ngx_copy(p, NGX_HTTP_LUA_FILE_TAG, NGX_HTTP_LUA_FILE_TAG_LEN);
    p = ngx_http_lua_digest_hex(p, value[2].data, value[2].len);
    *p = '\0';

    ngx_str_null(&filter_data->script);

    filter.data = filter_data;

    return ndk_set_var_multi_value_core(cf, &target, &value[2], &filter);
}
char *
ngx_http_set_hashed_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
{
    ngx_str_t               *value;
    ndk_set_var_t            filter;
    ngx_uint_t               n;
    ngx_str_t               *var;
    ngx_str_t               *ulname;
    ndk_upstream_list_t     *ul;
    ngx_str_t               *v;

    value = cf->args->elts;

    var = &value[1];
    ulname = &value[2];

    n = ngx_http_script_variables_count(ulname);

    filter.func = (void *) ngx_http_set_misc_set_hashed_upstream;

    if (n) {
        /* upstream list name contains variables */
        v = &value[2];
        filter.size = 2;
        filter.data = NULL;
        filter.type = NDK_SET_VAR_MULTI_VALUE_DATA;

        return  ndk_set_var_multi_value_core(cf, var, v, &filter);
    }

    ul = ndk_get_upstream_list(ndk_http_conf_get_main_conf(cf),
                                            ulname->data, ulname->len);
    if (ul == NULL) {
        ngx_log_error(NGX_LOG_ERR, cf->log, 0,
                      "set_hashed_upstream: upstream list \"%V\" "
                      "not defined yet", ulname);
        return NGX_CONF_ERROR;
    }

    v = &value[3];

    filter.size = 1;
    filter.data = ul;
    filter.type = NDK_SET_VAR_VALUE_DATA;

    return ndk_set_var_value_core(cf, var, v, &filter);
}
static char *
ngx_http_set_form_input_conf_handler(ngx_conf_t *cf, ngx_command_t *cmd,
    void *conf)
{
    ndk_set_var_t                            filter;
    ngx_str_t                               *value, s;
    u_char                                  *p;

#if defined(nginx_version) && nginx_version >= 8042 && nginx_version <= 8053
    return "does not work with " NGINX_VER;
#endif

    ngx_http_form_input_used = 1;

    filter.type = NDK_SET_VAR_MULTI_VALUE;
    filter.size = 1;

    value = cf->args->elts;

    if ((value->len == sizeof("set_form_input_multi") - 1) &&
        ngx_strncmp(value->data, "set_form_input_multi", value->len) == 0)
    {
        dd("use ngx_http_form_input_multi");
        filter.func = (void *) ngx_http_set_form_input_multi;

    } else {
        filter.func = (void *) ngx_http_set_form_input;
    }

    value++;

    if (cf->args->nelts == 2) {
        p = value->data;
        p++;
        s.len = value->len - 1;
        s.data = p;

    } else if (cf->args->nelts == 3) {
        s.len = (value + 1)->len;
        s.data = (value + 1)->data;
    }

    return ndk_set_var_multi_value_core (cf, value,  &s, &filter);
}