failure with proxyRequest when using http-proxy and connect if bodyDecoder() installed in chain during a POST request #20

Closed
xrd opened this Issue Jan 12, 2011 · 8 comments

Comments

Projects
None yet
3 participants

xrd commented Jan 12, 2011

Hi there,

I've come across what I think is a bug (or at least an incompatibility) within http-proxy.

What I expect to happen: when I make a proxied POST request to the backend, it should process the request normally.

What happens instead: when I make a proxied POST request with the Connect.bodyDecoder() middleware installed, the request hangs forever in the proxy.

I created a very simple test case here: http://vivoh.com/node-proxy.zip

If you unzip this (and have ruby and the sinatra gem installed), you can see what I mean.

Run as is using the run.sh script, and then hit http://localhost:4568. Then, hit the "Submit Query" button. You'll see the http-proxy module successfully proxies the POST request request to the backend sinatra ruby server.

If you then edit "app.js" and uncomment the Connect.bodyDecoder() line, and then kill the node and ruby servers, and then restart using run.sh, if you try the POST request again, you'll see it hangs forever. I speculate there is something happening inside the bodyDecoder() middleware which is incompatible with the http-proxy module. I've looked around, but have not figured it out myself.

Chris

Contributor

Marak commented Jan 12, 2011

I think this makes a lot of sense actually.

If you look at the bodyDecoder middleware you can see it's processing the request object and adding an event listener to the completion of the request. https://github.com/senchalabs/connect/blob/master/lib/connect/middleware/bodyDecoder.js#L40

To my understanding, since the request has already had it's end event fire, it's already been processed and cannot be proxied. http-proxy is hanging because the end and data event of the incoming request have already fired.

I'm sure there is a way around this, it's just a matter of figuring out which library needs to get patched. Wrapping http-proxy up as a proper connect middleware might also be a solution.

Let me talk to the Connect guys and I'll see what we can figure out.

xrd commented Jan 12, 2011

Sounds great. I really appreciate this module, it makes it so easy to do what I need to do and proxy out to other servers within node. Please let me know if there is anything I can do to help troubleshoot any solutions you come across.

xrd commented Jan 12, 2011

And, really what I want to do with the bodyDecoder middleware is pull out certain parameters from the post request. I need to do this for my connect-rpx module. If there were a better way to do this than use bodyDecoder() I would be OK with this too. If I understand you correctly, it seems like the problem is that if you want access to the body of the incoming request (like I need) then it is a bit too late to proxy it.

xrd commented Jan 13, 2011

I got things working. My solution was to remove the bodyDecoder from the filter chain, and then call it only when I need it inside my connect-rpx module.

xrd/connect-rpx@eaffd02

Thanks for your help, your explanation was very helpful in having my understand where the issue was happening.

Chris

Contributor

Marak commented Jan 14, 2011

Cool! You are very welcome. Let me know if you run into any additional issues. Closed.

FYI I have this issue as well, both with one node.js web app proxying AJAX POST requests via http-proxy to another one as well as just a single node.js web app handling AJAX POSTs straight from the browser independently. I found depending on where in the filter chain express.bodyParser() is, I can get this hang. I can work around it by emitting a duplicate 'end' event from the request, but I'd like to understand exactly what I'm doing wrong that is causing this.

Contributor

Marak commented May 18, 2011

@focusaurus If you buffer and parse the incoming request of the body before you proxy the request, you can't proxy the original request anymore.

Yes that makes sense. I have removed the bodyParser middleware from my front end web server, but I'm still hitting some variant of this issue on my back end web server, which is using bodyParser but is NOT proxying the request. Still digging through code to try to understand what other code in my back end web server is waiting for but not seeing the "end" event on the request.

This issue was closed.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment