# Ngx\_http\_send\_special\_response

**URL:** <https://www.ruby-forum.com/t/ngx-http-send-special-response/218926>\
**Category:** NGINX\
**Created:** [April 16, 2012, 10:54am UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926 "2012-04-16T10:54:23Z")\
**Posts on this page:** 7\
**Page:** 1

<div class="post-metadata">

**Author:** ![Gurdipe\_D](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/g/b77776/32.png) [@Gurdipe\_D](https://www.ruby-forum.com/u/Gurdipe_D)\
**Post date:** [April 16, 2012, 10:54am UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/1 "2012-04-16T10:54:23Z")

</div>

Hi

I am appreciate any help I can get on the following issues.

I am writing my own module.

1. I can see in function ngx\_http\_send\_special\_response  
that it calculates the content length of the error page even if the  
request signed as header only (r-\>header\_only = 1)  
and set the content length header with value, after sending the header  
it does not send the body ( because r-\>header\_only = 1)  
so the response arrive with content length different than 0 but without  
body

Is it a BUG?

2.In the module I am trying to redirect the request with status code 302  
(NGX\_HTTP\_MOVED\_TEMPORARILY)  
Trying to user-\>headers\_out.location for the Alternate URL failed, I  
looked in the code and saw the Location must start with “/” - why?

In the end I add it to r-\>headers\_out.headers  
using header = ngx\_list\_push(&r-\>headers\_out.headers);  
Is it the write way to do it?

1. Can you explain please the different between  
a. r-\>headers\_out.content\_length\_n  
b. r-\>headers\_out.content\_length

2. Can you explain the usage of the hash field in ngx\_table\_elt\_t

Thanks  
Hagai A.

---

<div class="post-metadata">

**Author:** ![hagai\_avrahami](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/e47c2d/32.png) [@hagai\_avrahami](https://www.ruby-forum.com/u/hagai_avrahami)\
**Post date:** [April 16, 2012, 12:38pm UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/2 "2012-04-16T12:38:08Z")

</div>

Hello!

On Mon, Apr 16, 2012 at 01:53:39AM -0700, hagai avrahami wrote:

> and set the content length header with value, after sending the header it does  
> not send the body ( because r-\>header\_only = 1)  
> so the response arrive with content length different than 0 but without body
> 
> Is it a BUG?

No. The r-\>header\_only flag should is set when body isn’t  
expected per protocol (HEAD requests, 304 responses). Having  
Content-Length present in such responses is ok.

> 2.In the module I am trying to redirect the request with status code 302  
> (NGX\_HTTP\_MOVED\_TEMPORARILY)  
> Trying to user-\>headers\_out.location for the Alternate URL failed, I looked in  
> the code and saw the Location must start with “/” - why?

You have to set it correctly, i.e. add to r-\>headers\_out.headers  
and link to r-\>headers\_out.location. If it starts with “/” it  
works even if set incorrectly due to adding of a server\_name,  
that’s probably what confused you.

> In the end I add it to r-\>headers\_out.headers  
> using header = ngx\_list\_push(&r-\>headers\_out.headers);  
> Is it the write way to do it?
> 
> 1. Can you explain please the different between  
> a. r-\>headers\_out.content\_length\_n  
> b. r-\>headers\_out.content\_length

The content\_length\_n is a numeric length, this what you normaly  
should set when generating response in nginx. The content\_length  
is a pointer to a headers array element, it might be present if  
there is string representation of a Content-Length header  
available for some reason (e.g. from a backend).

> 1. Can you explain the usage of the hash field in ngx\_table\_elt\_t

Normally the hash field is used for fast lookups in hash  
structures. In case of r-\>headers\_out it’s usually just set to 1  
indicate the header is valid (or reset to 0 to indicate the  
header should not be sent as it was superseeded by some other  
header).

Maxim D.

---

<div class="post-metadata">

**Author:** ![hagai\_avrahami](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/e47c2d/32.png) [@hagai\_avrahami](https://www.ruby-forum.com/u/hagai_avrahami)\
**Post date:** [April 16, 2012, 1:29pm UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/3 "2012-04-16T13:29:41Z")

</div>

WOW thanks for the quick and elaborate response

So what is the right way to send response with status code 302 on GET  
request but  
with content length 0 and no body (I want to redirect the request to  
other Server)

Thanks

Hagai

---

<div class="post-metadata">

**Author:** ![hagai\_avrahami](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/e47c2d/32.png) [@hagai\_avrahami](https://www.ruby-forum.com/u/hagai_avrahami)\
**Post date:** [April 16, 2012, 3:39pm UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/4 "2012-04-16T15:39:01Z")

</div>

Hello!

On Mon, Apr 16, 2012 at 04:29:18AM -0700, hagai avrahami wrote:

> WOW thanks for the quick and elaborate response
> 
> So what is the right way to send response with status code 302 on GET request  
> but  
> with content length 0 and no body (I want to redirect the request to other  
> Server)

Easiest solution is to just write

```
return 302 $where;

```

in config. 🙂

From the code point of view (assuming content handler context),  
something like this should work:

```
ngx_table_elt_t *h;

ngx_http_clear_location(r);

h = ngx_list_push(&r->headers_out.headers);
if (h == NULL) {
    return NGX_HTTP_INTERNAL_SERVER_ERROR;
}

h->hash = 1;
ngx_str_set(&h->key, "Location");

h->value.data = ...
h->value.len = ...

r->headers_out.location = h;

return NGX_HTTP_MOVED_TEMPORARILY;

```

Maxim D.

> > To: [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)
> > 
> > > 
> > 
> > that’s probably what confused you.  
> > should set when generating response in nginx. The content\_length  
> > header).
> > 
> > Maxim D.
> > 
> > * * *
> > 
> > nginx mailing list  
> > [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
> > [mailman.nginx.org archive](http://mailman.nginx.org/mailman/listinfo/nginx)

---

<div class="post-metadata">

**Author:** ![hagai\_avrahami](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/e47c2d/32.png) [@hagai\_avrahami](https://www.ruby-forum.com/u/hagai_avrahami)\
**Post date:** [April 16, 2012, 5:15pm UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/5 "2012-04-16T17:15:21Z")

</div>

Hi  
Thanks

The redirect response is from content handler context.

Using the code you added

cause Nginx to send back the Error Page (302) with Content-Length and  
Content-Type (“test/html”) (And I am trying avoid that) without Body

That’s why I assumed using r-\>header\_only = 1 will solve my problem but  
as you explained it is used for other cases.  
please see that in ngx\_http\_send\_special\_response when this flag set to  
1 the Header is set with this fields but no body in response (I think  
this is not a good result)

if adding in the beginning of the function  
(ngx\_http\_send\_special\_response) the following code it solves the  
problem:

if (r-\>header\_only == 1)  
{  
ngx\_http\_clear\_accept\_ranges®;  
ngx\_http\_clear\_last\_modified®;

rc = ngx\_http\_send\_header®;

return rc;  
}

Is there any other way I can avoid content length and content-type in  
302 response  
Thanks  
Hagai

---

<div class="post-metadata">

**Author:** ![hagai\_avrahami](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/e47c2d/32.png) [@hagai\_avrahami](https://www.ruby-forum.com/u/hagai_avrahami)\
**Post date:** [April 16, 2012, 5:58pm UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/6 "2012-04-16T17:58:08Z")

</div>

Hello!

On Mon, Apr 16, 2012 at 08:14:25AM -0700, hagai avrahami wrote:

> Hi  
> Thanks
> 
> The redirect response is from content handler context.
> 
> Using the code you added
> 
> cause Nginx to send back the Error Page (302) with  
> Content-Length and Content-Type (“test/html”) (And I am trying  
> avoid that) without Body

Ah, sorry, I missed you want to send 302 with an empty body, not  
just 302. Then instead of

```
return NGX_HTTP_MOVED_TEMPORARY;

```

you have to send actual response youself, like this:

```
r->headers_out.status = NGX_HTTP_MOVED_TEMPORARY;
r->headers_out.content_length_n = 0;

rc = ngx_http_send_header(r);

if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
    return rc;
}

return ngx_http_send_special(r, NGX_HTTP_LAST);

```

Maxim D.

---

<div class="post-metadata">

**Author:** ![hagai\_avrahami](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/h/e47c2d/32.png) [@hagai\_avrahami](https://www.ruby-forum.com/u/hagai_avrahami)\
**Post date:** [April 16, 2012, 6:28pm UTC](https://www.ruby-forum.com/t/ngx-http-send-special-response/218926/7 "2012-04-16T18:28:33Z")

</div>

Thanks!
