Nginx-Perl

 view release on metacpan or  search on metacpan

src/http/modules/perl/Nginx.xs  view on Meta::CPAN

        u_char                     *p, *lowcase_key, *value, sep;
        STRLEN                      len;
        ssize_t                     size;
        ngx_uint_t                  i, n, hash;
        ngx_array_t                *a;
        ngx_list_part_t            *part;
        ngx_table_elt_t            *h, **ph;
        ngx_http_header_t          *hh;
        ngx_http_core_main_conf_t  *cmcf;

        ngx_http_perl_set_request(r);

        key = ST(1);

        if (SvROK(key) && SvTYPE(SvRV(key)) == SVt_PV) {
            key = SvRV(key);
        }

        p = (u_char *) SvPV(key, len);

        /* look up hashed headers */

        lowcase_key = ngx_pnalloc(r->pool, len);
        if (lowcase_key == NULL) {
            XSRETURN_UNDEF;
        }

        hash = ngx_hash_strlow(lowcase_key, p, len);

        cmcf = ngx_http_get_module_main_conf(r, ngx_http_core_module);

        hh = ngx_hash_find(&cmcf->headers_in_hash, hash, lowcase_key, len);

        if (hh) {
            if (hh->offset == offsetof(ngx_http_headers_in_t, cookies)) {
                sep = ';';
                goto multi;
            }

    #if (NGX_HTTP_X_FORWARDED_FOR)
            if (hh->offset == offsetof(ngx_http_headers_in_t, x_forwarded_for)) {
                sep = ',';
                goto multi;
            }
    #endif
            if (hh->offset) {

                ph = (ngx_table_elt_t **) ((char *) &r->headers_in + 
                                                    hh->offset);
                if (*ph) {
                    ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);

                    goto done;
                }

                XSRETURN_UNDEF;
            }

        multi:

            /* Cookie, X-Forwarded-For */

            a = (ngx_array_t *) ((char *) &r->headers_in + hh->offset);

            n = a->nelts;

            if (n == 0) {
                XSRETURN_UNDEF;
            }

            ph = a->elts;

            if (n == 1) {
                ngx_http_perl_set_targ((*ph)->value.data, (*ph)->value.len);

                goto done;
            }

            size = - (ssize_t) (sizeof("; ") - 1);

            for (i = 0; i < n; i++) {
                size += ph[i]->value.len + sizeof("; ") - 1;
            }

            value = ngx_pnalloc(r->pool, size);
            if (value == NULL) {
                XSRETURN_UNDEF;
            }

            p = value;

            for (i = 0; /* void */ ; i++) {
                p = ngx_copy(p, ph[i]->value.data, ph[i]->value.len);

                if (i == n - 1) {
                    break;
                }

                *p++ = sep; *p++ = ' ';
            }

            ngx_http_perl_set_targ(value, size);

            goto done;
        }

        /* iterate over all headers */

        part = &r->headers_in.headers.part;
        h = part->elts;

        for (i = 0; /* void */ ; i++) {

            if (i >= part->nelts) {
                if (part->next == NULL) {
                    break;
                }

                part = part->next;
                h = part->elts;
                i = 0;



( run in 2.337 seconds using v1.01-cache-2.11-cpan-39bf76dae61 )