annotate src/http/modules/proxy/ngx_http_proxy_cache.c @ 0:f0b350454894 NGINX_0_1_0

nginx 0.1.0 *) The first public version.
author Igor Sysoev <http://sysoev.ru>
date Mon, 04 Oct 2004 00:00:00 +0400
parents
children 46833bd150cb
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
1
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
2 /*
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
4 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
5
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
6
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
9 #include <ngx_http.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
10 #include <ngx_http_proxy_handler.h>
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
11
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
12
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
13 static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
14 int rc);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
15 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
16 static void ngx_http_proxy_cache_look_complete_request(ngx_http_proxy_ctx_t *p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
17
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
18
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
19 int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
20 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
21 char *last;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
22 ngx_http_request_t *r;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
23 ngx_http_proxy_cache_t *c;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
24 ngx_http_proxy_upstream_conf_t *u;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
25
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
26 r = p->request;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
27
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
28 if (!(c = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_cache_t)))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
29 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
30 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
31
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
32 p->cache = c;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
33
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
34 c->ctx.file.fd = NGX_INVALID_FILE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
35 c->ctx.file.log = r->connection->log;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
36 c->ctx.path = p->lcf->cache_path;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
37
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
38 u = p->lcf->upstream;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
39
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
40 c->ctx.key.len = u->url.len + r->uri.len - u->location->len + r->args.len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
41 if (!(c->ctx.key.data = ngx_palloc(r->pool, c->ctx.key.len + 1))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
42 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
43 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
44
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
45 last = ngx_cpymem(c->ctx.key.data, u->url.data, u->url.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
46
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
47 last = ngx_cpymem(last, r->uri.data + u->location->len,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
48 r->uri.len - u->location->len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
49
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
50 if (r->args.len > 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
51 *(last++) = '?';
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
52 last = ngx_cpymem(last, r->args.data, r->args.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
53 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
54 *last = '\0';
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
55
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
56 p->header_in = ngx_create_temp_hunk(r->pool, p->lcf->header_buffer_size);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
57 if (p->header_in == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
58 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
59 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
60 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
61
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
62 c->ctx.buf = p->header_in;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
63 c->ctx.log = r->connection->log;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
64
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
65 return ngx_http_proxy_process_cached_response(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
66 ngx_http_cache_get_file(r, &c->ctx));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
67 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
68
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
69
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
70 static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
71 int rc)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
72 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
73 if (rc == NGX_OK) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
74 p->state->cache_state = NGX_HTTP_PROXY_CACHE_HIT;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
75 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
76
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
77 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
78 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
79 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
80
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
81 p->valid_header_in = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
82
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
83 return ngx_http_proxy_send_cached_response(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
84 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
85
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
86 if (rc == NGX_HTTP_CACHE_STALE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
87 p->state->cache_state = NGX_HTTP_PROXY_CACHE_EXPR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
88
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
89 } else if (rc == NGX_HTTP_CACHE_AGED) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
90 p->state->cache_state = NGX_HTTP_PROXY_CACHE_AGED;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
91 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
92
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
93 if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
94 p->state->expired = ngx_time() - p->cache->ctx.expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
95 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
96
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
97 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
98 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
99 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
100
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
101 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
102 p->header_in->last = p->header_in->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
103
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
104 p->stale = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
105 p->valid_header_in = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
106
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
107 } else if (rc == NGX_DECLINED) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
108 p->state->cache_state = NGX_HTTP_PROXY_CACHE_MISS;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
109 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
110 p->header_in->last = p->header_in->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
111 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
112
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
113 if (p->lcf->busy_lock) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
114 p->try_busy_lock = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
115
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
116 p->header_in->pos = p->header_in->start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
117 p->header_in->last = p->header_in->start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
118
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
119 p->busy_lock.time = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
120 p->busy_lock.event = p->request->connection->read;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
121 p->busy_lock.event_handler = ngx_http_proxy_busy_lock_handler;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
122 p->busy_lock.md5 = p->cache->ctx.md5;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
123
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
124 ngx_http_proxy_cache_busy_lock(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
125 return NGX_DONE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
126 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
127
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
128 return ngx_http_proxy_request_upstream(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
129 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
130
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
131
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
132 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
133 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
134 int rc, i;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
135 ngx_table_elt_t *h;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
136 ngx_http_request_t *r;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
137 ngx_http_proxy_cache_t *c;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
138
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
139 rc = ngx_http_proxy_parse_status_line(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
140
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
141 c = p->cache;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
142 r = p->request;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
143
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
144 if (rc == NGX_AGAIN) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
145 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
146 "\"proxy_header_buffer_size\" "
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
147 "is too small to read header from \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
148 c->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
149 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
150 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
151
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
152 if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
153 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
154 "no valid HTTP/1.0 header in \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
155 c->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
156 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
157 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
158
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
159 /* rc == NGX_OK */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
160
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
161 c->status = p->status;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
162 c->status_line.len = p->status_end - p->status_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
163 c->status_line.data = ngx_palloc(r->pool, c->status_line.len + 1);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
164 if (c->status_line.data == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
165 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
166 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
167
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
168 /* reset for the possible parsing the upstream header */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
169
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
170 p->status = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
171 p->status_count = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
172
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
173 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
174
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
175 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
176 "http cache status %d \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
177 c->status, c->status_line.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
178
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
179 /* TODO: ngx_init_table */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
180 c->headers_in.headers = ngx_create_table(r->pool, 20);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
181
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
182 for ( ;; ) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
183 rc = ngx_http_parse_header_line(r, p->header_in);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
184
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
185 if (rc == NGX_OK) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
186
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
187 /* a header line has been parsed successfully */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
188
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
189 h = ngx_http_add_header(&c->headers_in, ngx_http_proxy_headers_in);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
190 if (h == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
191 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
192 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
193
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
194 h->key.len = r->header_name_end - r->header_name_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
195 h->value.len = r->header_end - r->header_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
196
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
197 h->key.data = ngx_palloc(r->pool,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
198 h->key.len + 1 + h->value.len + 1);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
199 if (h->key.data == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
200 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
201 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
202
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
203 h->value.data = h->key.data + h->key.len + 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
204 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
205 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
206
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
207 for (i = 0; ngx_http_proxy_headers_in[i].name.len != 0; i++) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
208 if (ngx_http_proxy_headers_in[i].name.len != h->key.len) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
209 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
210 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
211
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
212 if (ngx_strcasecmp(ngx_http_proxy_headers_in[i].name.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
213 h->key.data) == 0)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
214 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
215 *((ngx_table_elt_t **) ((char *) &c->headers_in
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
216 + ngx_http_proxy_headers_in[i].offset)) = h;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
217 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
218 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
219 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
220
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
221 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
222 "http cache header: \"%s: %s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
223 h->key.data, h->value.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
224
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
225 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
226
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
227 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
228
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
229 /* a whole header has been parsed successfully */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
230
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
231 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
232 "http cache header done");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
233
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
234 c->ctx.file_start = p->header_in->pos - p->header_in->start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
235
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
236 return NGX_OK;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
237
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
238 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
239
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
240 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
241 "invalid header in \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
242 c->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
243 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
244 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
245
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
246 /* rc == NGX_AGAIN || rc == NGX_HTTP_PARSE_TOO_LONG_HEADER */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
247
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
248 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
249 "\"proxy_header_buffer_size\" "
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
250 "is too small to read header from \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
251 c->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
252 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
253 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
254 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
255
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
256
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
257 void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
258 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
259 int rc, ft_type;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
260
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
261 rc = ngx_http_busy_lock_cachable(p->lcf->busy_lock, &p->busy_lock,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
262 p->try_busy_lock);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
263
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
264 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, p->request->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
265 "http cache busy lock cachable: %d", rc);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
266
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
267 if (rc == NGX_OK) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
268 if (p->try_busy_lock) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
269 p->busy_locked = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
270 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
271 p->header_in->last = p->header_in->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
272
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
273 ngx_http_proxy_request_upstream(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
274 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
275 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
276
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
277 ngx_http_proxy_cache_look_complete_request(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
278 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
279 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
280
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
281 p->try_busy_lock = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
282
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
283 if (p->cache->ctx.file.fd != NGX_INVALID_FILE
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
284 && !p->cache->ctx.file.info_valid)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
285 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
286 if (ngx_fd_info(p->cache->ctx.file.fd, &p->cache->ctx.file.info)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
287 == NGX_FILE_ERROR)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
288 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
289 ngx_log_error(NGX_LOG_CRIT, p->request->connection->log, ngx_errno,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
290 ngx_fd_info_n " \"%s\" failed",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
291 p->cache->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
292 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
293 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
294 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
295
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
296 p->cache->ctx.file.info_valid = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
297 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
298
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
299 if (rc == NGX_AGAIN) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
300
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
301 if ((ngx_event_flags & (NGX_USE_CLEAR_EVENT|NGX_HAVE_KQUEUE_EVENT))
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
302 && !p->request->connection->write->active)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
303 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
304 /*
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
305 * kqueue allows to detect when client closes prematurely
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
306 * connection
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
307 */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
308
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
309 p->request->connection->write->event_handler =
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
310 ngx_http_proxy_check_broken_connection;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
311
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
312 if (ngx_add_event(p->request->connection->write, NGX_WRITE_EVENT,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
313 NGX_CLEAR_EVENT) == NGX_ERROR)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
314 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
315 ngx_http_proxy_finalize_request(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
316 NGX_HTTP_INTERNAL_SERVER_ERROR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
317 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
318 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
319 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
320
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
321 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
322 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
323
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
324 ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
325
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
326 if (rc == NGX_DONE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
327 ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
328
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
329 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
330 /* rc == NGX_ERROR */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
331 ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
332 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
333
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
334 if (p->stale && (p->lcf->use_stale & ft_type)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
335 ngx_http_proxy_finalize_request(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
336 ngx_http_proxy_send_cached_response(p));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
337 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
338 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
339
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
340 p->state->status = NGX_HTTP_SERVICE_UNAVAILABLE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
341 ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
342 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
343
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
344
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
345 static void ngx_http_proxy_cache_look_complete_request(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
346 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
347 int rc;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
348 ngx_http_cache_ctx_t *ctx;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
349
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
350 if (!(ctx = ngx_pcalloc(p->request->pool, sizeof(ngx_http_cache_ctx_t)))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
351 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
352 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
353 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
354
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
355 *ctx = p->cache->ctx;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
356
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
357 rc = ngx_http_cache_open_file(ctx, ngx_file_uniq(&p->cache->ctx.file.info));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
358
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
359 if (rc == NGX_DECLINED || rc == NGX_HTTP_CACHE_THE_SAME) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
360 p->try_busy_lock = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
361 p->busy_lock.time = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
362 ngx_http_proxy_cache_busy_lock(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
363 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
364 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
365
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
366 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, p->request->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
367 "http cache old fd:%d, new fd:%d",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
368 p->cache->ctx.file.fd, ctx->file.fd);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
369
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
370 if (p->cache->ctx.file.fd != NGX_INVALID_FILE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
371 if (ngx_close_file(p->cache->ctx.file.fd) == NGX_FILE_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
372 ngx_log_error(NGX_LOG_ALERT, p->request->connection->log, ngx_errno,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
373 ngx_close_file_n " \"%s\" failed",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
374 p->cache->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
375 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
376 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
377
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
378 p->cache->ctx = *ctx;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
379
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
380 p->status = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
381 p->status_count = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
382
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
383 ngx_http_proxy_finalize_request(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
384 ngx_http_proxy_process_cached_response(p, rc));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
385 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
386
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
387
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
388 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
389 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
390 int rc, len, i;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
391 off_t rest;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
392 ngx_hunk_t *h0, *h1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
393 ngx_chain_t out[2];
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
394 ngx_http_request_t *r;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
395
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
396 r = p->request;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
397
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
398 r->headers_out.status = p->cache->status;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
399
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
400 #if 0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
401 r->headers_out.content_length_n = -1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
402 r->headers_out.content_length = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
403 #endif
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
404
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
405 /* copy an cached header to r->headers_out */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
406
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
407 if (ngx_http_proxy_copy_header(p, &p->cache->headers_in) == NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
408 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
409 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
410
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
411 /* we need to allocate all before the header would be sent */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
412
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
413 len = p->header_in->end - (p->header_in->start + p->cache->ctx.file_start);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
414
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
415 h0 = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
416 h1 = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
417
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
418 if (len) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
419 if (!((h0 = ngx_calloc_hunk(r->pool)))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
420 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
421 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
422
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
423 if (!((h0->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
424 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
425 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
426 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
427
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
428 if (len < p->cache->ctx.length) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
429 if (!((h1 = ngx_calloc_hunk(r->pool)))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
430 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
431 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
432
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
433 if (!((h1->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
434 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
435 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
436 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
437
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
438 rc = ngx_http_send_header(r);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
439
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
440 /* NEEDED ??? */ p->header_sent = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
441
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
442 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
443 return rc;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
444 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
445
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
446 rest = p->cache->ctx.length;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
447
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
448 if (len) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
449 if (p->valid_header_in) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
450 h0->pos = p->header_in->start + p->cache->ctx.file_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
451
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
452 if (len > p->cache->ctx.length) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
453 h0->last = h0->pos + p->cache->ctx.length;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
454
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
455 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
456 h0->last = p->header_in->end;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
457 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
458
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
459 h0->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
460 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
461
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
462 h0->type |= NGX_HUNK_FILE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
463 h0->file_pos = p->cache->ctx.file_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
464
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
465 h0->file->fd = p->cache->ctx.file.fd;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
466 h0->file->log = r->connection->log;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
467
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
468 if (len > p->cache->ctx.length) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
469 h0->file_last = h0->file_pos + p->cache->ctx.length;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
470 rest = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
471
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
472 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
473 h0->file_last = h0->file_pos + len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
474 rest -= len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
475 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
476
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
477 out[0].hunk = h0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
478 out[0].next = &out[1];
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
479 i = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
480
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
481 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
482 i = -1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
483 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
484
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
485 if (rest) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
486 h1->file_pos = p->cache->ctx.file_start + len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
487 h1->file_last = h1->file_pos + rest;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
488 h1->type = NGX_HUNK_FILE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
489
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
490 h1->file->fd = p->cache->ctx.file.fd;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
491 h1->file->log = r->connection->log;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
492
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
493 out[++i].hunk = h1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
494 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
495
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
496 out[i].next = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
497 if (!r->main) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
498 out[i].hunk->type |= NGX_HUNK_LAST;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
499 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
500
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
501 r->file.fd = p->cache->ctx.file.fd;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
502
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
503 return ngx_http_output_filter(r, out);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
504 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
505
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
506
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
507 int ngx_http_proxy_is_cachable(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
508 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
509 time_t date, last_modified, expires, t;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
510 ngx_http_proxy_headers_in_t *h;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
511
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
512 switch (p->upstream->status) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
513 case NGX_HTTP_OK:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
514 case NGX_HTTP_MOVED_PERMANENTLY:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
515 case NGX_HTTP_MOVED_TEMPORARILY:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
516 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
517
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
518 #if 0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
519 case NGX_HTTP_NOT_MODIFIED:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
520 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
521 #endif
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
522
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
523 default:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
524 return 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
525 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
526
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
527 h = &p->upstream->headers_in;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
528
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
529 date = NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
530 if (h->date) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
531 date = ngx_http_parse_time(h->date->value.data, h->date->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
532 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
533 if (date == NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
534 date = ngx_time();
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
535 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
536 p->cache->ctx.date = date;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
537
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
538 last_modified = NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
539 if (h->last_modified) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
540 last_modified = ngx_http_parse_time(h->last_modified->value.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
541 h->last_modified->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
542 p->cache->ctx.last_modified = last_modified;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
543 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
544
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
545 if (h->x_accel_expires) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
546 expires = ngx_atoi(h->x_accel_expires->value.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
547 h->x_accel_expires->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
548 if (expires != NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
549 p->state->reason = NGX_HTTP_PROXY_CACHE_XAE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
550 p->state->expires = expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
551 p->cache->ctx.expires = date + expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
552 return (expires > 0);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
553 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
554 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
555
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
556 if (!p->lcf->ignore_expires) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
557
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
558 /* TODO: Cache-Control: no-cache, max-age= */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
559
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
560 if (h->expires) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
561 expires = ngx_http_parse_time(h->expires->value.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
562 h->expires->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
563 if (expires != NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
564 p->state->reason = NGX_HTTP_PROXY_CACHE_EXP;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
565 p->state->expires = expires - date;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
566 p->cache->ctx.expires = expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
567 return (date < expires);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
568 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
569 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
570 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
571
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
572 if (p->upstream->status == NGX_HTTP_MOVED_PERMANENTLY) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
573 p->state->reason = NGX_HTTP_PROXY_CACHE_MVD;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
574 p->state->expires = /* STUB: 1 hour */ 60 * 60;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
575 p->cache->ctx.expires = /* STUB: 1 hour */ 60 * 60;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
576 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
577 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
578
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
579 if (p->upstream->status == NGX_HTTP_MOVED_TEMPORARILY) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
580 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
581 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
582
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
583 if (last_modified != NGX_ERROR && p->lcf->lm_factor > 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
584
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
585 /* FIXME: time_t == int_64_t, we can use fpu */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
586
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
587 p->state->reason = NGX_HTTP_PROXY_CACHE_LMF;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
588 t = (time_t)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
589 ((((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
590 p->state->expires = t;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
591 p->cache->ctx.expires = ngx_time() + t;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
592 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
593 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
594
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
595 if (p->lcf->default_expires > 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
596 p->state->reason = NGX_HTTP_PROXY_CACHE_PDE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
597 p->state->expires = p->lcf->default_expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
598 p->cache->ctx.expires = ngx_time() + p->lcf->default_expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
599 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
600 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
601
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
602 return 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
603 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
604
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
605
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
606 int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
607 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
608 ngx_event_pipe_t *ep;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
609
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
610 if (p->cache == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
611 return NGX_OK;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
612 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
613
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
614 ep = p->upstream->event_pipe;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
615
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
616 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, p->request->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
617 "http cache update len: " OFF_T_FMT ":" OFF_T_FMT,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
618 p->cache->ctx.length, ep->read_length);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
619
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
620 if (p->cache->ctx.length == -1) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
621 /* TODO: test rc */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
622 ngx_write_file(&ep->temp_file->file,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
623 (char *) &ep->read_length, sizeof(off_t),
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
624 offsetof(ngx_http_cache_header_t, length));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
625 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
626
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
627 return ngx_http_cache_update_file(p->request, &p->cache->ctx,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
628 &ep->temp_file->file.name);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
629 }