# Subrequest using Parent Request Body

**URL:** <https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226>\
**Category:** NGINX\
**Created:** [May 8, 2010, 12:40am UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226 "2010-05-08T00:40:09Z")\
**Posts on this page:** 6\
**Page:** 1

<div class="post-metadata">

**Author:** ![Matthieu\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@Matthieu\_T](https://www.ruby-forum.com/u/Matthieu_T)\
**Post date:** [May 8, 2010, 12:40am UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226/1 "2010-05-08T00:40:09Z")

</div>

Hi,

I’m trying to send a POST Subrequest using the same request\_body as the  
Parent Request.  
The subrequest is sent first, and once it has been finalized the parent  
request goes through.  
(this is inspired on Maxim’s ngx\_http\_auth\_request\_module)

It works almost fine, but if I try to make this subrequest to a location  
containing a proxy\_pass, I get some weird behavior. (The connection  
takes  
forever to terminate).

My guess is that the request\_body gets read by the upstream, and  
discarded.  
When the parent request goes through, that data is not available  
anymore.  
If I create a dummy request\_body for the subrequest with temporary  
buffers,  
it seems to work fine.

I think I might be able to get around this by reading first the original  
request\_body using ngx\_http\_read\_client\_request\_body(),  
and then copying the content of r-\>request\_body to temporary buffers in  
my  
subrequest.

But I’m not sure that would be the best way to solve this problem.

Any ideas ?

Thank you,

Matthieu.

---

<div class="post-metadata">

**Author:** ![Matthieu\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@Matthieu\_T](https://www.ruby-forum.com/u/Matthieu_T)\
**Post date:** [May 10, 2010, 2:31am UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226/2 "2010-05-10T02:31:29Z")

</div>

matthieu,

i may be experiencing the same issue. built a filter which sends a  
subrequest to a location different from the parent request. in my  
scenario i’ve seen both the parent and subrequest called first  
(varnishlog), haven’t been able to figure out why the order in which  
requests are called is not consistent. from the nginx error log it  
appears that parent request is written to a temporary file and when the  
subrequest is returned from upstream my page will hang. there must be a  
way to finalize the request and force the buffer to written to the  
client.

peter

Posted at Nginx Forum:

> **[Re: Subrequest using Parent Request Body](https://forum.nginx.org/read.php?2,84026,84605#msg-84605)**
>
> Hi, I'm trying to send a POST Subrequest using the same request\_body as the Parent Request. The subrequest is sent first, and once it has been finalized the parent request goes through. (this is inspired on Maxim's ngx\_http\_auth\_request\_module) It wo

---

<div class="post-metadata">

**Author:** ![Matthieu\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@Matthieu\_T](https://www.ruby-forum.com/u/Matthieu_T)\
**Post date:** [May 10, 2010, 5:10am UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226/3 "2010-05-10T05:10:40Z")

</div>

On Mon, May 10, 2010 at 8:30 AM, peterjanovsky [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> i may be experiencing the same issue. built a filter which sends a  
> subrequest to a location different from the parent request. in my scenario  
> i’ve seen both the parent and subrequest called first (varnishlog), haven’t  
> been able to figure out why the order in which requests are called is not  
> consistent.

Because non-blocking I/O takes action here (well, merely a guess,  
because I haven’t seen your code and config) 🙂

There’s a consistent “active request” relay chain going on here  
though, i.e., the pointer of r-\>connection-\>data. One should not take  
certain actions when the current “active request” is not the one that  
is being operated in most cases, or he will run into troubles 🙂 Also,  
be very careful with r-\>main-\>count, if one does not get it right,  
mysterious issues like response truncating and request hanging are not  
unusual at all 🙂 (In those cases, --with-debug is your friend :))

There’re a bunch of nginx modules that take advantage of subrequests,  
like ngx\_addition, ngx\_ssi, ngx\_eval, ngx\_echo, ngx\_auth\_request (and  
more are coming!)

Cheers,  
-agentzh

---

<div class="post-metadata">

**Author:** ![Matthieu\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@Matthieu\_T](https://www.ruby-forum.com/u/Matthieu_T)\
**Post date:** [May 11, 2010, 3:42am UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226/4 "2010-05-11T03:42:27Z")

</div>

Hello!

On Fri, May 07, 2010 at 03:38:54PM -0700, Matthieu T. wrote:

> My guess is that the request\_body gets read by the upstream, and discarded.  
> When the parent request goes through, that data is not available anymore.

If you issue subrequest before request body was read by main  
request, you likely get SIGSEGV on an attempt to read it. If you  
didn’t - you probably just didn’t used -DDEBUG\_MALLOC while  
compiling nginx (or appropriate malloc options in your OS). It’s  
only possible to read request body in main request.

> If I create a dummy request\_body for the subrequest with temporary buffers,  
> it seems to work fine.
> 
> I think I might be able to get around this by reading first the original  
> request\_body using ngx\_http\_read\_client\_request\_body(),  
> and then copying the content of r-\>request\_body to temporary buffers in my  
> subrequest.

There is no good/reliable way to preserve request body and use it  
for two upstream requests. There are no problems with in-memory  
buffer (at least I’m not aware of), but once your request body is  
buffered to temporary file - it will be released by first  
successful upstream request (see ngx\_http\_upstream\_send\_response()  
in ngx\_http\_upstream.c).

Using dupfd() on temporary file descriptor may be an option, but  
it’s your responsibility to do it properly.

Maxim D.

---

<div class="post-metadata">

**Author:** ![Matthieu\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@Matthieu\_T](https://www.ruby-forum.com/u/Matthieu_T)\
**Post date:** [May 12, 2010, 9:16pm UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226/5 "2010-05-12T21:16:50Z")

</div>

On Mon, May 10, 2010 at 6:41 PM, Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid)  
wrote:

> > It works almost fine, but if I try to make this subrequest to a location  
> > compiling nginx (or appropriate malloc options in your OS). It’s  
> > subrequest.
> 
> Maxim D.

Hi,

So the way I solved this is to make a full copy of r-\>request\_body into  
temporary bufs of the subrequest.

I would create a subrequest using ngx\_http\_subrequest(),  
then use ngx\_http\_read\_client\_request\_body(r, post\_handler), to read  
r-\>request\_body and set a function to copy it in the subrquest as the  
post\_handler.

I was wondering if this could be dangerous, if the subrequest could be  
fired  
before r-\>request\_body would be completely read, or is it done in a  
sequential order ?

Concerning malloc, is :  
env MALLOC\_OPTIONS=J;  
in nginx.conf sufficient ?

Also, is it possible to something such as Valgrind on nginx workers ?

Thank you,

Matthieu.

---

<div class="post-metadata">

**Author:** ![Matthieu\_T](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/m/71c47a/32.png) [@Matthieu\_T](https://www.ruby-forum.com/u/Matthieu_T)\
**Post date:** [May 12, 2010, 11:23pm UTC](https://www.ruby-forum.com/t/subrequest-using-parent-request-body/188226/6 "2010-05-12T23:23:18Z")

</div>

Hello!

On Wed, May 12, 2010 at 12:15:22PM -0700, Matthieu T. wrote:

[…]

> sequential order ?  
> You have to read body and call ngx\_http\_subrequest() only when  
> it’s fully read (i.e. from post\_handler).

> Concerning malloc, is :  
> env MALLOC\_OPTIONS=J;  
> in nginx.conf sufficient ?

No. Under FreeBSD nginx respects MALLOC\_OPTIONS=J in environment  
and activates the same logic as with -DNGX\_DEBUG\_MALLOC, but it  
has to be already set at master process startup.

On other OSes the only available option is  
./configure --with-cc-opts=“-D NGX\_DEBUG\_MALLOC”.

> Also, is it possible to something such as Valgrind on nginx workers ?

Never tried. Though you may disable daemon mode and master process  
completely with “daemon off; master\_process off;”. This turns  
nginx into simple single-process programm which may be  
debugged/profiled by almost anything. There are some limitations  
(reconfiguration and binary update doesn’t work), but they are  
minimal.

Maxim D.
