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; }