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),