These might be bugs in the implementations of the web server or uWSGI or whatever else, or configuration issues.
At the end of writing the request body (if any) to the application, the
gateway writes an empty FCGI_STDIN record, which indicates that
no more bytes are available. AFICT uWSGI doesn't read
this unless the application tries to read the request body. httpd with mod_proxy_fcgi gets bit by this problem because it writes
the empty FCGI_STDIN in a separate syscall, and uWSGI may have already
closed the socket. When that timing scenario occurs, mod_proxy_fcgi
can get EPIPE from the writev() and fail the request, returning a
gateway error. The problem occurs much more frequently with Unix sockets
than with TCP sockets, and more frequently with multiple threads configured
for the WSGI application. This doesn't affect nginx because it sends the empty FCGI_STDIN in the
same buffer as the FastCGI parameters (envvars), so uWSGI is always still
waiting for that. See this
blog post for a tiny mod_proxy_fcgi patch to work around this.
This seems odd, but maybe it is on purpose.
If you send a request body that causes the data sent by nginx to uWSGI to exceed 4K (i.e., multiple writes) and the application doesn't try to read the data, nginx sees an error writing the rest but the client sees a 200 (OK) response with empty body. (With the uWSGI problem and httpd, the client sees a gateway error.) I've seen other error scenarios where nginx sent a 200 response with an empty body.
httpd's proxy will take the drastic action of sending no response in some error cases, but that is to get the browser to retry.
This is weird. strace on uWSGI (on the other side of a slow Wi-Fi LAN from nginx) says it wrote 71544 bytes, and strace on nginx says it read 71544 bytes, but the client got a short response, and nginx logged this:
2014/05/01 15:35:38 [error] 32092#0: *3 upstream timed out (110: Connection timed out) while reading upstream, client: 127.0.0.1, server: , request: "POST / HTTP/1.0", upstream: "fastcgi://192.168.1.211:2003", host: "127.0.0.1"
I did not see nginx try another read (after reading as many bytes as uWSGI sent). Maybe I'll find time to play with this more.
not investigated yet
At present, I don't know that I want to get too involved with mod_proxy_uwsgi, in case I want to start with mod_proxy_scgi and write an ASL-licensed version myself for potential inclusion in the httpd project. But for now it doesn't seem very important.