LCOV - code coverage report
Current view: top level - home/build/openresty-1.13.6.1/build/ngx_lua-0.10.11/src - ngx_http_lua_headers_out.c (source / functions) Hit Total Coverage
Test: coverage ngix Lines: 0 217 0.0 %
Date: 2020-03-03 04:25:50 Functions: 0 13 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : 
       2             : /*
       3             :  * Copyright (C) Xiaozhe Wang (chaoslawful)
       4             :  * Copyright (C) Yichun Zhang (agentzh)
       5             :  */
       6             : 
       7             : 
       8             : #ifndef DDEBUG
       9             : #define DDEBUG 0
      10             : #endif
      11             : #include "ddebug.h"
      12             : 
      13             : 
      14             : #include <nginx.h>
      15             : #include "ngx_http_lua_headers_out.h"
      16             : #include "ngx_http_lua_util.h"
      17             : #include <ctype.h>
      18             : 
      19             : 
      20             : static ngx_int_t ngx_http_set_header(ngx_http_request_t *r,
      21             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      22             : static ngx_int_t ngx_http_set_header_helper(ngx_http_request_t *r,
      23             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value,
      24             :     ngx_table_elt_t **output_header, unsigned no_create);
      25             : static ngx_int_t ngx_http_set_builtin_header(ngx_http_request_t *r,
      26             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      27             : static ngx_int_t ngx_http_set_builtin_multi_header(ngx_http_request_t *r,
      28             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      29             : static ngx_int_t ngx_http_set_last_modified_header(ngx_http_request_t *r,
      30             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      31             : static ngx_int_t ngx_http_set_content_length_header(ngx_http_request_t *r,
      32             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      33             : static ngx_int_t ngx_http_set_content_type_header(ngx_http_request_t *r,
      34             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      35             : static ngx_int_t ngx_http_clear_builtin_header(ngx_http_request_t *r,
      36             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      37             : static ngx_int_t ngx_http_clear_last_modified_header(ngx_http_request_t *r,
      38             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      39             : static ngx_int_t ngx_http_clear_content_length_header(ngx_http_request_t *r,
      40             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      41             : static ngx_int_t ngx_http_set_location_header(ngx_http_request_t *r,
      42             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value);
      43             : 
      44             : 
      45             : static ngx_http_lua_set_header_t  ngx_http_lua_set_handlers[] = {
      46             : 
      47             :     { ngx_string("Server"),
      48             :                  offsetof(ngx_http_headers_out_t, server),
      49             :                  ngx_http_set_builtin_header },
      50             : 
      51             :     { ngx_string("Date"),
      52             :                  offsetof(ngx_http_headers_out_t, date),
      53             :                  ngx_http_set_builtin_header },
      54             : 
      55             : #if 1
      56             :     { ngx_string("Content-Encoding"),
      57             :                  offsetof(ngx_http_headers_out_t, content_encoding),
      58             :                  ngx_http_set_builtin_header },
      59             : #endif
      60             : 
      61             :     { ngx_string("Location"),
      62             :                  offsetof(ngx_http_headers_out_t, location),
      63             :                  ngx_http_set_location_header },
      64             : 
      65             :     { ngx_string("Refresh"),
      66             :                  offsetof(ngx_http_headers_out_t, refresh),
      67             :                  ngx_http_set_builtin_header },
      68             : 
      69             :     { ngx_string("Last-Modified"),
      70             :                  offsetof(ngx_http_headers_out_t, last_modified),
      71             :                  ngx_http_set_last_modified_header },
      72             : 
      73             :     { ngx_string("Content-Range"),
      74             :                  offsetof(ngx_http_headers_out_t, content_range),
      75             :                  ngx_http_set_builtin_header },
      76             : 
      77             :     { ngx_string("Accept-Ranges"),
      78             :                  offsetof(ngx_http_headers_out_t, accept_ranges),
      79             :                  ngx_http_set_builtin_header },
      80             : 
      81             :     { ngx_string("WWW-Authenticate"),
      82             :                  offsetof(ngx_http_headers_out_t, www_authenticate),
      83             :                  ngx_http_set_builtin_header },
      84             : 
      85             :     { ngx_string("Expires"),
      86             :                  offsetof(ngx_http_headers_out_t, expires),
      87             :                  ngx_http_set_builtin_header },
      88             : 
      89             :     { ngx_string("E-Tag"),
      90             :                  offsetof(ngx_http_headers_out_t, etag),
      91             :                  ngx_http_set_builtin_header },
      92             : 
      93             :     { ngx_string("ETag"),
      94             :                  offsetof(ngx_http_headers_out_t, etag),
      95             :                  ngx_http_set_builtin_header },
      96             : 
      97             :     { ngx_string("Content-Length"),
      98             :                  offsetof(ngx_http_headers_out_t, content_length),
      99             :                  ngx_http_set_content_length_header },
     100             : 
     101             :     { ngx_string("Content-Type"),
     102             :                  offsetof(ngx_http_headers_out_t, content_type),
     103             :                  ngx_http_set_content_type_header },
     104             : 
     105             :     { ngx_string("Cache-Control"),
     106             :                  offsetof(ngx_http_headers_out_t, cache_control),
     107             :                  ngx_http_set_builtin_multi_header },
     108             : 
     109             :     { ngx_null_string, 0, ngx_http_set_header }
     110             : };
     111             : 
     112             : 
     113             : /* request time implementation */
     114             : 
     115             : static ngx_int_t
     116           0 : ngx_http_set_header(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv,
     117             :     ngx_str_t *value)
     118             : {
     119           0 :     return ngx_http_set_header_helper(r, hv, value, NULL, 0);
     120             : }
     121             : 
     122             : 
     123             : static ngx_int_t
     124           0 : ngx_http_set_header_helper(ngx_http_request_t *r, ngx_http_lua_header_val_t *hv,
     125             :     ngx_str_t *value, ngx_table_elt_t **output_header,
     126             :     unsigned no_create)
     127             : {
     128             :     ngx_table_elt_t             *h;
     129             :     ngx_list_part_t             *part;
     130             :     ngx_uint_t                   i;
     131           0 :     unsigned                     matched = 0;
     132             : 
     133           0 :     if (hv->no_override) {
     134           0 :         goto new_header;
     135             :     }
     136             : 
     137             : #if 1
     138           0 :     if (r->headers_out.location
     139           0 :         && r->headers_out.location->value.len
     140           0 :         && r->headers_out.location->value.data[0] == '/')
     141             :     {
     142             :         /* XXX ngx_http_core_find_config_phase, for example,
     143             :          * may not initialize the "key" and "hash" fields
     144             :          * for a nasty optimization purpose, and
     145             :          * we have to work-around it here */
     146             : 
     147           0 :         r->headers_out.location->hash = ngx_http_lua_location_hash;
     148           0 :         ngx_str_set(&r->headers_out.location->key, "Location");
     149             :     }
     150             : #endif
     151             : 
     152           0 :     part = &r->headers_out.headers.part;
     153           0 :     h = part->elts;
     154             : 
     155           0 :     for (i = 0; /* void */; i++) {
     156             : 
     157           0 :         if (i >= part->nelts) {
     158           0 :             if (part->next == NULL) {
     159           0 :                 break;
     160             :             }
     161             : 
     162           0 :             part = part->next;
     163           0 :             h = part->elts;
     164           0 :             i = 0;
     165             :         }
     166             : 
     167           0 :         if (h[i].hash != 0
     168           0 :             && h[i].key.len == hv->key.len
     169           0 :             && ngx_strncasecmp(hv->key.data, h[i].key.data, h[i].key.len) == 0)
     170             :         {
     171             :             dd("found out header %.*s", (int) h[i].key.len, h[i].key.data);
     172             : 
     173           0 :             if (value->len == 0 || matched) {
     174             :                 dd("clearing normal header for %.*s", (int) hv->key.len,
     175             :                    hv->key.data);
     176             : 
     177           0 :                 h[i].value.len = 0;
     178           0 :                 h[i].hash = 0;
     179             : 
     180             :             } else {
     181             :                 dd("setting header to value %.*s", (int) value->len,
     182             :                    value->data);
     183             : 
     184           0 :                 h[i].value = *value;
     185           0 :                 h[i].hash = hv->hash;
     186             :             }
     187             : 
     188           0 :             if (output_header) {
     189           0 :                 *output_header = &h[i];
     190             :             }
     191             : 
     192             :             /* return NGX_OK; */
     193           0 :             matched = 1;
     194             :         }
     195             :     }
     196             : 
     197           0 :     if (matched){
     198           0 :         return NGX_OK;
     199             :     }
     200             : 
     201           0 :     if (no_create && value->len == 0) {
     202           0 :         return NGX_OK;
     203             :     }
     204             : 
     205           0 : new_header:
     206             : 
     207             :     /* XXX we still need to create header slot even if the value
     208             :      * is empty because some builtin headers like Last-Modified
     209             :      * relies on this to get cleared */
     210             : 
     211           0 :     h = ngx_list_push(&r->headers_out.headers);
     212             : 
     213           0 :     if (h == NULL) {
     214           0 :         return NGX_ERROR;
     215             :     }
     216             : 
     217           0 :     if (value->len == 0) {
     218           0 :         h->hash = 0;
     219             : 
     220             :     } else {
     221           0 :         h->hash = hv->hash;
     222             :     }
     223             : 
     224           0 :     h->key = hv->key;
     225           0 :     h->value = *value;
     226             : 
     227           0 :     h->lowcase_key = ngx_pnalloc(r->pool, h->key.len);
     228           0 :     if (h->lowcase_key == NULL) {
     229           0 :         return NGX_ERROR;
     230             :     }
     231             : 
     232           0 :     ngx_strlow(h->lowcase_key, h->key.data, h->key.len);
     233             : 
     234           0 :     if (output_header) {
     235           0 :         *output_header = h;
     236             :     }
     237             : 
     238           0 :     return NGX_OK;
     239             : }
     240             : 
     241             : 
     242             : static ngx_int_t
     243           0 : ngx_http_set_location_header(ngx_http_request_t *r,
     244             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     245             : {
     246             :     ngx_int_t         rc;
     247             :     ngx_table_elt_t  *h;
     248             : 
     249           0 :     rc = ngx_http_set_builtin_header(r, hv, value);
     250           0 :     if (rc != NGX_OK) {
     251           0 :         return rc;
     252             :     }
     253             : 
     254             :     /*
     255             :      * we do not set r->headers_out.location here to avoid the handling
     256             :      * the local redirects without a host name by ngx_http_header_filter()
     257             :      */
     258             : 
     259           0 :     h = r->headers_out.location;
     260           0 :     if (h && h->value.len && h->value.data[0] == '/') {
     261           0 :         r->headers_out.location = NULL;
     262             :     }
     263             : 
     264           0 :     return NGX_OK;
     265             : }
     266             : 
     267             : 
     268             : static ngx_int_t
     269           0 : ngx_http_set_builtin_header(ngx_http_request_t *r,
     270             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     271             : {
     272             :     ngx_table_elt_t  *h, **old;
     273             : 
     274           0 :     if (hv->offset) {
     275           0 :         old = (ngx_table_elt_t **) ((char *) &r->headers_out + hv->offset);
     276             : 
     277             :     } else {
     278           0 :         old = NULL;
     279             :     }
     280             : 
     281           0 :     if (old == NULL || *old == NULL) {
     282           0 :         return ngx_http_set_header_helper(r, hv, value, old, 0);
     283             :     }
     284             : 
     285           0 :     h = *old;
     286             : 
     287           0 :     if (value->len == 0) {
     288             :         dd("clearing the builtin header");
     289             : 
     290           0 :         h->hash = 0;
     291           0 :         h->value = *value;
     292             : 
     293           0 :         return NGX_OK;
     294             :     }
     295             : 
     296           0 :     h->hash = hv->hash;
     297           0 :     h->key = hv->key;
     298           0 :     h->value = *value;
     299             : 
     300           0 :     return NGX_OK;
     301             : }
     302             : 
     303             : 
     304             : static ngx_int_t
     305           0 : ngx_http_set_builtin_multi_header(ngx_http_request_t *r,
     306             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     307             : {
     308             :     ngx_array_t      *pa;
     309             :     ngx_table_elt_t  *ho, **ph;
     310             :     ngx_uint_t        i;
     311             : 
     312           0 :     pa = (ngx_array_t *) ((char *) &r->headers_out + hv->offset);
     313             : 
     314           0 :     if (pa->elts == NULL) {
     315           0 :         if (ngx_array_init(pa, r->pool, 2, sizeof(ngx_table_elt_t *))
     316             :             != NGX_OK)
     317             :         {
     318           0 :             return NGX_ERROR;
     319             :         }
     320             :     }
     321             : 
     322           0 :     if (hv->no_override) {
     323           0 :         ph = pa->elts;
     324           0 :         for (i = 0; i < pa->nelts; i++) {
     325           0 :             if (!ph[i]->hash) {
     326           0 :                 ph[i]->value = *value;
     327           0 :                 ph[i]->hash = hv->hash;
     328           0 :                 return NGX_OK;
     329             :             }
     330             :         }
     331             : 
     332           0 :         goto create;
     333             :     }
     334             : 
     335             :     /* override old values (if any) */
     336             : 
     337           0 :     if (pa->nelts > 0) {
     338           0 :         ph = pa->elts;
     339           0 :         for (i = 1; i < pa->nelts; i++) {
     340           0 :             ph[i]->hash = 0;
     341           0 :             ph[i]->value.len = 0;
     342             :         }
     343             : 
     344           0 :         ph[0]->value = *value;
     345             : 
     346           0 :         if (value->len == 0) {
     347           0 :             ph[0]->hash = 0;
     348             : 
     349             :         } else {
     350           0 :             ph[0]->hash = hv->hash;
     351             :         }
     352             : 
     353           0 :         return NGX_OK;
     354             :     }
     355             : 
     356           0 : create:
     357             : 
     358           0 :     ph = ngx_array_push(pa);
     359           0 :     if (ph == NULL) {
     360           0 :         return NGX_ERROR;
     361             :     }
     362             : 
     363           0 :     ho = ngx_list_push(&r->headers_out.headers);
     364           0 :     if (ho == NULL) {
     365           0 :         return NGX_ERROR;
     366             :     }
     367             : 
     368           0 :     ho->value = *value;
     369             : 
     370           0 :     if (value->len == 0) {
     371           0 :         ho->hash = 0;
     372             : 
     373             :     } else {
     374           0 :         ho->hash = hv->hash;
     375             :     }
     376             : 
     377           0 :     ho->key = hv->key;
     378           0 :     *ph = ho;
     379             : 
     380           0 :     return NGX_OK;
     381             : }
     382             : 
     383             : 
     384             : static ngx_int_t
     385           0 : ngx_http_set_content_type_header(ngx_http_request_t *r,
     386             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     387             : {
     388             :     ngx_uint_t          i;
     389             : 
     390           0 :     r->headers_out.content_type_len = value->len;
     391             : 
     392             : #if 1
     393           0 :     for (i = 0; i < value->len; i++) {
     394           0 :         if (value->data[i] == ';') {
     395           0 :             r->headers_out.content_type_len = i;
     396           0 :             break;
     397             :         }
     398             :     }
     399             : #endif
     400             : 
     401           0 :     r->headers_out.content_type = *value;
     402           0 :     r->headers_out.content_type_hash = hv->hash;
     403           0 :     r->headers_out.content_type_lowcase = NULL;
     404             : 
     405           0 :     value->len = 0;
     406             : 
     407           0 :     return ngx_http_set_header_helper(r, hv, value, NULL, 1);
     408             : }
     409             : 
     410             : 
     411           0 : static ngx_int_t ngx_http_set_last_modified_header(ngx_http_request_t *r,
     412             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     413             : {
     414           0 :     if (value->len == 0) {
     415           0 :         return ngx_http_clear_last_modified_header(r, hv, value);
     416             :     }
     417             : 
     418           0 :     r->headers_out.last_modified_time = ngx_http_parse_time(value->data,
     419             :                                                             value->len);
     420             : 
     421             :     dd("last modified time: %d", (int) r->headers_out.last_modified_time);
     422             : 
     423           0 :     return ngx_http_set_builtin_header(r, hv, value);
     424             : }
     425             : 
     426             : 
     427             : static ngx_int_t
     428           0 : ngx_http_clear_last_modified_header(ngx_http_request_t *r,
     429             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     430             : {
     431           0 :     r->headers_out.last_modified_time = -1;
     432             : 
     433           0 :     return ngx_http_clear_builtin_header(r, hv, value);
     434             : }
     435             : 
     436             : 
     437             : static ngx_int_t
     438           0 : ngx_http_set_content_length_header(ngx_http_request_t *r,
     439             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     440             : {
     441             :     off_t           len;
     442             : 
     443           0 :     if (value->len == 0) {
     444           0 :         return ngx_http_clear_content_length_header(r, hv, value);
     445             :     }
     446             : 
     447           0 :     len = ngx_atosz(value->data, value->len);
     448           0 :     if (len == NGX_ERROR) {
     449           0 :         return NGX_ERROR;
     450             :     }
     451             : 
     452           0 :     r->headers_out.content_length_n = len;
     453             : 
     454           0 :     return ngx_http_set_builtin_header(r, hv, value);
     455             : }
     456             : 
     457             : 
     458             : static ngx_int_t
     459           0 : ngx_http_clear_content_length_header(ngx_http_request_t *r,
     460             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     461             : {
     462           0 :     r->headers_out.content_length_n = -1;
     463             : 
     464           0 :     return ngx_http_clear_builtin_header(r, hv, value);
     465             : }
     466             : 
     467             : 
     468             : static ngx_int_t
     469           0 : ngx_http_clear_builtin_header(ngx_http_request_t *r,
     470             :     ngx_http_lua_header_val_t *hv, ngx_str_t *value)
     471             : {
     472           0 :     value->len = 0;
     473             : 
     474           0 :     return ngx_http_set_builtin_header(r, hv, value);
     475             : }
     476             : 
     477             : 
     478             : ngx_int_t
     479           0 : ngx_http_lua_set_output_header(ngx_http_request_t *r, ngx_str_t key,
     480             :     ngx_str_t value, unsigned override)
     481             : {
     482             :     ngx_http_lua_header_val_t         hv;
     483           0 :     ngx_http_lua_set_header_t        *handlers = ngx_http_lua_set_handlers;
     484             :     ngx_uint_t                        i;
     485             : 
     486             :     dd("set header value: %.*s", (int) value.len, value.data);
     487             : 
     488           0 :     hv.hash = ngx_hash_key_lc(key.data, key.len);
     489           0 :     hv.key = key;
     490             : 
     491           0 :     hv.offset = 0;
     492           0 :     hv.no_override = !override;
     493           0 :     hv.handler = NULL;
     494             : 
     495           0 :     for (i = 0; handlers[i].name.len; i++) {
     496           0 :         if (hv.key.len != handlers[i].name.len
     497           0 :             || ngx_strncasecmp(hv.key.data, handlers[i].name.data,
     498           0 :                                handlers[i].name.len) != 0)
     499             :         {
     500             :             dd("hv key comparison: %s <> %s", handlers[i].name.data,
     501             :                hv.key.data);
     502             : 
     503           0 :             continue;
     504             :         }
     505             : 
     506             :         dd("Matched handler: %s %s", handlers[i].name.data, hv.key.data);
     507             : 
     508           0 :         hv.offset = handlers[i].offset;
     509           0 :         hv.handler = handlers[i].handler;
     510             : 
     511           0 :         break;
     512             :     }
     513             : 
     514           0 :     if (handlers[i].name.len == 0 && handlers[i].handler) {
     515           0 :         hv.offset = handlers[i].offset;
     516           0 :         hv.handler = handlers[i].handler;
     517             :     }
     518             : 
     519             : #if 1
     520           0 :     if (hv.handler == NULL) {
     521           0 :         return NGX_ERROR;
     522             :     }
     523             : #endif
     524             : 
     525           0 :     return hv.handler(r, &hv, &value);
     526             : }
     527             : 
     528             : 
     529             : int
     530           0 : ngx_http_lua_get_output_header(lua_State *L, ngx_http_request_t *r,
     531             :     ngx_str_t *key)
     532             : {
     533             :     ngx_table_elt_t            *h;
     534             :     ngx_list_part_t            *part;
     535             :     ngx_uint_t                  i;
     536             :     unsigned                    found;
     537             : 
     538             :     dd("looking for response header \"%.*s\"", (int) key->len, key->data);
     539             : 
     540           0 :     switch (key->len) {
     541           0 :     case 14:
     542           0 :         if (r->headers_out.content_length == NULL
     543           0 :             && r->headers_out.content_length_n >= 0
     544           0 :             && ngx_strncasecmp(key->data, (u_char *) "Content-Length", 14) == 0)
     545             :         {
     546           0 :             lua_pushinteger(L, (lua_Integer) r->headers_out.content_length_n);
     547           0 :             return 1;
     548             :         }
     549             : 
     550           0 :         break;
     551             : 
     552           0 :     case 12:
     553           0 :         if (r->headers_out.content_type.len
     554           0 :             && ngx_strncasecmp(key->data, (u_char *) "Content-Type", 12) == 0)
     555             :         {
     556           0 :             lua_pushlstring(L, (char *) r->headers_out.content_type.data,
     557             :                             r->headers_out.content_type.len);
     558           0 :             return 1;
     559             :         }
     560             : 
     561           0 :         break;
     562             : 
     563           0 :     default:
     564           0 :         break;
     565             :     }
     566             : 
     567             :     dd("not a built-in output header");
     568             : 
     569           0 :     found = 0;
     570             : 
     571             : #if 1
     572           0 :     if (r->headers_out.location
     573           0 :         && r->headers_out.location->value.len
     574           0 :         && r->headers_out.location->value.data[0] == '/')
     575             :     {
     576             :         /* XXX ngx_http_core_find_config_phase, for example,
     577             :          * may not initialize the "key" and "hash" fields
     578             :          * for a nasty optimization purpose, and
     579             :          * we have to work-around it here */
     580             : 
     581           0 :         r->headers_out.location->hash = ngx_http_lua_location_hash;
     582           0 :         ngx_str_set(&r->headers_out.location->key, "Location");
     583             :     }
     584             : #endif
     585             : 
     586           0 :     part = &r->headers_out.headers.part;
     587           0 :     h = part->elts;
     588             : 
     589           0 :     for (i = 0; /* void */; i++) {
     590             : 
     591           0 :         if (i >= part->nelts) {
     592           0 :             if (part->next == NULL) {
     593           0 :                 break;
     594             :             }
     595             : 
     596           0 :             part = part->next;
     597           0 :             h = part->elts;
     598           0 :             i = 0;
     599             :         }
     600             : 
     601           0 :         if (h[i].hash == 0) {
     602           0 :             continue;
     603             :         }
     604             : 
     605           0 :         if (h[i].hash != 0
     606           0 :             && h[i].key.len == key->len
     607           0 :             && ngx_strncasecmp(key->data, h[i].key.data, h[i].key.len) == 0)
     608             :          {
     609           0 :              if (!found) {
     610           0 :                  found = 1;
     611             : 
     612           0 :                  lua_pushlstring(L, (char *) h[i].value.data, h[i].value.len);
     613           0 :                  continue;
     614             :              }
     615             : 
     616           0 :              if (found == 1) {
     617           0 :                  lua_createtable(L, 4 /* narr */, 0);
     618           0 :                  lua_insert(L, -2);
     619           0 :                  lua_rawseti(L, -2, found);
     620             :              }
     621             : 
     622           0 :              found++;
     623             : 
     624           0 :              lua_pushlstring(L, (char *) h[i].value.data, h[i].value.len);
     625           0 :              lua_rawseti(L, -2, found);
     626             :          }
     627             :     }
     628             : 
     629           0 :     if (found) {
     630           0 :         return 1;
     631             :     }
     632             : 
     633           0 :     lua_pushnil(L);
     634           0 :     return 1;
     635             : }
     636             : 
     637             : /* vi:set ft=c ts=4 sw=4 et fdm=marker: */

Generated by: LCOV version 1.13