Should 0 bytes responses be cached or not (on middle points like CDN or other proxies) is a problem that can be addressed by two entities:
For client’s request to be met it’s assumed that #1 is honored. What RFC says for 0 bytes caching, basically, is that if a file (or other asset/object) is requested to be delivered as a full object and server delivers it incompletely unless incomplete delivery has been requested server must mark it as partial content. Otherwise this delivery is treated as broken delivery - corrupted delivery. Below is a sequence from RFC 7234 that defines the rule for object caching relative to content delivery: A cache MAY complete a stored incomplete response by making a subsequent range request ([RFC7233]) and combining the successful response with the stored entry, as defined in Section 3.3. A cache MUST NOT use an incomplete response to answer requests unless the response has been made complete or the request is partial and specifies a range that is wholly within the incomplete response. A cache MUST NOT send a partial response to a client without explicitly marking it as such using the 206 (Partial Content) status code. Workaround (with snippet located at: https://gist.github.com/caquino/5506639) is manipulating variable based on the upstream content length provided and it is then used in proxy_no_cache to prevent caching of a response without healthy content:
map $upstream_http_content_length $flag_cache_empty { default 0; 0 1; } server { .... location / { ... proxy_no_cache $flag_cache_empty; proxy_cache_bypass $flag_cache_empty; ... } }
Below is a test case with single vps box with apache (port 8080) and nginx (port 80 -> caching from 8080). Apache is delivering intentionally created 0 byte file which is proxied through nginx. Plan is to catch Content-Length on nginx side and perform proxy_no_cache with appropriate value (which, as explained, depends on Content-Length header): apache conf:
<VirtualHost *:8080> ServerAdmin webmaster@localhost DocumentRoot /var/www/html ErrorLog ${APACHE_LOG_DIR}/error.log CustomLog ${APACHE_LOG_DIR}/access.log combined </VirtualHost>
map $upstream_http_content_length $flag_cache_empty { default 0; 0 1; } server { listen 80 default_server; listen https://www.linkedin.com/redir/invalid-link-page?url=%5B%3A%3A%5D:80 default_server ipv6only=on; root /usr/share/nginx/html; index index.html index.htm; # Make site accessible from http://localhost/ server_name localhost; proxy_cache idabic; location / { proxy_pass http://localhost:8080; proxy_cache_valid 200 1d; proxy_cache_min_uses 2; gzip on; gzip_min_length 100; gzip_types text/plain text/xml application/xml text/css text/javascript application/javascript application/x-javascript text/x-component application/json application/xhtml+xml application/rss+xml application/atom+xml application/vnd.ms-fontobject image/svg+xml application/x-font-ttf font/opentype application/octet-stream; gzip_comp_level 1; gzip_disable "MSIE [1-6]\."; add_header Ivan-Cache $upstream_cache_status; add_header CL $upstream_http_content_length; add_header CL0 $flag_cache_empty; proxy_no_cache $flag_cache_empty; proxy_cache_key $scheme$http_host$uri$is_args$args; }
~# curl -I http://localhost/empty_file.js HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Date: Sat, 03 Oct 2015 15:09:42 GMT Content-Type: application/javascript Content-Length: 0 Connection: keep-alive Last-Modified: Sat, 03 Oct 2015 15:02:26 GMT ETag: "0-52134917e9217" Accept-Ranges: bytes Ivan-Cache: MISS CL: 0 CL0: 1
~# wget -O /dev/null -d http://localhost/empty_file.js DEBUG output created by Wget 1.15 on linux-gnu. URI encoding = ‘UTF-8’ --2015-10-03 11:10:01-- http://localhost/empty_file.js Resolving localhost (localhost)... 127.0.0.1 Caching localhost => 127.0.0.1 Connecting to localhost (localhost)|127.0.0.1|:80... connected. Created socket 4. Releasing 0x00000000014cf180 (new refcount 1). ---request begin--- GET /empty_file.js HTTP/1.1 User-Agent: Wget/1.15 (linux-gnu) Accept: */* Host: localhost Connection: Keep-Alive ---request end--- HTTP request sent, awaiting response... ---response begin--- HTTP/1.1 200 OK Server: nginx/1.4.6 (Ubuntu) Date: Sat, 03 Oct 2015 15:10:01 GMT Content-Type: application/javascript Content-Length: 0 Connection: keep-alive Last-Modified: Sat, 03 Oct 2015 15:02:26 GMT ETag: "0-52134917e9217" Accept-Ranges: bytes Ivan-Cache: MISS CL: 0 CL0: 1 ---response end--- 200 OK Registered socket 4 for persistent reuse. Length: 0 [application/javascript] Saving to: ‘/dev/null’ [ <=> ] 0 --.-K/s in 0s 2015-10-03 11:10:01 (0.00 B/s) - ‘/dev/null’ saved [0/0]
Fill out the enquiry form and we'll get back to you as soon as possible.
Fill out the enquiry form and we'll get back to you as soon as possible.