LCOV - code coverage report
Current view: top level - home/agentz/git/echo-nginx-module/src - ngx_http_echo_subrequest.c (source / functions) Hit Total Coverage
Test: foo.info Lines: 0 263 0.0 %
Date: 2011-05-12 Functions: 0 7 0.0 %
Branches: 0 152 0.0 %

           Branch data     Line data    Source code
       1                 :            : #define DDEBUG 0
       2                 :            : #include "ddebug.h"
       3                 :            : 
       4                 :            : #include "ngx_http_echo_util.h"
       5                 :            : #include "ngx_http_echo_subrequest.h"
       6                 :            : #include "ngx_http_echo_handler.h"
       7                 :            : 
       8                 :            : #define ngx_http_echo_method_name(m) { sizeof(m) - 1, (u_char *) m " " }
       9                 :            : 
      10                 :            : ngx_str_t  ngx_http_echo_content_length_header_key =
      11                 :            :         ngx_string("Content-Length");
      12                 :            : 
      13                 :            : ngx_str_t  ngx_http_echo_get_method = ngx_http_echo_method_name("GET");
      14                 :            : ngx_str_t  ngx_http_echo_put_method = ngx_http_echo_method_name("PUT");
      15                 :            : ngx_str_t  ngx_http_echo_post_method = ngx_http_echo_method_name("POST");
      16                 :            : ngx_str_t  ngx_http_echo_head_method = ngx_http_echo_method_name("HEAD");
      17                 :            : ngx_str_t  ngx_http_echo_copy_method = ngx_http_echo_method_name("COPY");
      18                 :            : ngx_str_t  ngx_http_echo_move_method = ngx_http_echo_method_name("MOVE");
      19                 :            : ngx_str_t  ngx_http_echo_lock_method = ngx_http_echo_method_name("LOCK");
      20                 :            : ngx_str_t  ngx_http_echo_mkcol_method = ngx_http_echo_method_name("MKCOL");
      21                 :            : ngx_str_t  ngx_http_echo_trace_method = ngx_http_echo_method_name("TRACE");
      22                 :            : ngx_str_t  ngx_http_echo_delete_method = ngx_http_echo_method_name("DELETE");
      23                 :            : ngx_str_t  ngx_http_echo_unlock_method = ngx_http_echo_method_name("UNLOCK");
      24                 :            : ngx_str_t  ngx_http_echo_options_method = ngx_http_echo_method_name("OPTIONS");
      25                 :            : ngx_str_t  ngx_http_echo_propfind_method =
      26                 :            :         ngx_http_echo_method_name("PROPFIND");
      27                 :            : ngx_str_t  ngx_http_echo_proppatch_method =
      28                 :            :         ngx_http_echo_method_name("PROPPATCH");
      29                 :            : 
      30                 :            : 
      31                 :            : typedef struct ngx_http_echo_subrequest_s {
      32                 :            :     ngx_uint_t                  method;
      33                 :            :     ngx_str_t                   *method_name;
      34                 :            :     ngx_str_t                   *location;
      35                 :            :     ngx_str_t                   *query_string;
      36                 :            :     ssize_t                     content_length_n;
      37                 :            :     ngx_http_request_body_t     *request_body;
      38                 :            : } ngx_http_echo_subrequest_t;
      39                 :            : 
      40                 :            : 
      41                 :            : static ngx_int_t ngx_http_echo_parse_method_name(ngx_str_t **method_name_ptr);
      42                 :            : 
      43                 :            : static ngx_int_t ngx_http_echo_adjust_subrequest(ngx_http_request_t *sr,
      44                 :            :         ngx_http_echo_subrequest_t *parsed_sr);
      45                 :            : 
      46                 :            : static ngx_int_t ngx_http_echo_parse_subrequest_spec(ngx_http_request_t *r,
      47                 :            :         ngx_array_t *computed_args, ngx_http_echo_subrequest_t **parsed_sr_ptr);
      48                 :            : 
      49                 :            : 
      50                 :            : ngx_int_t
      51                 :          0 : ngx_http_echo_exec_echo_subrequest_async(ngx_http_request_t *r,
      52                 :            :         ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
      53                 :            : {
      54                 :            :     ngx_int_t                       rc;
      55                 :            :     ngx_http_echo_subrequest_t      *parsed_sr;
      56                 :            :     ngx_http_request_t              *sr; /* subrequest object */
      57                 :            :     ngx_str_t                       args;
      58                 :          0 :     ngx_uint_t                      flags = 0;
      59                 :            : 
      60                 :            : 
      61                 :            :     dd_enter();
      62                 :            : 
      63                 :          0 :     rc = ngx_http_echo_parse_subrequest_spec(r, computed_args, &parsed_sr);
      64         [ #  # ]:          0 :     if (rc != NGX_OK) {
      65                 :          0 :         return rc;
      66                 :            :     }
      67                 :            : 
      68                 :            :     dd("location: %.*s",
      69                 :            :             (int) parsed_sr->location->len,
      70                 :            :             parsed_sr->location->data);
      71                 :            : 
      72                 :          0 :     args.data = NULL;
      73                 :          0 :     args.len = 0;
      74                 :            : 
      75         [ #  # ]:          0 :     if (ngx_http_parse_unsafe_uri(r, parsed_sr->location, &args, &flags)
      76                 :            :             != NGX_OK)
      77                 :            :     {
      78                 :          0 :         ctx->headers_sent = 1;
      79                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
      80                 :            :     }
      81                 :            : 
      82 [ #  # ][ #  # ]:          0 :     if (args.len > 0 && parsed_sr->query_string == NULL) {
      83                 :          0 :         parsed_sr->query_string = &args;
      84                 :            :     }
      85                 :            : 
      86                 :          0 :     rc = ngx_http_echo_send_header_if_needed(r, ctx);
      87 [ #  # ][ #  # ]:          0 :     if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
      88                 :          0 :         return rc;
      89                 :            :     }
      90                 :            : 
      91                 :          0 :     rc = ngx_http_subrequest(r, parsed_sr->location, parsed_sr->query_string,
      92                 :            :             &sr, NULL, 0);
      93                 :            : 
      94         [ #  # ]:          0 :     if (rc != NGX_OK) {
      95                 :          0 :         return NGX_ERROR;
      96                 :            :     }
      97                 :            : 
      98                 :          0 :     rc = ngx_http_echo_adjust_subrequest(sr, parsed_sr);
      99                 :            : 
     100         [ #  # ]:          0 :     if (rc != NGX_OK) {
     101                 :          0 :         return rc;
     102                 :            :     }
     103                 :            : 
     104                 :          0 :     return NGX_OK;
     105                 :            : }
     106                 :            : 
     107                 :            : 
     108                 :            : ngx_int_t
     109                 :          0 : ngx_http_echo_exec_echo_subrequest(ngx_http_request_t *r,
     110                 :            :         ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
     111                 :            : {
     112                 :            :     ngx_int_t                            rc;
     113                 :            :     ngx_http_request_t                  *sr; /* subrequest object */
     114                 :            :     ngx_http_post_subrequest_t          *psr;
     115                 :            :     ngx_http_echo_subrequest_t          *parsed_sr;
     116                 :            :     ngx_str_t                            args;
     117                 :          0 :     ngx_uint_t                           flags = 0;
     118                 :            :     ngx_http_echo_ctx_t                 *sr_ctx;
     119                 :            : 
     120                 :            :     dd_enter();
     121                 :            : 
     122                 :          0 :     rc = ngx_http_echo_parse_subrequest_spec(r, computed_args, &parsed_sr);
     123                 :            : 
     124         [ #  # ]:          0 :     if (rc != NGX_OK) {
     125                 :          0 :         return rc;
     126                 :            :     }
     127                 :            : 
     128                 :          0 :     args.data = NULL;
     129                 :          0 :     args.len = 0;
     130                 :            : 
     131         [ #  # ]:          0 :     if (ngx_http_parse_unsafe_uri(r, parsed_sr->location, &args, &flags)
     132                 :            :             != NGX_OK)
     133                 :            :     {
     134                 :          0 :         ctx->headers_sent = 1;
     135                 :            : 
     136                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     137                 :            :     }
     138                 :            : 
     139 [ #  # ][ #  # ]:          0 :     if (args.len > 0 && parsed_sr->query_string == NULL) {
     140                 :          0 :         parsed_sr->query_string = &args;
     141                 :            :     }
     142                 :            : 
     143                 :          0 :     rc = ngx_http_echo_send_header_if_needed(r, ctx);
     144                 :            : 
     145 [ #  # ][ #  # ]:          0 :     if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
     146                 :          0 :         return rc;
     147                 :            :     }
     148                 :            : 
     149                 :          0 :     sr_ctx = ngx_http_echo_create_ctx(r);
     150                 :            : 
     151                 :            :     /* set by ngx_http_echo_create_ctx
     152                 :            :      *  sr_ctx->run_post_subrequest = 0
     153                 :            :      */
     154                 :            : 
     155                 :          0 :     psr = ngx_palloc(r->pool, sizeof(ngx_http_post_subrequest_t));
     156                 :            : 
     157         [ #  # ]:          0 :     if (psr == NULL) {
     158                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     159                 :            :     }
     160                 :            : 
     161                 :          0 :     psr->handler = ngx_http_echo_post_subrequest;
     162                 :          0 :     psr->data = sr_ctx;
     163                 :            : 
     164                 :          0 :     rc = ngx_http_subrequest(r, parsed_sr->location, parsed_sr->query_string,
     165                 :            :             &sr, psr, 0);
     166                 :            : 
     167         [ #  # ]:          0 :     if (rc != NGX_OK) {
     168                 :          0 :         return NGX_ERROR;
     169                 :            :     }
     170                 :            : 
     171                 :          0 :     sr_ctx->sleep.data = sr;
     172                 :            : 
     173                 :          0 :     ngx_http_set_ctx(sr, sr_ctx, ngx_http_echo_module);
     174                 :            : 
     175                 :          0 :     rc = ngx_http_echo_adjust_subrequest(sr, parsed_sr);
     176                 :            : 
     177         [ #  # ]:          0 :     if (rc != NGX_OK) {
     178                 :          0 :         return NGX_ERROR;
     179                 :            :     }
     180                 :            : 
     181                 :          0 :     return NGX_AGAIN;
     182                 :            : }
     183                 :            : 
     184                 :            : 
     185                 :            : static ngx_int_t
     186                 :          0 : ngx_http_echo_parse_subrequest_spec(ngx_http_request_t *r,
     187                 :            :         ngx_array_t *computed_args, ngx_http_echo_subrequest_t **parsed_sr_ptr)
     188                 :            : {
     189                 :            :     ngx_str_t                   *computed_arg_elts, *arg;
     190                 :          0 :     ngx_str_t                  **to_write = NULL;
     191                 :            :     ngx_str_t                   *method_name;
     192                 :          0 :     ngx_str_t                   *body_str = NULL;
     193                 :          0 :     ngx_str_t                   *body_file = NULL;
     194                 :            :     ngx_uint_t                   i;
     195                 :            :     ngx_flag_t                   expecting_opt;
     196                 :          0 :     ngx_http_request_body_t     *rb = NULL;
     197                 :            :     ngx_buf_t                   *b;
     198                 :            :     ngx_http_echo_subrequest_t  *parsed_sr;
     199                 :            :     ngx_open_file_info_t         of;
     200                 :            :     ngx_http_core_loc_conf_t    *clcf;
     201                 :            :     size_t                       len;
     202                 :            : 
     203                 :          0 :     *parsed_sr_ptr = ngx_pcalloc(r->pool, sizeof(ngx_http_echo_subrequest_t));
     204         [ #  # ]:          0 :     if (*parsed_sr_ptr == NULL) {
     205                 :          0 :         return NGX_ERROR;
     206                 :            :     }
     207                 :            : 
     208                 :          0 :     parsed_sr = *parsed_sr_ptr;
     209                 :            : 
     210                 :          0 :     computed_arg_elts = computed_args->elts;
     211                 :            : 
     212                 :          0 :     method_name = &computed_arg_elts[0];
     213                 :            : 
     214                 :          0 :     parsed_sr->location     = &computed_arg_elts[1];
     215                 :            : 
     216         [ #  # ]:          0 :     if (parsed_sr->location->len == 0) {
     217                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     218                 :            :     }
     219                 :            : 
     220                 :          0 :     expecting_opt = 1;
     221                 :            : 
     222         [ #  # ]:          0 :     for (i = 2; i < computed_args->nelts; i++) {
     223                 :          0 :         arg = &computed_arg_elts[i];
     224                 :            : 
     225         [ #  # ]:          0 :         if (!expecting_opt) {
     226         [ #  # ]:          0 :             if (to_write == NULL) {
     227         [ #  # ]:          0 :                 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
     228                 :            :                         "echo_subrequest_async: to_write should NOT be NULL");
     229                 :          0 :                 return NGX_HTTP_INTERNAL_SERVER_ERROR;
     230                 :            :             }
     231                 :            : 
     232                 :          0 :             *to_write = arg;
     233                 :          0 :             to_write = NULL;
     234                 :            : 
     235                 :          0 :             expecting_opt = 1;
     236                 :            : 
     237                 :          0 :             continue;
     238                 :            :         }
     239                 :            : 
     240         [ #  # ]:          0 :         if (arg->len == 2) {
     241         [ #  # ]:          0 :             if (ngx_strncmp("-q", arg->data, arg->len) == 0) {
     242                 :          0 :                 to_write = &parsed_sr->query_string;
     243                 :          0 :                 expecting_opt = 0;
     244                 :          0 :                 continue;
     245                 :            :             }
     246                 :            : 
     247         [ #  # ]:          0 :             if (ngx_strncmp("-b", arg->data, arg->len) == 0) {
     248                 :          0 :                 to_write = &body_str;
     249                 :          0 :                 expecting_opt = 0;
     250                 :          0 :                 continue;
     251                 :            :             }
     252                 :            : 
     253         [ #  # ]:          0 :             if (ngx_strncmp("-f", arg->data, arg->len) == 0) {
     254                 :            :               dd("found option -f");
     255                 :          0 :               to_write = &body_file;
     256                 :          0 :               expecting_opt = 0;
     257                 :          0 :               continue;
     258                 :            :             }
     259                 :            :         }
     260                 :            : 
     261         [ #  # ]:          0 :         ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
     262                 :            :                 "Unknown option for echo_subrequest_async: %V", arg);
     263                 :            : 
     264                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     265                 :            :     }
     266                 :            : 
     267 [ #  # ][ #  # ]:          0 :     if (body_str != NULL && body_str->len) {
     268                 :          0 :         rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
     269                 :            : 
     270         [ #  # ]:          0 :         if (rb == NULL) {
     271                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     272                 :            :         }
     273                 :            : 
     274                 :          0 :         parsed_sr->content_length_n = body_str->len;
     275                 :            : 
     276                 :          0 :         b = ngx_calloc_buf(r->pool);
     277         [ #  # ]:          0 :         if (b == NULL) {
     278                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     279                 :            :         }
     280                 :            : 
     281                 :          0 :         b->temporary = 1;
     282                 :            :         /* b->memory = 1; */
     283                 :          0 :         b->start = b->pos = body_str->data;
     284                 :          0 :         b->end = b->last = body_str->data + body_str->len;
     285                 :            : 
     286                 :          0 :         rb->bufs = ngx_alloc_chain_link(r->pool);
     287         [ #  # ]:          0 :         if (rb->bufs == NULL) {
     288                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     289                 :            :         }
     290                 :            : 
     291                 :          0 :         rb->bufs->buf = b;
     292                 :          0 :         rb->bufs->next = NULL;
     293                 :            : 
     294                 :          0 :         rb->buf = b;
     295                 :            : 
     296 [ #  # ][ #  # ]:          0 :     } else if (body_file != NULL && body_file->len) {
     297                 :            : 
     298                 :            :         dd("body_file defined %.*s", (int) body_file->len, body_file->data);
     299                 :            : 
     300                 :          0 :         body_file->data = ngx_http_echo_rebase_path(r->pool, body_file->data,
     301                 :          0 :                 body_file->len, &len);
     302                 :            : 
     303         [ #  # ]:          0 :         if (body_file->data == NULL) {
     304                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     305                 :            :         }
     306                 :            : 
     307                 :          0 :         body_file->len = len;
     308                 :            : 
     309                 :            :         dd("after rebase, the path becomes %.*s", (int) body_file->len,
     310                 :            :                 body_file->data);
     311                 :            : 
     312                 :          0 :         rb = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t));
     313         [ #  # ]:          0 :         if (rb == NULL) {
     314                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     315                 :            :         }
     316                 :            : 
     317                 :          0 :         clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
     318                 :          0 :         ngx_memzero(&of, sizeof(ngx_open_file_info_t));
     319                 :            : 
     320                 :            : #if defined(nginx_version) && nginx_version >= 8018
     321                 :          0 :         of.read_ahead = clcf->read_ahead;
     322                 :            : #endif
     323                 :            : 
     324                 :          0 :         of.directio = clcf->directio;
     325                 :          0 :         of.valid = clcf->open_file_cache_valid;
     326                 :          0 :         of.min_uses = clcf->open_file_cache_min_uses;
     327                 :          0 :         of.errors = clcf->open_file_cache_errors;
     328                 :          0 :         of.events = clcf->open_file_cache_events;
     329                 :            : 
     330         [ #  # ]:          0 :         if (ngx_open_cached_file(clcf->open_file_cache, body_file, &of, r->pool)
     331                 :            :             != NGX_OK)
     332                 :            :         {
     333         [ #  # ]:          0 :             ngx_log_error(NGX_LOG_ERR, r->connection->log, of.err,
     334                 :            :                     "%s \"%V\" failed",
     335                 :            :                     of.failed, body_file);
     336                 :            : 
     337                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     338                 :            :         }
     339                 :            : 
     340                 :            :         dd("file content size: %d", (int) of.size);
     341                 :            : 
     342                 :          0 :         parsed_sr->content_length_n = of.size;
     343                 :            : 
     344                 :          0 :         b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
     345         [ #  # ]:          0 :         if (b == NULL) {
     346                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     347                 :            :         }
     348                 :            : 
     349                 :          0 :         b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
     350         [ #  # ]:          0 :         if (b->file == NULL) {
     351                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     352                 :            :         }
     353                 :            : 
     354                 :          0 :         b->file_pos = 0;
     355                 :          0 :         b->file_last = of.size;
     356                 :            : 
     357                 :          0 :         b->in_file = b->file_last ? 1: 0;
     358                 :            : 
     359                 :            : #if 0
     360                 :            :         b->last_buf = (r == r->main) ? 1: 0;
     361                 :            :         b->last_in_chain = 1;
     362                 :            : #endif
     363                 :            : 
     364                 :          0 :         b->file->fd = of.fd;
     365                 :          0 :         b->file->name = *body_file;
     366                 :          0 :         b->file->log = r->connection->log;
     367                 :          0 :         b->file->directio = of.is_directio;
     368                 :            : 
     369                 :          0 :         rb->bufs = ngx_alloc_chain_link(r->pool);
     370         [ #  # ]:          0 :         if (rb->bufs == NULL) {
     371                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     372                 :            :         }
     373                 :            : 
     374                 :          0 :         rb->bufs->buf = b;
     375                 :          0 :         rb->bufs->next = NULL;
     376                 :          0 :         rb->buf = b;
     377                 :            :     }
     378                 :            : 
     379                 :          0 :     parsed_sr->request_body = rb;
     380                 :            : 
     381                 :          0 :     parsed_sr->method = ngx_http_echo_parse_method_name(&method_name);
     382                 :          0 :     parsed_sr->method_name  = method_name;
     383                 :            : 
     384                 :          0 :     return NGX_OK;
     385                 :            : }
     386                 :            : 
     387                 :            : 
     388                 :            : static ngx_int_t
     389                 :          0 : ngx_http_echo_adjust_subrequest(ngx_http_request_t *sr,
     390                 :            :         ngx_http_echo_subrequest_t *parsed_sr)
     391                 :            : {
     392                 :            :     ngx_table_elt_t            *h;
     393                 :            :     ngx_http_core_main_conf_t  *cmcf;
     394                 :            :     ngx_http_request_t         *r;
     395                 :            : 
     396                 :          0 :     sr->method = parsed_sr->method;
     397                 :          0 :     sr->method_name = *(parsed_sr->method_name);
     398                 :            : 
     399                 :          0 :     r = sr->parent;
     400                 :            : 
     401                 :          0 :     sr->header_in = r->header_in;
     402                 :            : 
     403                 :            :     /* XXX work-around a bug in ngx_http_subrequest */
     404         [ #  # ]:          0 :     if (r->headers_in.headers.last == &r->headers_in.headers.part) {
     405                 :          0 :         sr->headers_in.headers.last = &sr->headers_in.headers.part;
     406                 :            :     }
     407                 :            : 
     408                 :            :     /* we do not inherit the parent request's variables */
     409                 :          0 :     cmcf = ngx_http_get_module_main_conf(sr, ngx_http_core_module);
     410                 :          0 :     sr->variables = ngx_pcalloc(sr->pool, cmcf->variables.nelts
     411                 :            :                                         * sizeof(ngx_http_variable_value_t));
     412                 :            : 
     413         [ #  # ]:          0 :     if (sr->variables == NULL) {
     414                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     415                 :            :     }
     416                 :            : 
     417         [ #  # ]:          0 :     if (parsed_sr->content_length_n > 0) {
     418                 :          0 :         sr->headers_in.content_length_n = parsed_sr->content_length_n;
     419                 :          0 :         sr->request_body = parsed_sr->request_body;
     420                 :            : 
     421                 :          0 :         sr->headers_in.content_length = ngx_pcalloc(sr->pool,
     422                 :            :                 sizeof(ngx_table_elt_t));
     423                 :          0 :         sr->headers_in.content_length->value.data =
     424                 :          0 :             ngx_palloc(sr->pool, NGX_OFF_T_LEN);
     425         [ #  # ]:          0 :         if (sr->headers_in.content_length->value.data == NULL) {
     426                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     427                 :            :         }
     428                 :          0 :         sr->headers_in.content_length->value.len = ngx_sprintf(
     429                 :          0 :                 sr->headers_in.content_length->value.data, "%O",
     430                 :            :                 sr->headers_in.content_length_n) -
     431                 :          0 :                 sr->headers_in.content_length->value.data;
     432                 :            : 
     433         [ #  # ]:          0 :         if (ngx_list_init(&sr->headers_in.headers, sr->pool, 20,
     434                 :            :                     sizeof(ngx_table_elt_t)) != NGX_OK) {
     435                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     436                 :            :         }
     437                 :            : 
     438                 :          0 :         h = ngx_list_push(&sr->headers_in.headers);
     439         [ #  # ]:          0 :         if (h == NULL) {
     440                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     441                 :            :         }
     442                 :            : 
     443                 :          0 :         h->hash = sr->header_hash;
     444                 :            : 
     445                 :          0 :         h->key = ngx_http_echo_content_length_header_key;
     446                 :          0 :         h->value = sr->headers_in.content_length->value;
     447                 :            : 
     448                 :          0 :         h->lowcase_key = ngx_pnalloc(sr->pool, h->key.len);
     449         [ #  # ]:          0 :         if (h->lowcase_key == NULL) {
     450                 :          0 :             return NGX_HTTP_INTERNAL_SERVER_ERROR;
     451                 :            :         }
     452                 :            : 
     453                 :          0 :         ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
     454                 :            : 
     455                 :            :         dd("sr content length: %.*s",
     456                 :            :                 (int) sr->headers_in.content_length->value.len,
     457                 :            :                 sr->headers_in.content_length->value.data);
     458                 :            :     }
     459                 :            : 
     460                 :            :     dd("subrequest body: %p", sr->request_body);
     461                 :            : 
     462                 :          0 :     return NGX_OK;
     463                 :            : }
     464                 :            : 
     465                 :            : 
     466                 :            : static ngx_int_t
     467                 :          0 : ngx_http_echo_parse_method_name(ngx_str_t **method_name_ptr)
     468                 :            : {
     469                 :          0 :     const ngx_str_t* method_name = *method_name_ptr;
     470                 :            : 
     471   [ #  #  #  #  :          0 :     switch (method_name->len) {
             #  #  #  # ]
     472                 :            :     case 3:
     473         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "GET") == 0) {
     474                 :          0 :             *method_name_ptr = &ngx_http_echo_get_method;
     475                 :          0 :             return NGX_HTTP_GET;
     476                 :            :             break;
     477                 :            :         }
     478                 :            : 
     479         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "PUT") == 0) {
     480                 :          0 :             *method_name_ptr = &ngx_http_echo_put_method;
     481                 :          0 :             return NGX_HTTP_PUT;
     482                 :            :             break;
     483                 :            :         }
     484                 :            : 
     485                 :          0 :         return NGX_HTTP_UNKNOWN;
     486                 :            :         break;
     487                 :            : 
     488                 :            :     case 4:
     489         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "POST") == 0) {
     490                 :          0 :             *method_name_ptr = &ngx_http_echo_post_method;
     491                 :          0 :             return NGX_HTTP_POST;
     492                 :            :             break;
     493                 :            :         }
     494         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "HEAD") == 0) {
     495                 :          0 :             *method_name_ptr = &ngx_http_echo_head_method;
     496                 :          0 :             return NGX_HTTP_HEAD;
     497                 :            :             break;
     498                 :            :         }
     499         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "COPY") == 0) {
     500                 :          0 :             *method_name_ptr = &ngx_http_echo_copy_method;
     501                 :          0 :             return NGX_HTTP_COPY;
     502                 :            :             break;
     503                 :            :         }
     504         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "MOVE") == 0) {
     505                 :          0 :             *method_name_ptr = &ngx_http_echo_move_method;
     506                 :          0 :             return NGX_HTTP_MOVE;
     507                 :            :             break;
     508                 :            :         }
     509         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "LOCK") == 0) {
     510                 :          0 :             *method_name_ptr = &ngx_http_echo_lock_method;
     511                 :          0 :             return NGX_HTTP_LOCK;
     512                 :            :             break;
     513                 :            :         }
     514                 :          0 :         return NGX_HTTP_UNKNOWN;
     515                 :            :         break;
     516                 :            : 
     517                 :            :     case 5:
     518         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "MKCOL") == 0) {
     519                 :          0 :             *method_name_ptr = &ngx_http_echo_mkcol_method;
     520                 :          0 :             return NGX_HTTP_MKCOL;
     521                 :            :             break;
     522                 :            :         }
     523         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "TRACE") == 0) {
     524                 :          0 :             *method_name_ptr = &ngx_http_echo_trace_method;
     525                 :          0 :             return NGX_HTTP_TRACE;
     526                 :            :             break;
     527                 :            :         }
     528                 :          0 :         return NGX_HTTP_UNKNOWN;
     529                 :            :         break;
     530                 :            : 
     531                 :            :     case 6:
     532         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "DELETE") == 0) {
     533                 :          0 :             *method_name_ptr = &ngx_http_echo_delete_method;
     534                 :          0 :             return NGX_HTTP_DELETE;
     535                 :            :             break;
     536                 :            :         }
     537                 :            : 
     538         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "UNLOCK") == 0) {
     539                 :          0 :             *method_name_ptr = &ngx_http_echo_unlock_method;
     540                 :          0 :             return NGX_HTTP_UNLOCK;
     541                 :            :             break;
     542                 :            :         }
     543                 :          0 :         return NGX_HTTP_UNKNOWN;
     544                 :            :         break;
     545                 :            : 
     546                 :            :     case 7:
     547         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "OPTIONS") == 0) {
     548                 :          0 :             *method_name_ptr = &ngx_http_echo_options_method;
     549                 :          0 :             return NGX_HTTP_OPTIONS;
     550                 :            :             break;
     551                 :            :         }
     552                 :          0 :         return NGX_HTTP_UNKNOWN;
     553                 :            :         break;
     554                 :            : 
     555                 :            :     case 8:
     556         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "PROPFIND") == 0) {
     557                 :          0 :             *method_name_ptr = &ngx_http_echo_propfind_method;
     558                 :          0 :             return NGX_HTTP_PROPFIND;
     559                 :            :             break;
     560                 :            :         }
     561                 :          0 :         return NGX_HTTP_UNKNOWN;
     562                 :            :         break;
     563                 :            : 
     564                 :            :     case 9:
     565         [ #  # ]:          0 :         if (ngx_http_echo_strcmp_const(method_name->data, "PROPPATCH") == 0) {
     566                 :          0 :             *method_name_ptr = &ngx_http_echo_proppatch_method;
     567                 :          0 :             return NGX_HTTP_PROPPATCH;
     568                 :            :             break;
     569                 :            :         }
     570                 :          0 :         return NGX_HTTP_UNKNOWN;
     571                 :            :         break;
     572                 :            : 
     573                 :            :     default:
     574                 :          0 :         return NGX_HTTP_UNKNOWN;
     575                 :            :         break;
     576                 :            :     }
     577                 :            : 
     578                 :            :     return NGX_HTTP_UNKNOWN;
     579                 :            : }
     580                 :            : 
     581                 :            : 
     582                 :            : /* XXX extermely evil and not working yet */
     583                 :            : ngx_int_t
     584                 :          0 : ngx_http_echo_exec_abort_parent(ngx_http_request_t *r,
     585                 :            :         ngx_http_echo_ctx_t *ctx)
     586                 :            : {
     587                 :            : #if 0
     588                 :            :     ngx_http_postponed_request_t    *pr, *ppr;
     589                 :            :     ngx_http_request_t              *saved_data = NULL;
     590                 :            :     ngx_chain_t                     *out = NULL;
     591                 :            :     /* ngx_int_t                       rc; */
     592                 :            : 
     593                 :            :     dd("aborting parent...");
     594                 :            : 
     595                 :            :     if (r == r->main || r->parent == NULL) {
     596                 :            :         return NGX_OK;
     597                 :            :     }
     598                 :            : 
     599                 :            :     if (r->parent->postponed) {
     600                 :            :         dd("Found parent->postponed...");
     601                 :            : 
     602                 :            :         saved_data = r->connection->data;
     603                 :            :         ppr = NULL;
     604                 :            :         for (pr = r->parent->postponed; pr->next; pr = pr->next) {
     605                 :            :             if (pr->request == NULL) {
     606                 :            :                 continue;
     607                 :            :             }
     608                 :            : 
     609                 :            :             if (pr->request == r) {
     610                 :            :                 /* r->parent->postponed->next = pr; */
     611                 :            :                 dd("found the current subrequest");
     612                 :            :                 out = pr->out;
     613                 :            :                 continue;
     614                 :            :             }
     615                 :            : 
     616                 :            :             /* r->connection->data = pr->request; */
     617                 :            :             dd("finalizing the subrequest...");
     618                 :            :             ngx_http_upstream_create(pr->request);
     619                 :            :             pr->request->upstream = NULL;
     620                 :            : 
     621                 :            :             if (ppr == NULL) {
     622                 :            :                 r->parent->postponed = pr->next;
     623                 :            :                 ppr = pr->next;
     624                 :            :             } else {
     625                 :            :                 ppr->next = pr->next;
     626                 :            :                 ppr = pr->next;
     627                 :            :             }
     628                 :            :         }
     629                 :            :     }
     630                 :            : 
     631                 :            :     r->parent->postponed->next = NULL;
     632                 :            : 
     633                 :            :     /*
     634                 :            :     r->connection->data = r->parent;
     635                 :            :     r->connection->buffered = 0;
     636                 :            : 
     637                 :            :     if (out != NULL) {
     638                 :            :         dd("trying to send more stuffs for the parent");
     639                 :            :         ngx_http_output_filter(r->parent, out);
     640                 :            :     }
     641                 :            :     */
     642                 :            : 
     643                 :            :     /* ngx_http_send_special(r->parent, NGX_HTTP_LAST); */
     644                 :            : 
     645                 :            :     if (saved_data) {
     646                 :            :         r->connection->data = saved_data;
     647                 :            :     }
     648                 :            : 
     649                 :            :     dd("terminating the parent request");
     650                 :            : 
     651                 :            :     return ngx_http_echo_send_chain_link(r, ctx, NULL /* indicate LAST */);
     652                 :            : 
     653                 :            :     /* ngx_http_upstream_create(r); */
     654                 :            : 
     655                 :            :     /* ngx_http_finalize_request(r->parent, NGX_ERROR); */
     656                 :            : #endif
     657                 :            : 
     658                 :          0 :     return NGX_OK;
     659                 :            : }
     660                 :            : 
     661                 :            : 
     662                 :            : ngx_int_t
     663                 :          0 : ngx_http_echo_exec_exec(ngx_http_request_t *r,
     664                 :            :         ngx_http_echo_ctx_t *ctx, ngx_array_t *computed_args)
     665                 :            : {
     666                 :            :     ngx_str_t                       *uri;
     667                 :            :     ngx_str_t                       *user_args;
     668                 :            :     ngx_str_t                        args;
     669                 :            :     ngx_uint_t                       flags;
     670                 :            :     ngx_str_t                       *computed_arg;
     671                 :            : 
     672                 :          0 :     computed_arg = computed_args->elts;
     673                 :            : 
     674                 :          0 :     uri = &computed_arg[0];
     675                 :            : 
     676         [ #  # ]:          0 :     if (uri->len == 0) {
     677                 :          0 :         return NGX_HTTP_BAD_REQUEST;
     678                 :            :     }
     679                 :            : 
     680         [ #  # ]:          0 :     if (computed_args->nelts > 1) {
     681                 :          0 :         user_args = &computed_arg[1];
     682                 :            :     } else {
     683                 :          0 :         user_args = NULL;
     684                 :            :     }
     685                 :            : 
     686                 :          0 :     args.data = NULL;
     687                 :          0 :     args.len = 0;
     688                 :            : 
     689         [ #  # ]:          0 :     if (ngx_http_parse_unsafe_uri(r, uri, &args, &flags)
     690                 :            :             != NGX_OK) {
     691                 :          0 :         ctx->headers_sent = 1;
     692                 :          0 :         return NGX_HTTP_INTERNAL_SERVER_ERROR;
     693                 :            :     }
     694                 :            : 
     695 [ #  # ][ #  # ]:          0 :     if (args.len > 0 && user_args == NULL) {
     696                 :          0 :         user_args = &args;
     697                 :            :     }
     698                 :            : 
     699                 :            :     /*
     700                 :            :     rc = ngx_http_echo_send_header_if_needed(r, ctx);
     701                 :            :     if (r->header_only || rc >= NGX_HTTP_SPECIAL_RESPONSE) {
     702                 :            :         return rc;
     703                 :            :     }
     704                 :            :     */
     705                 :            : 
     706         [ #  # ]:          0 :     if (uri->data[0] == '@') {
     707 [ #  # ][ #  # ]:          0 :         if (user_args && user_args->len > 0) {
     708         [ #  # ]:          0 :             ngx_log_error(NGX_LOG_ALERT, r->connection->log, 0,
     709                 :            :                     "query strings %V ignored when exec'ing named location %V",
     710                 :            :                     user_args, uri);
     711                 :            : 
     712                 :            :         }
     713                 :            : 
     714                 :          0 :         return ngx_http_named_location(r, uri);
     715                 :            :     }
     716                 :            : 
     717                 :          0 :     return ngx_http_internal_redirect(r, uri, user_args);
     718                 :            : }
     719                 :            : 

Generated by: LCOV version 1.9