ngx_http_lua_copy_request_headers(ngx_http_request_t *sr,
    ngx_http_request_t *pr, int pr_not_chunked)
{
    ngx_table_elt_t                 *clh, *header;
    ngx_list_part_t                 *part;
    ngx_uint_t                       i;
    u_char                          *p;
    off_t                            len;

    dd("before: parent req headers count: %d",
       (int) pr->headers_in.headers.part.nelts);

    if (ngx_list_init(&sr->headers_in.headers, sr->pool, 20,
                      sizeof(ngx_table_elt_t)) != NGX_OK)
    {
        return NGX_ERROR;
    }

    if (sr->request_body && !pr_not_chunked) {

        /* craft our own Content-Length */

        len = sr->request_body->buf ? ngx_buf_size(sr->request_body->buf) : 0;

        clh = ngx_list_push(&sr->headers_in.headers);
        if (clh == NULL) {
            return NGX_ERROR;
        }

        clh->hash = ngx_http_lua_content_length_hash;
        clh->key = ngx_http_lua_content_length_header_key;
        clh->lowcase_key = ngx_pnalloc(sr->pool, clh->key.len);
        if (clh->lowcase_key == NULL) {
            return NGX_ERROR;
        }

        ngx_strlow(clh->lowcase_key, clh->key.data, clh->key.len);

        p = ngx_palloc(sr->pool, NGX_OFF_T_LEN);
        if (p == NULL) {
            return NGX_ERROR;
        }

        clh->value.data = p;
        clh->value.len = ngx_sprintf(clh->value.data, "%O", len)
                         - clh->value.data;

        sr->headers_in.content_length = clh;
        sr->headers_in.content_length_n = len;

        dd("sr crafted content-length: %.*s",
           (int) sr->headers_in.content_length->value.len,
           sr->headers_in.content_length->value.data);
    }

    /* copy the parent request's headers */

    part = &pr->headers_in.headers.part;
    header = part->elts;

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

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

            part = part->next;
            header = part->elts;
            i = 0;
        }

        if (!pr_not_chunked && header[i].key.len == sizeof("Content-Length") - 1
            && ngx_strncasecmp(header[i].key.data, (u_char *) "Content-Length",
                               sizeof("Content-Length") - 1) == 0)
        {
            continue;
        }

        dd("sr copied req header %.*s: %.*s", (int) header[i].key.len,
           header[i].key.data, (int) header[i].value.len,
           header[i].value.data);

        if (ngx_http_lua_set_input_header(sr, header[i].key,
                                          header[i].value, 0) == NGX_ERROR)
        {
            return NGX_ERROR;
        }
    }

    dd("after: parent req headers count: %d",
       (int) pr->headers_in.headers.part.nelts);

    return NGX_OK;
}
ngx_http_lua_copy_request_headers(ngx_http_request_t *sr,
    ngx_http_request_t *pr, int pr_not_chunked)
{
    ngx_table_elt_t                 *clh, *header;
    ngx_list_part_t                 *part;
    ngx_uint_t                       i;
    u_char                          *p;
    off_t                            len;

    dd("before: parent req headers count: %d",
       (int) pr->headers_in.headers.part.nelts);

    if (ngx_list_init(&sr->headers_in.headers, sr->pool, 20,
                      sizeof(ngx_table_elt_t)) != NGX_OK)
    {
        return NGX_ERROR;
    }

    if (sr->request_body && !pr_not_chunked) {

         

        len = sr->request_body->buf ? ngx_buf_size(sr->request_body->buf) : 0;

        clh = ngx_list_push(&sr->headers_in.headers);
        if (clh == NULL) {
            return NGX_ERROR;
        }

        clh->hash = ngx_http_lua_content_length_hash;
        clh->key = ngx_http_lua_content_length_header_key;
        clh->lowcase_key = ngx_pnalloc(sr->pool, clh->key.len);
        if (clh->lowcase_key == NULL) {
            return NGX_ERROR;
        }

        ngx_strlow(clh->lowcase_key, clh->key.data, clh->key.len);

        p = ngx_palloc(sr->pool, NGX_OFF_T_LEN);
        if (p == NULL) {
            return NGX_ERROR;
        }

        clh->value.data = p;
        clh->value.len = ngx_sprintf(clh->value.data, "%O", len)
                         - clh->value.data;

        sr->headers_in.content_length = clh;
        sr->headers_in.content_length_n = len;

        dd("sr crafted content-length: %.*s",
           (int) sr->headers_in.content_length->value.len,
           sr->headers_in.content_length->value.data);
    }

     

    part = &pr->headers_in.headers.part;
    header = part->elts;

    for (i = 0;  ; i++) {

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

            part = part->next;
            header = part->elts;
            i = 0;
        }

        if (!pr_not_chunked && header[i].key.len == sizeof("Content-Length") - 1
            && ngx_strncasecmp(header[i].key.data, (u_char *) "Content-Length",
                               sizeof("Content-Length") - 1) == 0)
        {
            continue;
        }

        dd("sr copied req header %.*s: %.*s", (int) header[i].key.len,
           header[i].key.data, (int) header[i].value.len,
           header[i].value.data);

        if (ngx_http_lua_set_input_header(sr, header[i].key,
                                          header[i].value, 0) == NGX_ERROR)
        {
            return NGX_ERROR;
        }
    }

    dd("after: parent req headers count: %d",
       (int) pr->headers_in.headers.part.nelts);

    return NGX_OK;
}