ngx_int_t ngx_http_echo_send_chain_link(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_chain_t *in) { ngx_int_t rc; rc = ngx_http_echo_send_header_if_needed(r, ctx); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } if (in == NULL) { #if defined(nginx_version) && nginx_version <= 8004 /* earlier versions of nginx does not allow subrequests to send last_buf themselves */ if (r != r->main) { return NGX_OK; } #endif rc = ngx_http_send_special(r, NGX_HTTP_LAST); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_OK; } /* FIXME we should udpate chains to recycle chain links and bufs */ return ngx_http_output_filter(r, in); }
ngx_int_t ngx_http_echo_exec_echo_location_async(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_int_t rc; ngx_http_request_t *sr; /* subrequest object */ ngx_str_t *computed_arg_elts; ngx_str_t location; ngx_str_t *url_args; ngx_str_t args; ngx_uint_t flags = 0; dd_enter(); computed_arg_elts = computed_args->elts; location = computed_arg_elts[0]; if (location.len == 0) { return NGX_ERROR; } if (computed_args->nelts > 1) { url_args = &computed_arg_elts[1]; } else { url_args = NULL; } args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, &location, &args, &flags) != NGX_OK) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "echo_location_async sees unsafe uri: \"%V\"", &location); return NGX_ERROR; } if (args.len > 0 && url_args == NULL) { url_args = &args; } rc = ngx_http_echo_send_header_if_needed(r, ctx); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } rc = ngx_http_subrequest(r, &location, url_args, &sr, NULL, 0); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_echo_adjust_subrequest(sr); if (rc != NGX_OK) { return NGX_ERROR; } return NGX_OK; }
static ngx_int_t ngx_http_rj_cdn_com_handler(ngx_http_request_t *r) { ngx_int_t rc; ngx_str_t uri; ngx_http_request_t *sr; /*subrequest object*/ uri.data = ngx_pcalloc(r->pool, r->args.len); uri.len = r->args.len; memcpy(uri.data, r->args.data, r->args.len); rc = ngx_http_echo_send_header_if_needed(r); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } rc = ngx_http_subrequest(r, &uri, NULL, &sr, NULL, 0); if (rc != NGX_OK) return NGX_ERROR; rc = ngx_http_rj_cdn_com_adjust_subrequest(sr); if (rc != NGX_OK) return NGX_ERROR; rc = ngx_http_send_special(r, NGX_HTTP_LAST); if (rc == NGX_ERROR || rc >= NGX_HTTP_SPECIAL_RESPONSE){ return rc; } return rc; }
ngx_int_t ngx_http_echo_exec_echo_duplicate(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_str_t *computed_arg; ngx_str_t *computed_arg_elts; ssize_t i, count; ngx_str_t *str; u_char *p; ngx_int_t rc; ngx_buf_t *buf; ngx_chain_t *cl; dd_enter(); computed_arg_elts = computed_args->elts; computed_arg = &computed_arg_elts[0]; count = ngx_http_echo_atosz(computed_arg->data, computed_arg->len); if (count == NGX_ERROR) { ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, "invalid size specified: \"%V\"", computed_arg); return NGX_HTTP_INTERNAL_SERVER_ERROR; } str = &computed_arg_elts[1]; if (count == 0 || str->len == 0) { rc = ngx_http_echo_send_header_if_needed(r, ctx); if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_OK; } buf = ngx_create_temp_buf(r->pool, count * str->len); if (buf == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } p = buf->pos; for (i = 0; i < count; i++) { p = ngx_copy(p, str->data, str->len); } buf->last = p; cl = ngx_alloc_chain_link(r->pool); if (cl == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } cl->next = NULL; cl->buf = buf; return ngx_http_echo_send_chain_link(r, ctx, cl); }
ngx_int_t ngx_http_echo_exec_echo_location_async(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_int_t rc; ngx_http_request_t *sr; /* subrequest object */ ngx_str_t *computed_arg_elts; ngx_str_t location; ngx_str_t *url_args; ngx_str_t args; ngx_uint_t flags; computed_arg_elts = computed_args->elts; location = computed_arg_elts[0]; if (location.len == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (computed_args->nelts > 1) { url_args = &computed_arg_elts[1]; } else { url_args = NULL; } dd("location: %s", location.data); dd("location args: %s", (char*) (url_args ? url_args->data : (u_char*)"NULL")); args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, &location, &args, &flags) != NGX_OK) { ctx->headers_sent = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (args.len > 0 && url_args == NULL) { url_args = &args; } rc = ngx_http_echo_send_header_if_needed(r, ctx); if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } rc = ngx_http_subrequest(r, &location, url_args, &sr, NULL, 0); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_echo_adjust_subrequest(sr); if (rc != NGX_OK) { return rc; } return NGX_OK; }
ngx_int_t ngx_http_echo_exec_echo_subrequest(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_int_t rc; ngx_http_request_t *sr; /* subrequest object */ ngx_http_post_subrequest_t *psr; ngx_http_echo_subrequest_t *parsed_sr; ngx_str_t args; ngx_uint_t flags; rc = ngx_http_echo_parse_subrequest_spec(r, computed_args, &parsed_sr); if (rc != NGX_OK) { return rc; } args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, parsed_sr->location, &args, &flags) != NGX_OK) { ctx->headers_sent = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (args.len > 0 && parsed_sr->query_string == NULL) { parsed_sr->query_string = &args; } rc = ngx_http_echo_send_header_if_needed(r, ctx); if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } psr->handler = ngx_http_echo_post_subrequest; psr->data = ctx; rc = ngx_http_subrequest(r, parsed_sr->location, parsed_sr->query_string, &sr, psr, 0); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_echo_adjust_subrequest(sr, parsed_sr); if (rc != NGX_OK) { return rc; } return NGX_OK; }
ngx_int_t ngx_http_echo_exec_echo_subrequest_async(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_int_t rc; ngx_http_echo_subrequest_t *parsed_sr; ngx_http_request_t *sr; /* subrequest object */ ngx_str_t args; ngx_uint_t flags; rc = ngx_http_echo_parse_subrequest_spec(r, computed_args, &parsed_sr); if (rc != NGX_OK) { return rc; } dd("location: %s", parsed_sr->location->data); dd("location args: %s", (char*) (parsed_sr->query_string ? parsed_sr->query_string->data : (u_char*)"NULL")); args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, parsed_sr->location, &args, &flags) != NGX_OK) { ctx->headers_sent = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (args.len > 0 && parsed_sr->query_string == NULL) { parsed_sr->query_string = &args; } rc = ngx_http_echo_send_header_if_needed(r, ctx); if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } rc = ngx_http_subrequest(r, parsed_sr->location, parsed_sr->query_string, &sr, NULL, 0); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_echo_adjust_subrequest(sr, parsed_sr); if (rc != NGX_OK) { return rc; } return NGX_OK; }
ngx_int_t ngx_http_echo_exec_echo_location(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_int_t rc; ngx_http_request_t *sr; /* subrequest object */ ngx_str_t *computed_arg_elts; ngx_str_t location; ngx_str_t *url_args; ngx_http_post_subrequest_t *psr; ngx_str_t args; ngx_uint_t flags; computed_arg_elts = computed_args->elts; location = computed_arg_elts[0]; if (location.len == 0) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (computed_args->nelts > 1) { url_args = &computed_arg_elts[1]; } else { url_args = NULL; } args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, &location, &args, &flags) != NGX_OK) { ctx->headers_sent = 1; return NGX_HTTP_INTERNAL_SERVER_ERROR; } if (args.len > 0 && url_args == NULL) { url_args = &args; } rc = ngx_http_echo_send_header_if_needed(r, ctx); if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_HTTP_INTERNAL_SERVER_ERROR; } psr->handler = ngx_http_echo_post_subrequest; psr->data = ctx; rc = ngx_http_subrequest(r, &location, url_args, &sr, psr, 0); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_echo_adjust_subrequest(sr); if (rc != NGX_OK) { return rc; } return NGX_OK; }
ngx_int_t ngx_http_echo_exec_echo_location(ngx_http_request_t *r, ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args) { ngx_int_t rc; ngx_http_request_t *sr; /* subrequest object */ ngx_str_t *computed_arg_elts; ngx_str_t location; ngx_str_t *url_args; ngx_http_post_subrequest_t *psr; ngx_str_t args; ngx_uint_t flags = 0; ngx_http_echo_ctx_t *sr_ctx; computed_arg_elts = computed_args->elts; location = computed_arg_elts[0]; if (location.len == 0) { return NGX_ERROR; } if (computed_args->nelts > 1) { url_args = &computed_arg_elts[1]; } else { url_args = NULL; } args.data = NULL; args.len = 0; if (ngx_http_parse_unsafe_uri(r, &location, &args, &flags) != NGX_OK) { ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "echo_location sees unsafe uri: \"%V\"", &location); return NGX_ERROR; } if (args.len > 0 && url_args == NULL) { url_args = &args; } rc = ngx_http_echo_send_header_if_needed(r, ctx); if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { return rc; } sr_ctx = ngx_http_echo_create_ctx(r); psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t)); if (psr == NULL) { return NGX_ERROR; } psr->handler = ngx_http_echo_post_subrequest; psr->data = sr_ctx; rc = ngx_http_subrequest(r, &location, url_args, &sr, psr, 0); if (rc != NGX_OK) { return NGX_ERROR; } rc = ngx_http_echo_adjust_subrequest(sr); if (rc != NGX_OK) { return NGX_ERROR; } return NGX_AGAIN; }
ngx_int_t ngx_http_echo_send_chain_link(ngx_http_request_t* r, ngx_http_echo_ctx_t *ctx, ngx_chain_t *cl) { ngx_int_t rc; size_t size; ngx_chain_t *p; rc = ngx_http_echo_send_header_if_needed(r, ctx); if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } if (r->http_version < NGX_HTTP_VERSION_11 && !ctx->headers_sent) { ctx->headers_sent = 1; size = 0; for (p = cl; p; p = p->next) { if (p->buf->memory) { size += p->buf->last - p->buf->pos; } } r->headers_out.content_length_n = (off_t) size; if (r->headers_out.content_length) { r->headers_out.content_length->hash = 0; } r->headers_out.content_length = NULL; rc = ngx_http_send_header(r); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } } if (cl == NULL) { #if defined(nginx_version) && nginx_version <= 8004 /* earlier versions of nginx does not allow subrequests to send last_buf themselves */ if (r != r->main) { return NGX_OK; } #endif rc = ngx_http_send_special(r, NGX_HTTP_LAST); if (rc >= NGX_HTTP_SPECIAL_RESPONSE) { return rc; } return NGX_OK; } return ngx_http_output_filter(r, cl); }