Mercurial > hg > nginx-quic
comparison src/http/ngx_http_cache.c @ 202:74994aeef848
nginx-0.0.1-2003-12-01-19:28:14 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 01 Dec 2003 16:28:14 +0000 |
parents | 267ea1d98683 |
children | c9da5900c79e |
comparison
equal
deleted
inserted
replaced
201:267ea1d98683 | 202:74994aeef848 |
---|---|
1 | 1 |
2 #include <ngx_config.h> | 2 #include <ngx_config.h> |
3 #include <ngx_core.h> | 3 #include <ngx_core.h> |
4 #include <ngx_http.h> | 4 #include <ngx_http.h> |
5 | 5 |
6 | |
7 #include <md5.h> | |
8 | |
9 #if (HAVE_OPENSSL_MD5) | |
10 #define MD5Init MD5_Init | |
11 #define MD5Update MD5_Update | |
12 #define MD5Final MD5_Final | |
13 #endif | |
14 | 6 |
15 | 7 |
16 static ngx_http_module_t ngx_http_cache_module_ctx = { | 8 static ngx_http_module_t ngx_http_cache_module_ctx = { |
17 NULL, /* pre conf */ | 9 NULL, /* pre conf */ |
18 | 10 |
56 && ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0) | 48 && ngx_rstrncmp(c[i].key.data, key->data, key->len) == 0) |
57 { | 49 { |
58 c[i].refs++; | 50 c[i].refs++; |
59 ngx_mutex_unlock(&hash->mutex); | 51 ngx_mutex_unlock(&hash->mutex); |
60 | 52 |
61 if (c[i].notify) { | 53 if ((!(c[i].notify && (ngx_event_flags & NGX_HAVE_KQUEUE_EVENT))) |
62 if (!(ngx_event_flags & NGX_HAVE_KQUEUE_EVENT)) { | 54 && (ngx_cached_time - c[i].updated >= hash->update)) |
63 c[i].valid = 0; | 55 { |
64 } | 56 c[i].expired = 1; |
65 | |
66 } else if (ngx_cached_time - c[i].updated >= hash->update) { | |
67 c[i].valid = 0; | |
68 } | 57 } |
69 | 58 |
70 if (cleanup) { | 59 if (cleanup) { |
71 cleanup->data.cache.hash = hash; | 60 cleanup->data.cache.hash = hash; |
72 cleanup->data.cache.cache = &c[i]; | 61 cleanup->data.cache.cache = &c[i]; |
166 cache->key.len = key->len; | 155 cache->key.len = key->len; |
167 | 156 |
168 cache->refs = 1; | 157 cache->refs = 1; |
169 cache->count = 0; | 158 cache->count = 0; |
170 | 159 |
171 cache->valid = 1; | |
172 cache->deleted = 0; | 160 cache->deleted = 0; |
161 cache->expired = 0; | |
173 cache->memory = 0; | 162 cache->memory = 0; |
174 cache->mmap = 0; | 163 cache->mmap = 0; |
175 cache->notify = 0; | 164 cache->notify = 0; |
176 | 165 |
177 if (cleanup) { | 166 if (cleanup) { |
251 | 240 |
252 ev = &ngx_cycle->read_events[fd]; | 241 ev = &ngx_cycle->read_events[fd]; |
253 ngx_memzero(ev, sizeof(ngx_event_t); | 242 ngx_memzero(ev, sizeof(ngx_event_t); |
254 | 243 |
255 ev->data = data; | 244 ev->data = data; |
256 ev->event_handler = handler; | 245 ev->event_handler = ngx_http_cache_invalidate; |
257 | 246 |
258 return ngx_add_event(ev, NGX_VNODE_EVENT, 0); | 247 return ngx_add_event(ev, NGX_VNODE_EVENT, 0); |
259 } | 248 } |
260 | 249 |
261 | 250 |
276 | 265 |
277 ngx_http_cache_unlock(&ctx->hash->mutex); | 266 ngx_http_cache_unlock(&ctx->hash->mutex); |
278 } | 267 } |
279 | 268 |
280 #endif | 269 #endif |
281 | |
282 | |
283 int ngx_http_cache_get_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx) | |
284 { | |
285 MD5_CTX md5; | |
286 | |
287 /* we use offsetof() because sizeof() pads struct size to int size */ | |
288 ctx->header_size = offsetof(ngx_http_cache_header_t, key) | |
289 + ctx->key.len + 1; | |
290 | |
291 ctx->file.name.len = ctx->path->name.len + 1 + ctx->path->len + 32; | |
292 if (!(ctx->file.name.data = ngx_palloc(r->pool, ctx->file.name.len + 1))) { | |
293 return NGX_ERROR; | |
294 } | |
295 | |
296 ngx_memcpy(ctx->file.name.data, ctx->path->name.data, ctx->path->name.len); | |
297 | |
298 MD5Init(&md5); | |
299 MD5Update(&md5, (u_char *) ctx->key.data, ctx->key.len); | |
300 MD5Final(ctx->md5, &md5); | |
301 | |
302 ngx_md5_text(ctx->file.name.data + ctx->path->name.len + 1 + ctx->path->len, | |
303 ctx->md5); | |
304 | |
305 ngx_log_debug(r->connection->log, "URL: %s, md5: %s" _ ctx->key.data _ | |
306 ctx->file.name.data + ctx->path->name.len + 1 + ctx->path->len); | |
307 | |
308 ngx_create_hashed_filename(&ctx->file, ctx->path); | |
309 | |
310 ngx_log_debug(r->connection->log, "FILE: %s" _ ctx->file.name.data); | |
311 | |
312 /* TODO: look open files cache */ | |
313 | |
314 return ngx_http_cache_open_file(ctx, 0); | |
315 } | |
316 | |
317 | |
318 int ngx_http_cache_open_file(ngx_http_cache_ctx_t *ctx, ngx_file_uniq_t uniq) | |
319 { | |
320 ssize_t n; | |
321 ngx_err_t err; | |
322 ngx_http_cache_header_t *h; | |
323 | |
324 ctx->file.fd = ngx_open_file(ctx->file.name.data, | |
325 NGX_FILE_RDONLY, NGX_FILE_OPEN); | |
326 | |
327 if (ctx->file.fd == NGX_INVALID_FILE) { | |
328 err = ngx_errno; | |
329 | |
330 if (err == NGX_ENOENT || err == NGX_ENOTDIR) { | |
331 return NGX_DECLINED; | |
332 } | |
333 | |
334 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | |
335 ngx_open_file_n " \"%s\" failed", ctx->file.name.data); | |
336 return NGX_ERROR; | |
337 } | |
338 | |
339 if (uniq) { | |
340 if (ngx_fd_info(ctx->file.fd, &ctx->file.info) == NGX_FILE_ERROR) { | |
341 ngx_log_error(NGX_LOG_CRIT, ctx->log, ngx_errno, | |
342 ngx_fd_info_n " \"%s\" failed", ctx->file.name.data); | |
343 | |
344 return NGX_ERROR; | |
345 } | |
346 | |
347 if (ngx_file_uniq(&ctx->file.info) == uniq) { | |
348 if (ngx_close_file(ctx->file.fd) == NGX_FILE_ERROR) { | |
349 ngx_log_error(NGX_LOG_ALERT, ctx->log, ngx_errno, | |
350 ngx_close_file_n " \"%s\" failed", | |
351 ctx->file.name.data); | |
352 } | |
353 | |
354 return NGX_HTTP_CACHE_THE_SAME; | |
355 } | |
356 } | |
357 | |
358 n = ngx_read_file(&ctx->file, ctx->buf->pos, | |
359 ctx->buf->end - ctx->buf->last, 0); | |
360 | |
361 if (n == NGX_ERROR || n == NGX_AGAIN) { | |
362 return n; | |
363 } | |
364 | |
365 if (n <= ctx->header_size) { | |
366 ngx_log_error(NGX_LOG_CRIT, ctx->log, 0, | |
367 "cache file \"%s\" is too small", ctx->file.name.data); | |
368 return NGX_ERROR; | |
369 } | |
370 | |
371 h = (ngx_http_cache_header_t *) ctx->buf->pos; | |
372 ctx->expires = h->expires; | |
373 ctx->last_modified= h->last_modified; | |
374 ctx->date = h->date; | |
375 ctx->length = h->length; | |
376 | |
377 if (h->key_len > (size_t) (ctx->buf->end - ctx->buf->pos)) { | |
378 ngx_log_error(NGX_LOG_ALERT, ctx->log, 0, | |
379 "cache file \"%s\" is probably invalid", | |
380 ctx->file.name.data); | |
381 return NGX_DECLINED; | |
382 } | |
383 | |
384 if (ctx->key.len | |
385 && (h->key_len != ctx->key.len | |
386 || ngx_strncmp(h->key, ctx->key.data, h->key_len) != 0)) | |
387 { | |
388 h->key[h->key_len] = '\0'; | |
389 ngx_log_error(NGX_LOG_ALERT, ctx->log, 0, | |
390 "md5 collision: \"%s\" and \"%s\"", | |
391 h->key, ctx->key.data); | |
392 return NGX_DECLINED; | |
393 } | |
394 | |
395 ctx->buf->last += n; | |
396 | |
397 if (ctx->expires < ngx_time()) { | |
398 ngx_log_debug(ctx->log, "EXPIRED"); | |
399 return NGX_HTTP_CACHE_STALE; | |
400 } | |
401 | |
402 /* TODO: NGX_HTTP_CACHE_AGED */ | |
403 | |
404 return NGX_OK; | |
405 } | |
406 | |
407 | |
408 int ngx_http_cache_update_file(ngx_http_request_t *r, ngx_http_cache_ctx_t *ctx, | |
409 ngx_str_t *temp_file) | |
410 { | |
411 int retry; | |
412 ngx_err_t err; | |
413 | |
414 retry = 0; | |
415 | |
416 for ( ;; ) { | |
417 if (ngx_rename_file(temp_file->data, ctx->file.name.data) == NGX_OK) { | |
418 return NGX_OK; | |
419 } | |
420 | |
421 err = ngx_errno; | |
422 | |
423 #if (WIN32) | |
424 if (err == NGX_EEXIST) { | |
425 if (ngx_win32_rename_file(temp_file, &ctx->file.name, r->pool) | |
426 == NGX_ERROR) | |
427 { | |
428 return NGX_ERROR; | |
429 } | |
430 } | |
431 #endif | |
432 | |
433 if (retry || (err != NGX_ENOENT && err != NGX_ENOTDIR)) { | |
434 ngx_log_error(NGX_LOG_CRIT, r->connection->log, ngx_errno, | |
435 ngx_rename_file_n "(\"%s\", \"%s\") failed", | |
436 temp_file->data, ctx->file.name.data); | |
437 | |
438 return NGX_ERROR; | |
439 } | |
440 | |
441 if (ngx_create_path(&ctx->file, ctx->path) == NGX_ERROR) { | |
442 return NGX_ERROR; | |
443 } | |
444 | |
445 retry = 1; | |
446 } | |
447 } | |
448 | 270 |
449 | 271 |
450 /* TODO: currently fd only */ | 272 /* TODO: currently fd only */ |
451 | 273 |
452 ngx_int_t ngx_http_send_cached(ngx_http_request_t *r) | 274 ngx_int_t ngx_http_send_cached(ngx_http_request_t *r) |
484 } | 306 } |
485 | 307 |
486 h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST; | 308 h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST; |
487 | 309 |
488 h->file_pos = 0; | 310 h->file_pos = 0; |
489 h->file_last = ngx_file_size(&r->file.info); | 311 h->file_last = r->cache->data.size; |
490 | 312 |
491 h->file->fd = r->cache->fd; | 313 h->file->fd = r->cache->fd; |
492 h->file->log = r->connection->log; | 314 h->file->log = r->connection->log; |
493 | 315 |
494 out.hunk = h; | 316 out.hunk = h; |
495 out.next = NULL; | 317 out.next = NULL; |
496 | 318 |
497 return ngx_http_output_filter(r, &out); | 319 return ngx_http_output_filter(r, &out); |
498 } | |
499 | |
500 | |
501 int ngx_garbage_collector_http_cache_handler(ngx_gc_t *gc, ngx_str_t *name, | |
502 ngx_dir_t *dir) | |
503 { | |
504 int rc; | |
505 char data[sizeof(ngx_http_cache_header_t)]; | |
506 ngx_hunk_t buf; | |
507 ngx_http_cache_ctx_t ctx; | |
508 | |
509 ctx.file.fd = NGX_INVALID_FILE; | |
510 ctx.file.name = *name; | |
511 ctx.file.log = gc->log; | |
512 | |
513 ctx.header_size = sizeof(ngx_http_cache_header_t); | |
514 ctx.buf = &buf; | |
515 ctx.log = gc->log; | |
516 ctx.key.len = 0; | |
517 | |
518 buf.type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; | |
519 buf.pos = data; | |
520 buf.last = data; | |
521 buf.start = data; | |
522 buf.end = data + sizeof(ngx_http_cache_header_t); | |
523 | |
524 rc = ngx_http_cache_open_file(&ctx, 0); | |
525 | |
526 /* TODO: NGX_AGAIN */ | |
527 | |
528 if (rc != NGX_ERROR && rc != NGX_DECLINED && rc != NGX_HTTP_CACHE_STALE) { | |
529 return NGX_OK; | |
530 } | |
531 | |
532 if (ngx_delete_file(name->data) == NGX_FILE_ERROR) { | |
533 ngx_log_error(NGX_LOG_CRIT, gc->log, ngx_errno, | |
534 ngx_delete_file_n " \"%s\" failed", name->data); | |
535 return NGX_ERROR; | |
536 } | |
537 | |
538 gc->deleted++; | |
539 gc->freed += ngx_de_size(dir); | |
540 | |
541 return NGX_OK; | |
542 } | 320 } |
543 | 321 |
544 | 322 |
545 char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) | 323 char *ngx_http_set_cache_slot(ngx_conf_t *cf, ngx_command_t *cmd, void *conf) |
546 { | 324 { |