Mercurial > hg > nginx
comparison src/http/modules/proxy/ngx_http_proxy_cache.c @ 176:c0552e5ab567
nginx-0.0.1-2003-11-09-23:03:38 import; separate building
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Sun, 09 Nov 2003 20:03:38 +0000 |
parents | e92c2c647c57 |
children | 4db54fdbcbe7 |
comparison
equal
deleted
inserted
replaced
175:e92c2c647c57 | 176:c0552e5ab567 |
---|---|
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 #include <ngx_http_proxy_handler.h> | 5 #include <ngx_http_proxy_handler.h> |
6 | 6 |
7 | 7 |
8 static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p, | |
9 int rc); | |
8 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p); | 10 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p); |
11 static void ngx_http_proxy_cache_look_complete_request(ngx_http_proxy_ctx_t *p); | |
9 | 12 |
10 | 13 |
11 int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p) | 14 int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p) |
12 { | 15 { |
13 int rc; | |
14 char *last; | 16 char *last; |
15 ngx_http_request_t *r; | 17 ngx_http_request_t *r; |
16 ngx_http_proxy_cache_t *c; | 18 ngx_http_proxy_cache_t *c; |
17 ngx_http_proxy_upstream_conf_t *u; | 19 ngx_http_proxy_upstream_conf_t *u; |
18 | 20 |
52 } | 54 } |
53 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; | 55 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; |
54 | 56 |
55 c->ctx.buf = p->header_in; | 57 c->ctx.buf = p->header_in; |
56 | 58 |
57 rc = ngx_http_cache_get_file(r, &c->ctx); | 59 return ngx_http_proxy_process_cached_response(p, |
58 | 60 ngx_http_cache_get_file(r, &c->ctx)); |
59 switch (rc) { | 61 } |
60 case NGX_HTTP_CACHE_STALE: | 62 |
61 p->stale = 1; | 63 |
62 p->state->cache = NGX_HTTP_PROXY_CACHE_EXPR; | 64 static int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p, |
63 break; | 65 int rc) |
64 | 66 { |
65 case NGX_HTTP_CACHE_AGED: | 67 if (rc == NGX_OK) { |
66 p->stale = 1; | 68 p->state->cache_state = NGX_HTTP_PROXY_CACHE_HIT; |
67 p->state->cache = NGX_HTTP_PROXY_CACHE_AGED; | 69 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; |
68 break; | 70 |
69 | |
70 case NGX_OK: | |
71 p->state->cache = NGX_HTTP_PROXY_CACHE_HIT; | |
72 break; | |
73 | |
74 default: | |
75 p->state->cache = NGX_HTTP_PROXY_CACHE_MISS; | |
76 } | |
77 | |
78 if (rc == NGX_OK | |
79 || rc == NGX_HTTP_CACHE_STALE | |
80 || rc == NGX_HTTP_CACHE_AGED) | |
81 { | |
82 p->header_in->pos = p->header_in->start + c->ctx.header_size; | |
83 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { | 71 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { |
84 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 72 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
85 } | 73 } |
86 p->header_in->pos = p->header_in->start + c->ctx.header_size; | 74 |
75 p->valid_header_in = 1; | |
76 | |
77 return ngx_http_proxy_send_cached_response(p); | |
78 } | |
79 | |
80 if (rc == NGX_HTTP_CACHE_STALE) { | |
81 p->state->cache_state = NGX_HTTP_PROXY_CACHE_EXPR; | |
82 | |
83 } else if (rc == NGX_HTTP_CACHE_AGED) { | |
84 p->state->cache_state = NGX_HTTP_PROXY_CACHE_AGED; | |
85 } | |
86 | |
87 if (rc == NGX_HTTP_CACHE_STALE || rc == NGX_HTTP_CACHE_AGED) { | |
88 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; | |
89 | |
90 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { | |
91 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
92 } | |
93 | |
94 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; | |
87 p->header_in->last = p->header_in->pos; | 95 p->header_in->last = p->header_in->pos; |
88 | 96 |
97 p->stale = 1; | |
98 p->valid_header_in = 1; | |
99 | |
89 } else if (rc == NGX_DECLINED) { | 100 } else if (rc == NGX_DECLINED) { |
90 p->header_in->pos = p->header_in->start + c->ctx.header_size; | 101 p->state->cache_state = NGX_HTTP_PROXY_CACHE_MISS; |
102 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; | |
91 p->header_in->last = p->header_in->pos; | 103 p->header_in->last = p->header_in->pos; |
92 } | 104 } |
93 | 105 |
94 return rc; | 106 if (p->lcf->busy_lock) { |
107 p->try_busy_lock = 1; | |
108 | |
109 p->header_in->pos = p->header_in->start; | |
110 p->header_in->last = p->header_in->start; | |
111 | |
112 p->busy_lock.time = 0; | |
113 p->busy_lock.event = p->request->connection->read; | |
114 p->busy_lock.event_handler = ngx_http_proxy_busy_lock_handler; | |
115 p->busy_lock.md5 = p->cache->ctx.md5; | |
116 | |
117 ngx_http_proxy_cache_busy_lock(p); | |
118 return NGX_DONE; | |
119 } | |
120 | |
121 return ngx_http_proxy_request_upstream(p); | |
95 } | 122 } |
96 | 123 |
97 | 124 |
98 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p) | 125 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p) |
99 { | 126 { |
139 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1); | 166 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1); |
140 | 167 |
141 ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ | 168 ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ |
142 c->status _ c->status_line.data); | 169 c->status _ c->status_line.data); |
143 | 170 |
171 /* TODO: ngx_init_table */ | |
144 c->headers_in.headers = ngx_create_table(r->pool, 20); | 172 c->headers_in.headers = ngx_create_table(r->pool, 20); |
145 | 173 |
146 for ( ;; ) { | 174 for ( ;; ) { |
147 rc = ngx_http_parse_header_line(r, p->header_in); | 175 rc = ngx_http_parse_header_line(r, p->header_in); |
148 | 176 |
214 return NGX_ERROR; | 242 return NGX_ERROR; |
215 } | 243 } |
216 } | 244 } |
217 | 245 |
218 | 246 |
219 #if 0 | 247 void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p) |
220 | 248 { |
221 static void ngx_http_proxy_cache_busy_lock(ngx_http_proxy_ctx_t *p) | 249 int rc, ft_type; |
222 { | 250 |
223 rc = ngx_http_busy_lock(p->lcf->busy_lock, p->cache->ctx.md5); | 251 rc = ngx_http_busy_lock_cachable(p->lcf->busy_lock, &p->busy_lock, |
252 p->try_busy_lock); | |
224 | 253 |
225 if (rc == NGX_OK) { | 254 if (rc == NGX_OK) { |
226 ngx_http_proxy_request_upstream(p); | 255 if (p->try_busy_lock) { |
227 } | 256 p->busy_locked = 1; |
257 p->header_in->pos = p->header_in->start + p->cache->ctx.header_size; | |
258 p->header_in->last = p->header_in->pos; | |
259 | |
260 ngx_http_proxy_request_upstream(p); | |
261 return; | |
262 } | |
263 | |
264 ngx_http_proxy_cache_look_complete_request(p); | |
265 return; | |
266 } | |
267 | |
268 p->try_busy_lock = 0; | |
269 | |
270 if (p->cache->ctx.file.fd != NGX_INVALID_FILE | |
271 && !p->cache->ctx.file.info_valid) | |
272 { | |
273 if (ngx_stat_fd(p->cache->ctx.file.fd, &p->cache->ctx.file.info) | |
274 == NGX_FILE_ERROR) | |
275 { | |
276 ngx_log_error(NGX_LOG_CRIT, p->request->connection->log, ngx_errno, | |
277 ngx_stat_fd_n " \"%s\" failed", | |
278 p->cache->ctx.file.name.data); | |
279 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
280 return; | |
281 } | |
282 | |
283 p->cache->ctx.file.info_valid = 1; | |
284 } | |
285 | |
228 | 286 |
229 if (rc == NGX_AGAIN) { | 287 if (rc == NGX_AGAIN) { |
230 if (p->busy_lock_time) { | 288 return; |
231 ngx_add_timer(p->request->connection->read, 1000); | 289 } |
232 return; | 290 |
233 } | 291 if (rc == NGX_DONE) { |
234 } | 292 ft_type = NGX_HTTP_PROXY_FT_BUSY_LOCK; |
235 | 293 |
236 rc == NGX_ERROR | 294 } else { |
237 check waitn | 295 /* rc == NGX_ERROR */ |
238 } | 296 ft_type = NGX_HTTP_PROXY_FT_MAX_WAITING; |
239 | 297 } |
240 #endif | 298 |
299 if (p->stale && (p->lcf->use_stale & ft_type)) { | |
300 ngx_http_proxy_finalize_request(p, | |
301 ngx_http_proxy_send_cached_response(p)); | |
302 return; | |
303 } | |
304 | |
305 ngx_http_proxy_finalize_request(p, NGX_HTTP_SERVICE_UNAVAILABLE); | |
306 } | |
307 | |
308 | |
309 static void ngx_http_proxy_cache_look_complete_request(ngx_http_proxy_ctx_t *p) | |
310 { | |
311 int rc; | |
312 ngx_http_cache_ctx_t *ctx; | |
313 | |
314 if (!(ctx = ngx_pcalloc(p->request->pool, sizeof(ngx_http_cache_ctx_t)))) { | |
315 ngx_http_proxy_finalize_request(p, NGX_HTTP_INTERNAL_SERVER_ERROR); | |
316 return; | |
317 } | |
318 | |
319 *ctx = p->cache->ctx; | |
320 | |
321 rc = ngx_http_cache_open_file(p->request, ctx, | |
322 ngx_file_uniq(p->cache->ctx.file.info)); | |
323 | |
324 if (rc == NGX_HTTP_CACHE_THE_SAME) { | |
325 p->try_busy_lock = 1; | |
326 p->busy_lock.time = 0; | |
327 ngx_http_proxy_cache_busy_lock(p); | |
328 return; | |
329 } | |
330 | |
331 ngx_log_debug(p->request->connection->log, "OLD: %d, NEW: %d" _ | |
332 p->cache->ctx.file.fd _ ctx->file.fd); | |
333 | |
334 if (p->cache->ctx.file.fd != NGX_INVALID_FILE) { | |
335 if (ngx_close_file(p->cache->ctx.file.fd) == NGX_FILE_ERROR) { | |
336 ngx_log_error(NGX_LOG_ALERT, p->request->connection->log, ngx_errno, | |
337 ngx_close_file_n " \"%s\" failed", | |
338 p->cache->ctx.file.name.data); | |
339 } | |
340 } | |
341 | |
342 p->cache->ctx = *ctx; | |
343 | |
344 p->status = 0; | |
345 p->status_count = 0; | |
346 | |
347 ngx_http_proxy_finalize_request(p, | |
348 ngx_http_proxy_process_cached_response(p, rc)); | |
349 } | |
241 | 350 |
242 | 351 |
243 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) | 352 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) |
244 { | 353 { |
245 int rc, len, i; | 354 int rc, len, i; |
433 if (last_modified != NGX_ERROR && p->lcf->lm_factor > 0) { | 542 if (last_modified != NGX_ERROR && p->lcf->lm_factor > 0) { |
434 | 543 |
435 /* FIXME: time_t == int_64_t, we can use fpu */ | 544 /* FIXME: time_t == int_64_t, we can use fpu */ |
436 | 545 |
437 p->state->reason = NGX_HTTP_PROXY_CACHE_LMF; | 546 p->state->reason = NGX_HTTP_PROXY_CACHE_LMF; |
438 p->cache->ctx.expires = ngx_time() | 547 p->cache->ctx.expires = (time_t) (ngx_time() |
439 + (((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100; | 548 + (((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100); |
440 return 1; | 549 return 1; |
441 } | 550 } |
442 | 551 |
443 if (p->lcf->default_expires > 0) { | 552 if (p->lcf->default_expires > 0) { |
444 p->state->reason = NGX_HTTP_PROXY_CACHE_PDE; | 553 p->state->reason = NGX_HTTP_PROXY_CACHE_PDE; |
457 if (p->cache == NULL) { | 566 if (p->cache == NULL) { |
458 return NGX_OK; | 567 return NGX_OK; |
459 } | 568 } |
460 | 569 |
461 ep = p->upstream->event_pipe; | 570 ep = p->upstream->event_pipe; |
571 | |
572 ngx_log_debug(p->request->connection->log, "LEN: " OFF_FMT ", " OFF_FMT _ | |
573 p->cache->ctx.length _ ep->read_length); | |
462 | 574 |
463 if (p->cache->ctx.length == -1) { | 575 if (p->cache->ctx.length == -1) { |
464 /* TODO: test rc */ | 576 /* TODO: test rc */ |
465 ngx_write_file(&ep->temp_file->file, | 577 ngx_write_file(&ep->temp_file->file, |
466 (char *) &ep->read_length, sizeof(off_t), | 578 (char *) &ep->read_length, sizeof(off_t), |