# Reverse proxy + caching seems to break range requests

**URL:** <https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318>\
**Category:** NGINX\
**Created:** [April 4, 2010, 7:54pm UTC](https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318 "2010-04-04T19:54:29Z")\
**Posts on this page:** 5\
**Page:** 1

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [April 4, 2010, 7:54pm UTC](https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318/1 "2010-04-04T19:54:29Z")

</div>

Hi,  
I’ve configured nginx to run as a http reverse proxy with caching turned  
on  
for a location. The backend server supports range headers and responds  
correctly with 206 partial content response. This is needed to support  
pause/resume functionality in the browsers and download managers and  
also to  
support download accelerator clients.

But with nginx reverse proxy with caching enabled, it seems to not work.  
nginx returns full response even when range header is present. Is this a  
known issue?  
Please help fix this.

Thanks,  
Vinay

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [April 4, 2010, 11:17pm UTC](https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318/2 "2010-04-04T23:17:34Z")

</div>

Hello!

On Sun, Apr 04, 2010 at 11:23:32PM +0530, Vinay Y S wrote:

> Please help fix this.  
> nginx removes Range header (as well as several other headers)  
> before passing request to upstream to make sure full response will  
> be cached and other requests for the same uri will be served  
> correctly.

You may change this by adding appropriate headers into  
proxy\_cache\_key and pass Range header via proxy\_set\_header  
directive. E.g.

```
proxy_cache_key "$scheme$proxy_host$request_uri $http_range";
proxy_set_header Range $http_range;

```

See here for more details:

[http://wiki.nginx.org/NginxHttpProxyModule#proxy\_cache\_key](http://wiki.nginx.org/NginxHttpProxyModule#proxy_cache_key)

> **[GitHub - nginxinc/nginx-wiki: ARCHIVED -- Source for the now archived NGINX Wiki...](https://github.com/nginxinc/nginx-wiki)**
>
> ARCHIVED -- Source for the now archived NGINX Wiki section of https://www.nginx.com

Maxim D.

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [April 5, 2010, 10:43pm UTC](https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318/3 "2010-04-05T22:43:56Z")

</div>

On Mon, Apr 5, 2010 at 2:46 AM, Maxim D. [removed\_email\_address@domain.invalid](mailto:removed_email_address@domain.invalid) wrote:

> to  
> correctly.
> 
> It’s fine for it send full request to the upstream so that it can cache  
> the full response. Actually range requests and 206 responses work  
> correctly  
> when caching is not enabled. So, even when caching is enabled, it can  
> still  
> respond correctly to the client by obeying the range header, isn’t it?  
> Is  
> this not implemented consciously for some reason?

Thanks,

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [April 5, 2010, 11:20pm UTC](https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318/4 "2010-04-05T23:20:13Z")

</div>

I see this in the ngx\_http\_upstream.c  
3481 if (r-\>cached) {  
3482 r-\>allow\_ranges = 1;  
3483 return NGX\_OK;  
3484  
3485 }

This seems to explain my observation of ranges working for cache-hits  
but  
not for cache-misses. Can’t we allow ranges to work even for  
cache-misses?

This becomes very important for configurations where caching is enabled  
or  
disabled by the upstream by using X-accel-expires header typically based  
on  
size of the response, like don’t cache larger files. And we especially  
need  
Range mechanism to work for larger files because they are typically file  
downloads for which pause/resume or download accelerator case makes lot  
of  
sense.

Has anyone else faced this problem? Any fix/workaround for this problem?

Thanks,  
Vinay

---

<div class="post-metadata">

**Author:** ![vys](https://www.ruby-forum.com/letter_avatar_proxy/v4/letter/v/4bbf92/32.png) [@vys](https://www.ruby-forum.com/u/vys)\
**Post date:** [April 6, 2010, 12:56am UTC](https://www.ruby-forum.com/t/reverse-proxy-caching-seems-to-break-range-requests/186318/5 "2010-04-06T00:56:46Z")

</div>

Hello!

On Tue, Apr 06, 2010 at 02:13:09AM +0530, Vinay Y S wrote:

> > > correctly with 206 partial content response. This is needed to support  
> > > before passing request to upstream to make sure full response will  
> > > be cached and other requests for the same uri will be served  
> > > correctly.
> > 
> > It’s fine for it send full request to the upstream so that it can cache  
> > the full response. Actually range requests and 206 responses work correctly  
> > when caching is not enabled. So, even when caching is enabled, it can still  
> > respond correctly to the client by obeying the range header, isn’t it? Is  
> > this not implemented consciously for some reason?

Arbitrary range request can’t be satisfied from stream, only from  
file. During first request we have no file yet, so stream is  
passed as is (and this should break anything as client should be  
prepared to get full response in reply to range request per RFC  
2616).

We may try to do some preliminary analysis of requested range and  
obey it if we can though. This is likely to cover almost all  
request (the only exception is multipart range requests, and I’ve  
seen only Acrobat Reader sending them in wild). But this isn’t  
[yet] done, and will likely require some non-trivial changes to  
range filter logic.

Maxim D.
