I am running Nginx as a reverse proxy in front of a Python (Gunicorn) application server.

I would like to configure it such that reading from a (potentially large) client request is aborted and the connection with the downstream client is closed once the upstream server has sent a response and closed its connection.
Ideally, the upstream response is still sent downstream to the client before closing the connection.

The use-case is summarized as follows:

* requests may be relatively large; processing them in nginx (including SSL) is expensive and a performance-bottleneck.
* it is often possible to determine that a request is invalid based on a small percentage of leading bytes of the request (i.e. request-headers, or other header information)
* the logic for determining this fact is in the upstream application server and is non-trivial and dynamic in nature, i.e. pushing the logic into an nginx conf is undesirable.

The implementation of the part that I got working is:

* In my Python application code, I do reading from the request in streaming style. I return a (non-streaming, but small) response when having determined one of the error conditions.
* Gunicorn (configured with the "sync" worker) writes the response to the socket and closes the connection. (i.e. sock.close)

My test set up is to have an artificially rate-limited client (basically putting sock.send(single_byte) in a loop with a sleep).

* Running Gunicorn without nginx in front, I see that the client indeed stops sending right after Gunicorn closes the connection
* Running Gunicorn with ngnix in front, I see (having added a print-statement) that Gunicorn closes its connection (with Nginx). But Nginx does not take that as a clue to drop the connection with the client.

The relevant part of the Nginx conf is:

```
location / {
# Pass the request to Gunicorn via proxy_pass.
proxy_pass http://127.0.0.1:8000;

proxy_request_buffering off; # this is needed such that the upstream server can read the parts of the request that have been sent by the test script and act on it.
proxy_buffering off; # as I understand it this is not needed / helpful, but I added it "just in case"
```

How do I instruct nginx to pass on the upstream connection-close on to the client?

Previously on (the version on the present forum is more up-to-date): https://serverfault.com/questions/1162301/configure-nginx-to-close-connection-when-upstream-has-sent-its-response
> Ideally, the upstream response is still sent downstream to the client before closing the connection.

I have just confirmed that in the status quo the response from the upstream server is already sent to the client. It's just that the closing of the connection is not passed on.
Sorry, only registered users may post in this forum.

Click here to login

Online Users

Guests: 264
Record Number of Users: 8 on April 13, 2023
Record Number of Guests: 500 on July 15, 2024
Powered by nginx      Powered by FreeBSD      PHP Powered      Powered by MariaDB      ipv6 ready