openresty / srcache-nginx-module

Transparent subrequest-based caching layout for arbitrary nginx locations.
http://wiki.nginx.org/NginxHttpSRCacheModule
476 stars 105 forks source link

send 304 header by this module #29

Closed lloydzhou closed 10 years ago

lloydzhou commented 10 years ago

i make one location, to using lua code, and check the Etag to send 304 status code. but when i use this module to cache this location, it always hit the cache, and send 200 status code, also send the body every time.

lloydzhou commented 10 years ago

I make some mistake..... please just close this issue.

lloydzhou commented 10 years ago

i have read source code "ngx_http_srcache_fetch.c", this module just send 304 when check the "r->headers_out.last_modified_time".

i want to add check for etag.

lloydzhou commented 10 years ago

i have fork you code, and add the etag check in "ngx_http_srcache_fetch.c". you can review the code here https://github.com/lloydzhou/srcache-nginx-module/commit/d5303ac35ea99f253e0c01f309182cba25dc9543.

lloydzhou commented 10 years ago

may be we no need to check if modified or not, when hit the cache in "srcache_fetch". if hit cache, the response data from cache always the latest data. so, if user send any header to check if modified, just send 304 status. is this right?

agentzh commented 10 years ago

@lloydzhou I've just committed a fix to git master of this module so that it no longer bypasses the standard ngx_not_modified module's header filter. That way ngx_srcache supports both If-Modified-Since (for Last-Modified) and If-None-Match (for ETag) request headers out of the box.

The following test case demonstrates the usage:

https://github.com/openresty/srcache-nginx-module/blob/master/t/etag.t#L80

Please try it out on your side and let me know if it works for you.

But please note that due to a bug in the NGINX core, the Last-modified response header is required for ETag to take effect, see

http://osdir.com/ml/nginx/2013-11/msg00015.html

BTW, the suggestion in your last comment is not valid because browser-side cache and server-side cache may have different TTL settings (not to mention it also breaks RFC rules horribly).

lloydzhou commented 10 years ago

good job!!!

lloydzhou commented 10 years ago

i have update code, using master branch code. but some times the ngx_srcache module do not store the response body, only http headers...

this is my config: \ outner location:

        location ~ '/api/(.*)' {
            set $key $uri;
            set_escape_uri $escaped_key $key;
            srcache_fetch GET /redis $key;
            srcache_store PUT /redis2 key=$escaped_key&exptime=60*60;

            add_header X-Fetch-Status $srcache_fetch_status;
            add_header X-Store-Status $srcache_store_status;

            add_header Access-Control-Allow-Origin '*';
            add_header Access-Control-Allow-Methods 'PUT, POST, GET, OPTIONS';
            add_header Access-Control-Allow-Headers 'X-Requested-With';
            add_header Access-Control-Allow-Credentials 'true';

            header_filter_by_lua 'ngx.header.Content_Type="application/json; charset=utf-8;" ngx.header.Etag = ngx.time(); ngx.header.Last_Modified = ngx.http_time(ngx.time()+60*60);';
            echo_location '/internal/$1';
        }

\ internal location:

        location ~ '/internal/user/([0-9]+)'{
            drizzle_query 'select * from users where id=$1';
            drizzle_pass backend;
            rds_json on;
        }

some times i get 200 status code, and not get the body...the "X-Fetch-Status" is "HIT", and the "X-Store-Status" is "BYPASS"... so i check the reids, and see there's only http header, no http body stored...

redis 127.7.97.4:16379> get 7924bb905466929097060e3b256878d7
"HTTP/1.1 200 OK\r\nContent-Type: application/json; charset=utf-8;\r\nEtag: 1398786039\r\nLast-Modified: Tue, 29 Apr 2014 16:40:39 GMT\r\n\r\n"
redis 127.7.97.4:16379> get 4d2bf7b90748140382303e0dff53378a
"HTTP/1.1 200 OK\r\nContent-Type: application/json; charset=utf-8;\r\nEtag: 1398786066\r\nLast-Modified: Tue, 29 Apr 2014 16:41:06 GMT\r\n\r\n"
agentzh commented 10 years ago

@lloydzhou For your latest issue, to quote the related part in ngx_srcache's official documentation:

"The srcache_store directive can not be used to capture the responses generated by echo-nginx-module's subrequest directivees like echo_subrequest_async and echo_location."

See https://github.com/openresty/srcache-nginx-module#known-issues

And this is due to the internal limiation in the nginx core and I can do nothing about it on my side.

You're recommended to use the ngx_lua module to initiate and capture subrequests, which should work with ngx_srcache. Because you'll use Lua to do subrequests to ngx_drizzle anyway, you're recommended to use the lua-resty-mysql library instead, which should be more efficient (and also simpler): https://github.com/openresty/lua-resty-mysql#readme

lloydzhou commented 10 years ago

thank you very much!

agentzh commented 10 years ago

Consider it resolved.