Example #1
0
ngx_int_t
ngx_http_redis2_build_query(ngx_http_request_t *r, ngx_array_t *queries,
    ngx_buf_t **b)
{
    ngx_uint_t                       i, j;
    ngx_uint_t                       n;
    ngx_str_t                       *arg;
    ngx_array_t                     *args;
    size_t                           len;
    ngx_array_t                    **query_args;
    ngx_http_complex_value_t       **complex_arg;
    u_char                          *p;
    ngx_http_redis2_loc_conf_t      *rlcf;

    rlcf = ngx_http_get_module_loc_conf(r, ngx_http_redis2_module);

    query_args = rlcf->queries->elts;

    n = 0;
    for (i = 0; i < rlcf->queries->nelts; i++) {
        for (j = 0; j < query_args[i]->nelts; j++) {
            n++;
        }
    }

    args = ngx_array_create(r->pool, n, sizeof(ngx_str_t));

    if (args == NULL) {
        return NGX_ERROR;
    }

    len = 0;
    n = 0;

    for (i = 0; i < rlcf->queries->nelts; i++) {
        complex_arg = query_args[i]->elts;

        len += sizeof("*") - 1
             + ngx_get_num_size(query_args[i]->nelts)
             + sizeof("\r\n") - 1
             ;

        for (j = 0; j < query_args[i]->nelts; j++) {
            n++;

            arg = ngx_array_push(args);
            if (arg == NULL) {
                return NGX_ERROR;
            }

            if (ngx_http_complex_value(r, complex_arg[j], arg) != NGX_OK) {
                return NGX_ERROR;
            }

            len += sizeof("$") - 1
                 + ngx_get_num_size(arg->len)
                 + sizeof("\r\n") - 1
                 + arg->len
                 + sizeof("\r\n") - 1
                 ;
        }
    }

    *b = ngx_create_temp_buf(r->pool, len);
    if (*b == NULL) {
        return NGX_ERROR;
    }

    p = (*b)->last;

    arg = args->elts;

    n = 0;
    for (i = 0; i < rlcf->queries->nelts; i++) {
        *p++ = '*';
        p = ngx_sprintf(p, "%uz", query_args[i]->nelts);
        *p++ = '\r'; *p++ = '\n';

        for (j = 0; j < query_args[i]->nelts; j++) {
            *p++ = '$';
            p = ngx_sprintf(p, "%uz", arg[n].len);
            *p++ = '\r'; *p++ = '\n';
            p = ngx_copy(p, arg[n].data, arg[n].len);
            *p++ = '\r'; *p++ = '\n';

            n++;
        }
    }

    dd("query: %.*s", (int) (p - (*b)->pos), (*b)->pos);

    if (p - (*b)->pos != (ssize_t) len) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "redis2: redis2_query buffer error %uz != %uz",
                (size_t) (p - (*b)->pos), len);

        return NGX_ERROR;
    }

    (*b)->last = p;

    return NGX_OK;
}
ngx_int_t
ngx_http_rds_csv_output_header(ngx_http_request_t *r,
    ngx_http_rds_csv_ctx_t *ctx, ngx_http_rds_header_t *header)
{
    u_char                  *pos, *last;
    size_t                   size;
    uintptr_t                escape;
    unsigned                 last_buf = 0;
    unsigned                 need_quotes = 0;
    u_char                   sep;

    ngx_http_rds_csv_loc_conf_t       *conf;

    /* calculate the buffer size */

    conf = ngx_http_get_module_loc_conf(r, ngx_http_rds_csv_filter_module);

    if (conf->field_name_header) {
        size = sizeof("errcode,errstr,insert_id,affected_rows") - 1
               + conf->row_term.len;

    } else {
        size = 0;
    }

    sep = (u_char) conf->field_sep;

    size += 3 /* field seperators */ + conf->row_term.len;

    size += ngx_get_num_size(header->std_errcode);

    escape = ngx_http_rds_csv_escape_csv_str(sep, NULL, header->errstr.data,
                                             header->errstr.len,
                                             &need_quotes);

    if (need_quotes) {
        size += sizeof("\"\"") - 1;
    }

    size += header->errstr.len + escape
            + ngx_get_num_size(header->insert_id)
            + ngx_get_num_size(header->affected_rows);

    /* create the buffer */

    pos = ngx_http_rds_csv_request_mem(r, ctx, size);
    if (pos == NULL) {
        return NGX_ERROR;
    }

    last = pos;

    /* fill up the buffer */

    last = ngx_sprintf(last, "errcode%cerrstr%cinsert_id%caffected_rows%V"
                       "%uD%c", sep, sep, sep, &conf->row_term,
                       (uint32_t) header->std_errcode, sep);

    if (need_quotes) {
        *last++ = '"';
    }

    if (escape == 0) {
        last = ngx_copy(last, header->errstr.data, header->errstr.len);

    } else {
        last = (u_char *)
                ngx_http_rds_csv_escape_csv_str(sep, last,
                                                header->errstr.data,
                                                header->errstr.len, NULL);
    }

    if (need_quotes) {
        *last++ = '"';
    }

    last = ngx_sprintf(last, "%c%uL%c%uL%V", sep, header->insert_id, sep,
                       header->affected_rows, &conf->row_term);

    if ((size_t) (last - pos) != size) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "rds_csv: output header buffer error: %uz != %uz",
                      (size_t) (last - pos), size);

        return NGX_ERROR;
    }

    if (r == r->main) {
        last_buf = 1;
    }

    ctx->seen_stream_end = 1;

    return ngx_http_rds_csv_submit_mem(r, ctx, size, last_buf);
}
ngx_int_t
ngx_http_rds_json_output_header(ngx_http_request_t *r,
    ngx_http_rds_json_ctx_t *ctx, ngx_http_rds_header_t *header)
{
    u_char                  *pos, *last;
    size_t                   size;
    uintptr_t                escape;
    unsigned                 last_buf = 0;
    ngx_uint_t               i;
    ngx_str_t               *values = NULL;
    uintptr_t               *escapes = NULL;

    ngx_http_rds_json_property_t        *prop = NULL;
    ngx_http_rds_json_loc_conf_t        *conf;

    conf = ngx_http_get_module_loc_conf(r, ngx_http_rds_json_filter_module);

    /* calculate the buffer size */

    size = sizeof("{") - 1
           + conf->errcode_key.len
           + sizeof(":") - 1
           + ngx_get_num_size(header->std_errcode)
           + sizeof("}") - 1;

    if (conf->success.len) {
        size += conf->success.len + sizeof(":,") - 1;
        if (header->std_errcode == 0) {
            size += sizeof("true") - 1;

        } else {
            size += sizeof("false") - 1;
        }
    }

    if (conf->user_props) {
        values = ngx_pnalloc(r->pool,
                             conf->user_props->nelts * (sizeof(ngx_str_t)
                             + sizeof(uintptr_t)));

        if (values == NULL) {
            return NGX_ERROR;
        }

        escapes = (uintptr_t *) ((u_char *) values
                  + conf->user_props->nelts * sizeof(ngx_str_t));

        prop = conf->user_props->elts;
        for (i = 0; i < conf->user_props->nelts; i++) {
            if (ngx_http_complex_value(r, &prop[i].value, &values[i])
                != NGX_OK)
            {
                return NGX_ERROR;
            }

            escapes[i] = ngx_http_rds_json_escape_json_str(NULL,
                                                           values[i].data,
                                                           values[i].len);

            size += sizeof(":\"\",") - 1 + prop[i].key.len + values[i].len
                    + escapes[i];
        }
    }


    if (header->errstr.len) {
        escape = ngx_http_rds_json_escape_json_str(NULL, header->errstr.data,
                                                   header->errstr.len);

        size += sizeof(",") - 1
                + conf->errstr_key.len
                + sizeof(":") - 1
                + sizeof("\"") - 1
                + header->errstr.len
                + escape
                + sizeof("\"") - 1;

    } else {
        escape = (uintptr_t) 0;
    }

    if (header->insert_id) {
        size += sizeof(",\"insert_id\":") - 1
                + ngx_get_num_size(header->insert_id);
    }

    if (header->affected_rows) {
        size += sizeof(",\"affected_rows\":") - 1
                + ngx_get_num_size(header->affected_rows);
    }

    /* create the buffer */

    pos = ngx_http_rds_json_request_mem(r, ctx, size);
    if (pos == NULL) {
        return NGX_ERROR;
    }

    last = pos;

    /* fill up the buffer */

    *last++ = '{';

    if (conf->success.len) {
        last = ngx_copy(last, conf->success.data, conf->success.len);

        if (header->std_errcode == 0) {
            last = ngx_copy_literal(last, ":true,");

        } else {
            last = ngx_copy_literal(last, ":false,");
        }
    }

    if (conf->user_props) {
        for (i = 0; i < conf->user_props->nelts; i++) {
            last = ngx_copy(last, prop[i].key.data, prop[i].key.len);
            *last++ = ':';
            *last++ = '"';

            if (escapes[i] == 0) {
                last = ngx_copy(last, values[i].data, values[i].len);

            } else {
                last = (u_char *)
                        ngx_http_rds_json_escape_json_str(last,
                                                          values[i].data,
                                                          values[i].len);
            }

            *last++ = '"';
            *last++ = ',';
        }
    }

    last = ngx_copy(last, conf->errcode_key.data, conf->errcode_key.len);
    *last++ = ':';

    last = ngx_snprintf(last, NGX_UINT16_LEN, "%uD",
                        (uint32_t) header->std_errcode);

    if (header->errstr.len) {
        *last++ = ',';
        last = ngx_copy(last, conf->errstr_key.data, conf->errstr_key.len);
        *last++ = ':';
        *last++ = '"';

        if (escape == 0) {
            last = ngx_copy(last, header->errstr.data, header->errstr.len);

        } else {
            last = (u_char *)
                    ngx_http_rds_json_escape_json_str(last,
                                                      header->errstr.data,
                                                      header->errstr.len);
        }

        *last++ = '"';
    }

    if (header->insert_id) {
        last = ngx_copy_literal(last, ",\"insert_id\":");
        last = ngx_snprintf(last, NGX_UINT64_LEN, "%uL", header->insert_id);
    }

    if (header->affected_rows) {
        last = ngx_copy_literal(last, ",\"affected_rows\":");
        last = ngx_snprintf(last, NGX_UINT64_LEN, "%uL",
                            header->affected_rows);
    }

    *last++ = '}';

    if ((size_t) (last - pos) != size) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                      "rds_json: output header buffer error: %O != %uz",
                      (off_t) (last - pos), size);

        return NGX_ERROR;
    }

    if (r == r->main) {
        last_buf = 1;
    }

    ctx->seen_stream_end = 1;

    return ngx_http_rds_json_submit_mem(r, ctx, size, (unsigned) last_buf);
}
static ngx_int_t
ngx_http_beanstalkd_build_put_query(ngx_http_request_t *r,
        ngx_array_t *query_args, ngx_buf_t **b)
{
    ngx_uint_t                       i;
    ngx_str_t                       *arg;
    ngx_array_t                     *args;
    ngx_http_complex_value_t       **complex_arg;
    size_t                           len = 0;
    u_char                          *p;

    dd("ngx_http_beanstalkd_build_put_query");

    dd("query_args->nelts:%d", (int) query_args->nelts);

    args = ngx_array_create(r->pool, query_args->nelts, sizeof(ngx_str_t));

    if (args == NULL) {
        return NGX_ERROR;
    }

    complex_arg = query_args->elts;

    /* beanstalkd_query put <pri> <delay> <ttr> $job */
    if (query_args->nelts != 5) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
            "beanstalkd: number of beanstalkd_query arguments does not equal 5, actual number:%uz", query_args->nelts);

        return NGX_ERROR;
    }

    /* calculate the length of bufer needed to store the request commands */
    for (i = 0; i < query_args->nelts; i++) {
        arg = ngx_array_push(args);
        if (arg == NULL) {
            return NGX_ERROR;
        }

        if (ngx_http_complex_value(r, complex_arg[i], arg) != NGX_OK) {
            return NGX_ERROR;
        }
    }

    arg = args->elts;

    len += arg[0].len
         + arg[1].len
         + arg[2].len
         + arg[3].len
         + ngx_get_num_size(arg[4].len)
         + arg[4].len
         + (sizeof(" ") - 1) * 4
         + (sizeof("\r\n") - 1) * 2;

    dd("len = %d", (int)len);

    *b = ngx_create_temp_buf(r->pool, len);
    if (*b == NULL) {
        return NGX_ERROR;
    }

    p = (*b)->pos;

    /* fill the buffer with each command */
    for (i = 0; i < 4; i++) {
        p = ngx_copy(p, arg[i].data, arg[i].len);
        *p++ = ' ';
    }

    p = ngx_sprintf(p, "%uz", arg[4].len);
    *p++ = '\r'; *p++ = '\n';

    p = ngx_copy(p, arg[4].data, arg[4].len);
    *p++ = '\r'; *p++ = '\n';

    dd("query:%.*s", (int) (p - (*b)->pos), (*b)->pos);

    if (p - (*b)->pos != (ssize_t) len) {
        ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
                "beanstalkd: beanstalkd_query buffer error %uz != %uz",
                (size_t) (p - (*b)->pos), len);

        return NGX_ERROR;
    }

    (*b)->last = p;

    return NGX_OK;
}