mirror of
https://github.com/nginx/nginx.git
synced 2025-02-25 18:55:26 -06:00
Entity tags: basic support in not modified filter.
This includes handling of ETag headers (if present in a response) with basic support for If-Match, If-None-Match conditionals in not modified filter. Note that the "r->headers_out.last_modified_time == -1" check in the not modified filter is left as is intentionally. It's to prevent handling of If-* headers in case of proxy without cache (much like currently done with If-Modified-Since).
This commit is contained in:
parent
a9456d55ab
commit
13eb6898aa
@ -12,6 +12,8 @@
|
||||
|
||||
static ngx_uint_t ngx_http_test_if_unmodified(ngx_http_request_t *r);
|
||||
static ngx_uint_t ngx_http_test_if_modified(ngx_http_request_t *r);
|
||||
static ngx_uint_t ngx_http_test_if_match(ngx_http_request_t *r,
|
||||
ngx_table_elt_t *header);
|
||||
static ngx_int_t ngx_http_not_modified_filter_init(ngx_conf_t *cf);
|
||||
|
||||
|
||||
@ -66,9 +68,27 @@ ngx_http_not_modified_header_filter(ngx_http_request_t *r)
|
||||
NGX_HTTP_PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
if (r->headers_in.if_modified_since
|
||||
&& !ngx_http_test_if_modified(r))
|
||||
if (r->headers_in.if_match
|
||||
&& !ngx_http_test_if_match(r, r->headers_in.if_match))
|
||||
{
|
||||
return ngx_http_filter_finalize_request(r, NULL,
|
||||
NGX_HTTP_PRECONDITION_FAILED);
|
||||
}
|
||||
|
||||
if (r->headers_in.if_modified_since || r->headers_in.if_none_match) {
|
||||
|
||||
if (r->headers_in.if_modified_since
|
||||
&& ngx_http_test_if_modified(r))
|
||||
{
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
if (r->headers_in.if_none_match
|
||||
&& !ngx_http_test_if_match(r, r->headers_in.if_none_match))
|
||||
{
|
||||
return ngx_http_next_header_filter(r);
|
||||
}
|
||||
|
||||
/* not modified */
|
||||
|
||||
r->headers_out.status = NGX_HTTP_NOT_MODIFIED;
|
||||
@ -140,6 +160,76 @@ ngx_http_test_if_modified(ngx_http_request_t *r)
|
||||
}
|
||||
|
||||
|
||||
static ngx_uint_t
|
||||
ngx_http_test_if_match(ngx_http_request_t *r, ngx_table_elt_t *header)
|
||||
{
|
||||
u_char *start, *end, ch;
|
||||
ngx_str_t *etag, *list;
|
||||
|
||||
list = &header->value;
|
||||
|
||||
if (list->len == 1 && list->data[0] == '*') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (r->headers_out.etag == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
etag = &r->headers_out.etag->value;
|
||||
|
||||
ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
|
||||
"http im:\"%V\" etag:%V", list, etag);
|
||||
|
||||
start = list->data;
|
||||
end = list->data + list->len;
|
||||
|
||||
while (start < end) {
|
||||
|
||||
if (etag->len > (size_t) (end - start)) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ngx_strncmp(start, etag->data, etag->len) != 0) {
|
||||
goto skip;
|
||||
}
|
||||
|
||||
start += etag->len;
|
||||
|
||||
while (start < end) {
|
||||
ch = *start;
|
||||
|
||||
if (ch == ' ' || ch == '\t') {
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
if (start == end || *start == ',') {
|
||||
return 1;
|
||||
}
|
||||
|
||||
skip:
|
||||
|
||||
while (start < end && *start != ',') { start++; }
|
||||
while (start < end) {
|
||||
ch = *start;
|
||||
|
||||
if (ch == ' ' || ch == '\t' || ch == ',') {
|
||||
start++;
|
||||
continue;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
static ngx_int_t
|
||||
ngx_http_not_modified_filter_init(ngx_conf_t *cf)
|
||||
{
|
||||
|
@ -93,6 +93,14 @@ ngx_http_header_t ngx_http_headers_in[] = {
|
||||
offsetof(ngx_http_headers_in_t, if_unmodified_since),
|
||||
ngx_http_process_unique_header_line },
|
||||
|
||||
{ ngx_string("If-Match"),
|
||||
offsetof(ngx_http_headers_in_t, if_match),
|
||||
ngx_http_process_unique_header_line },
|
||||
|
||||
{ ngx_string("If-None-Match"),
|
||||
offsetof(ngx_http_headers_in_t, if_none_match),
|
||||
ngx_http_process_unique_header_line },
|
||||
|
||||
{ ngx_string("User-Agent"), offsetof(ngx_http_headers_in_t, user_agent),
|
||||
ngx_http_process_user_agent },
|
||||
|
||||
|
@ -172,6 +172,8 @@ typedef struct {
|
||||
ngx_table_elt_t *connection;
|
||||
ngx_table_elt_t *if_modified_since;
|
||||
ngx_table_elt_t *if_unmodified_since;
|
||||
ngx_table_elt_t *if_match;
|
||||
ngx_table_elt_t *if_none_match;
|
||||
ngx_table_elt_t *user_agent;
|
||||
ngx_table_elt_t *referer;
|
||||
ngx_table_elt_t *content_length;
|
||||
|
Loading…
Reference in New Issue
Block a user