annotate src/http/modules/proxy/ngx_http_proxy_cache.c @ 10:46833bd150cb NGINX_0_1_5

nginx 0.1.5 *) Bugfix: on Solaris and Linux there may be too many "recvmsg() returned not enough data" alerts. *) Bugfix: there were the "writev() failed (22: Invalid argument)" errors on Solaris in proxy mode without sendfile. On other platforms that do not support sendfile at all the process got caught in an endless loop. *) Bugfix: segmentation fault on Solaris in proxy mode and using sendfile. *) Bugfix: segmentation fault on Solaris. *) Bugfix: on-line upgrade did not work on Linux. *) Bugfix: the ngx_http_autoindex_module module did not escape the spaces, the quotes, and the percent signs in the directory listing. *) Change: the decrease of the copy operations. *) Feature: the userid_p3p directive.
author Igor Sysoev <http://sysoev.ru>
date Thu, 11 Nov 2004 00:00:00 +0300
parents f0b350454894
children 6f8b0dc0f8dd
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,
10
46833bd150cb nginx 0.1.5
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
176 "http cache status %ui \"%V\"",
46833bd150cb nginx 0.1.5
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
177 c->status, &c->status_line);
0
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,
10
46833bd150cb nginx 0.1.5
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
222 "http cache header: \"%V: %V\"", &h->key, &h->value);
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
223
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
224 continue;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
225
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
226 } else if (rc == NGX_HTTP_PARSE_HEADER_DONE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
227
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
228 /* a whole header has been parsed successfully */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
229
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
230 ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
231 "http cache header done");
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
232
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
233 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
234
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
235 return NGX_OK;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
236
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
237 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
238
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
239 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
240 "invalid header in \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
241 c->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
242 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
243 }
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 /* rc == NGX_AGAIN || rc == NGX_HTTP_PARSE_TOO_LONG_HEADER */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
246
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
247 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
248 "\"proxy_header_buffer_size\" "
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
249 "is too small to read header from \"%s\"",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
250 c->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
251 return NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
252 }
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 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
257 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
258 int rc, ft_type;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
259
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
260 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
261 p->try_busy_lock);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
262
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
263 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
264 "http cache busy lock cachable: %d", rc);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
265
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
266 if (rc == NGX_OK) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
267 if (p->try_busy_lock) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
268 p->busy_locked = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
269 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
270 p->header_in->last = p->header_in->pos;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
271
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
272 ngx_http_proxy_request_upstream(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
273 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
274 }
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 ngx_http_proxy_cache_look_complete_request(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
277 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
278 }
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 p->try_busy_lock = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
281
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
282 if (p->cache->ctx.file.fd != NGX_INVALID_FILE
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
283 && !p->cache->ctx.file.info_valid)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
284 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
285 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
286 == NGX_FILE_ERROR)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
287 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
288 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
289 ngx_fd_info_n " \"%s\" failed",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
290 p->cache->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
291 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
292 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
293 }
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 p->cache->ctx.file.info_valid = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
296 }
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 if (rc == NGX_AGAIN) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
299
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
300 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
301 && !p->request->connection->write->active)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
302 {
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 * kqueue allows to detect when client closes prematurely
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
305 * connection
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
306 */
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 p->request->connection->write->event_handler =
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
309 ngx_http_proxy_check_broken_connection;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
310
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
311 if (ngx_add_event(p->request->connection->write, NGX_WRITE_EVENT,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
312 NGX_CLEAR_EVENT) == NGX_ERROR)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
313 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
314 ngx_http_proxy_finalize_request(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
315 NGX_HTTP_INTERNAL_SERVER_ERROR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
316 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
317 }
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 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
321 }
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 ngx_http_busy_unlock(p->lcf->busy_lock, &p->busy_lock);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
324
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
325 if (rc == NGX_DONE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
326 ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
327
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
328 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
329 /* rc == NGX_ERROR */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
330 ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
331 }
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 if (p->stale && (p->lcf->use_stale & ft_type)) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
334 ngx_http_proxy_finalize_request(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
335 ngx_http_proxy_send_cached_response(p));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
336 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
337 }
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 p->state->status = NGX_HTTP_SERVICE_UNAVAILABLE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
340 ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
341 }
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 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
345 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
346 int rc;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
347 ngx_http_cache_ctx_t *ctx;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
348
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
349 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
350 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
351 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
352 }
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 *ctx = p->cache->ctx;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
355
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
356 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
357
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
358 if (rc == NGX_DECLINED || rc == NGX_HTTP_CACHE_THE_SAME) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
359 p->try_busy_lock = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
360 p->busy_lock.time = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
361 ngx_http_proxy_cache_busy_lock(p);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
362 return;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
363 }
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 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
366 "http cache old fd:%d, new fd:%d",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
367 p->cache->ctx.file.fd, ctx->file.fd);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
368
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
369 if (p->cache->ctx.file.fd != NGX_INVALID_FILE) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
370 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
371 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
372 ngx_close_file_n " \"%s\" failed",
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
373 p->cache->ctx.file.name.data);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
374 }
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 p->cache->ctx = *ctx;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
378
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
379 p->status = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
380 p->status_count = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
381
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
382 ngx_http_proxy_finalize_request(p,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
383 ngx_http_proxy_process_cached_response(p, rc));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
384 }
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 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
388 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
389 int rc, len, i;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
390 off_t rest;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
391 ngx_hunk_t *h0, *h1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
392 ngx_chain_t out[2];
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
393 ngx_http_request_t *r;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
394
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
395 r = p->request;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
396
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
397 r->headers_out.status = p->cache->status;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
398
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
399 #if 0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
400 r->headers_out.content_length_n = -1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
401 r->headers_out.content_length = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
402 #endif
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
403
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
404 /* copy an cached header to r->headers_out */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
405
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
406 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
407 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
408 }
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 /* we need to allocate all before the header would be sent */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
411
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
412 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
413
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
414 h0 = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
415 h1 = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
416
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
417 if (len) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
418 if (!((h0 = ngx_calloc_hunk(r->pool)))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
419 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
420 }
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 if (!((h0->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
423 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
424 }
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 if (len < p->cache->ctx.length) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
428 if (!((h1 = ngx_calloc_hunk(r->pool)))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
429 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
430 }
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 if (!((h1->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
433 return NGX_HTTP_INTERNAL_SERVER_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
434 }
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 rc = ngx_http_send_header(r);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
438
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
439 /* NEEDED ??? */ p->header_sent = 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
440
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
441 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
442 return rc;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
443 }
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 rest = p->cache->ctx.length;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
446
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
447 if (len) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
448 if (p->valid_header_in) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
449 h0->pos = p->header_in->start + p->cache->ctx.file_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
450
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
451 if (len > p->cache->ctx.length) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
452 h0->last = h0->pos + p->cache->ctx.length;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
453
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
454 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
455 h0->last = p->header_in->end;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
456 }
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 h0->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
459 }
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 h0->type |= NGX_HUNK_FILE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
462 h0->file_pos = p->cache->ctx.file_start;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
463
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
464 h0->file->fd = p->cache->ctx.file.fd;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
465 h0->file->log = r->connection->log;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
466
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
467 if (len > p->cache->ctx.length) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
468 h0->file_last = h0->file_pos + p->cache->ctx.length;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
469 rest = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
470
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
471 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
472 h0->file_last = h0->file_pos + len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
473 rest -= len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
474 }
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 out[0].hunk = h0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
477 out[0].next = &out[1];
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
478 i = 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
479
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
480 } else {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
481 i = -1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
482 }
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 if (rest) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
485 h1->file_pos = p->cache->ctx.file_start + len;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
486 h1->file_last = h1->file_pos + rest;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
487 h1->type = NGX_HUNK_FILE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
488
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
489 h1->file->fd = p->cache->ctx.file.fd;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
490 h1->file->log = r->connection->log;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
491
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
492 out[++i].hunk = h1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
493 }
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 out[i].next = NULL;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
496 if (!r->main) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
497 out[i].hunk->type |= NGX_HUNK_LAST;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
498 }
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 r->file.fd = p->cache->ctx.file.fd;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
501
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
502 return ngx_http_output_filter(r, out);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
503 }
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 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
507 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
508 time_t date, last_modified, expires, t;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
509 ngx_http_proxy_headers_in_t *h;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
510
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
511 switch (p->upstream->status) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
512 case NGX_HTTP_OK:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
513 case NGX_HTTP_MOVED_PERMANENTLY:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
514 case NGX_HTTP_MOVED_TEMPORARILY:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
515 break;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
516
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
517 #if 0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
518 case NGX_HTTP_NOT_MODIFIED:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
519 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
520 #endif
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
521
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
522 default:
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
523 return 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
524 }
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 h = &p->upstream->headers_in;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
527
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
528 date = NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
529 if (h->date) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
530 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
531 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
532 if (date == NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
533 date = ngx_time();
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
534 }
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
535 p->cache->ctx.date = date;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
536
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
537 last_modified = NGX_ERROR;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
538 if (h->last_modified) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
539 last_modified = ngx_http_parse_time(h->last_modified->value.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
540 h->last_modified->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
541 p->cache->ctx.last_modified = last_modified;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
542 }
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 if (h->x_accel_expires) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
545 expires = ngx_atoi(h->x_accel_expires->value.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
546 h->x_accel_expires->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
547 if (expires != NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
548 p->state->reason = NGX_HTTP_PROXY_CACHE_XAE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
549 p->state->expires = expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
550 p->cache->ctx.expires = date + expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
551 return (expires > 0);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
552 }
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 if (!p->lcf->ignore_expires) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
556
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
557 /* TODO: Cache-Control: no-cache, max-age= */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
558
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
559 if (h->expires) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
560 expires = ngx_http_parse_time(h->expires->value.data,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
561 h->expires->value.len);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
562 if (expires != NGX_ERROR) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
563 p->state->reason = NGX_HTTP_PROXY_CACHE_EXP;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
564 p->state->expires = expires - date;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
565 p->cache->ctx.expires = expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
566 return (date < expires);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
567 }
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 if (p->upstream->status == NGX_HTTP_MOVED_PERMANENTLY) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
572 p->state->reason = NGX_HTTP_PROXY_CACHE_MVD;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
573 p->state->expires = /* STUB: 1 hour */ 60 * 60;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
574 p->cache->ctx.expires = /* STUB: 1 hour */ 60 * 60;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
575 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
576 }
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 if (p->upstream->status == NGX_HTTP_MOVED_TEMPORARILY) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
579 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
580 }
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 if (last_modified != NGX_ERROR && p->lcf->lm_factor > 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
583
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
584 /* FIXME: time_t == int_64_t, we can use fpu */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
585
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
586 p->state->reason = NGX_HTTP_PROXY_CACHE_LMF;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
587 t = (time_t)
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
588 ((((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
589 p->state->expires = t;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
590 p->cache->ctx.expires = ngx_time() + t;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
591 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
592 }
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 if (p->lcf->default_expires > 0) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
595 p->state->reason = NGX_HTTP_PROXY_CACHE_PDE;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
596 p->state->expires = p->lcf->default_expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
597 p->cache->ctx.expires = ngx_time() + p->lcf->default_expires;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
598 return 1;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
599 }
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 return 0;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
602 }
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 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
606 {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
607 ngx_event_pipe_t *ep;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
608
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
609 if (p->cache == NULL) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
610 return NGX_OK;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
611 }
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 ep = p->upstream->event_pipe;
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
614
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
615 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, p->request->connection->log, 0,
10
46833bd150cb nginx 0.1.5
Igor Sysoev <http://sysoev.ru>
parents: 0
diff changeset
616 "http cache update len: %O:%O",
0
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
617 p->cache->ctx.length, ep->read_length);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
618
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
619 if (p->cache->ctx.length == -1) {
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
620 /* TODO: test rc */
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
621 ngx_write_file(&ep->temp_file->file,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
622 (char *) &ep->read_length, sizeof(off_t),
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
623 offsetof(ngx_http_cache_header_t, length));
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
624 }
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 return ngx_http_cache_update_file(p->request, &p->cache->ctx,
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
627 &ep->temp_file->file.name);
f0b350454894 nginx 0.1.0
Igor Sysoev <http://sysoev.ru>
parents:
diff changeset
628 }