Mercurial > hg > nginx
comparison src/http/modules/proxy/ngx_http_proxy_cache.c @ 174:ea464a6c0581
nginx-0.0.1-2003-11-05-01:12:39 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Tue, 04 Nov 2003 22:12:39 +0000 |
parents | caa57ddf6d77 |
children | e92c2c647c57 |
comparison
equal
deleted
inserted
replaced
173:4fb2a2cff023 | 174:ea464a6c0581 |
---|---|
77 | 77 |
78 if (rc == NGX_OK | 78 if (rc == NGX_OK |
79 || rc == NGX_HTTP_CACHE_STALE | 79 || rc == NGX_HTTP_CACHE_STALE |
80 || rc == NGX_HTTP_CACHE_AGED) | 80 || rc == NGX_HTTP_CACHE_AGED) |
81 { | 81 { |
82 p->header_in->pos += c->ctx.header_size; | 82 p->header_in->pos = p->header_in->start + c->ctx.header_size; |
83 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { | 83 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { |
84 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 84 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
85 } | 85 } |
86 p->header_in->pos = p->header_in->start + c->ctx.header_size; | |
87 p->header_in->last = p->header_in->pos; | |
86 | 88 |
87 } else if (rc == NGX_DECLINED) { | 89 } else if (rc == NGX_DECLINED) { |
88 p->header_in->pos += c->ctx.header_size; | 90 p->header_in->pos = p->header_in->start + c->ctx.header_size; |
89 p->header_in->last = p->header_in->pos; | 91 p->header_in->last = p->header_in->pos; |
90 } | 92 } |
91 | 93 |
92 return rc; | 94 return rc; |
93 } | 95 } |
126 c->status_line.len = p->status_end - p->status_start; | 128 c->status_line.len = p->status_end - p->status_start; |
127 c->status_line.data = ngx_palloc(r->pool, c->status_line.len + 1); | 129 c->status_line.data = ngx_palloc(r->pool, c->status_line.len + 1); |
128 if (c->status_line.data == NULL) { | 130 if (c->status_line.data == NULL) { |
129 return NGX_ERROR; | 131 return NGX_ERROR; |
130 } | 132 } |
133 | |
134 /* reset for the possible parsing the upstream header */ | |
135 | |
136 p->status = 0; | |
137 p->status_count = 0; | |
131 | 138 |
132 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1); | 139 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1); |
133 | 140 |
134 ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ | 141 ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ |
135 c->status _ c->status_line.data); | 142 c->status _ c->status_line.data); |
184 | 191 |
185 /* a whole header has been parsed successfully */ | 192 /* a whole header has been parsed successfully */ |
186 | 193 |
187 ngx_log_debug(r->connection->log, "HTTP header done"); | 194 ngx_log_debug(r->connection->log, "HTTP header done"); |
188 | 195 |
196 c->ctx.file_start = p->header_in->pos - p->header_in->start; | |
197 | |
189 return NGX_OK; | 198 return NGX_OK; |
190 | 199 |
191 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { | 200 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { |
192 | 201 |
193 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 202 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
207 } | 216 } |
208 | 217 |
209 | 218 |
210 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) | 219 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) |
211 { | 220 { |
212 int rc; | 221 int rc, len, i; |
213 ngx_hunk_t *h; | 222 off_t rest; |
214 ngx_chain_t out; | 223 ngx_hunk_t *h0, *h1; |
224 ngx_chain_t out[2]; | |
215 ngx_http_request_t *r; | 225 ngx_http_request_t *r; |
216 | 226 |
217 r = p->request; | 227 r = p->request; |
218 | 228 |
219 r->headers_out.status = p->cache->status; | 229 r->headers_out.status = p->cache->status; |
229 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 239 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
230 } | 240 } |
231 | 241 |
232 /* we need to allocate all before the header would be sent */ | 242 /* we need to allocate all before the header would be sent */ |
233 | 243 |
234 if (!((h = ngx_calloc_hunk(r->pool)))) { | 244 len = p->header_in->end - (p->header_in->start + p->cache->ctx.file_start); |
235 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 245 |
236 } | 246 h0 = NULL; |
237 | 247 h1 = NULL; |
238 if (!((h->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) { | 248 |
239 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 249 if (len) { |
250 if (!((h0 = ngx_calloc_hunk(r->pool)))) { | |
251 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
252 } | |
253 | |
254 if (!((h0->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) { | |
255 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
256 } | |
257 } | |
258 | |
259 if (len < p->cache->ctx.length) { | |
260 if (!((h1 = ngx_calloc_hunk(r->pool)))) { | |
261 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
262 } | |
263 | |
264 if (!((h1->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t))))) { | |
265 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
266 } | |
240 } | 267 } |
241 | 268 |
242 rc = ngx_http_send_header(r); | 269 rc = ngx_http_send_header(r); |
243 | 270 |
244 /* NEEDED ??? */ p->header_sent = 1; | 271 /* NEEDED ??? */ p->header_sent = 1; |
245 | 272 |
246 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { | 273 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { |
247 return rc; | 274 return rc; |
248 } | 275 } |
249 | 276 |
250 /* TODO: part in p->header_in */ | 277 rest = p->cache->ctx.length; |
251 | 278 |
252 h->type = r->main ? NGX_HUNK_FILE : NGX_HUNK_FILE|NGX_HUNK_LAST; | 279 if (len) { |
253 | 280 if (p->valid_header_in) { |
254 h->file_pos = p->header_in->pos - p->header_in->start; | 281 h0->pos = p->header_in->start + p->cache->ctx.file_start; |
255 h->file_last = h->file_pos + p->cache->ctx.header.length; | 282 |
256 | 283 if (len > p->cache->ctx.length) { |
257 h->file->fd = p->cache->ctx.file.fd; | 284 h0->last = h0->pos + p->cache->ctx.length; |
258 h->file->log = r->connection->log; | 285 |
259 | 286 } else { |
260 out.hunk = h; | 287 h0->last = p->header_in->end; |
261 out.next = NULL; | 288 } |
262 | 289 |
263 return ngx_http_output_filter(r, &out); | 290 h0->type = NGX_HUNK_IN_MEMORY|NGX_HUNK_TEMP; |
291 } | |
292 | |
293 h0->type |= NGX_HUNK_FILE; | |
294 h0->file_pos = p->cache->ctx.file_start; | |
295 | |
296 h0->file->fd = p->cache->ctx.file.fd; | |
297 h0->file->log = r->connection->log; | |
298 | |
299 if (len > p->cache->ctx.length) { | |
300 h0->file_last = h0->file_pos + p->cache->ctx.length; | |
301 rest = 0; | |
302 | |
303 } else { | |
304 h0->file_last = h0->file_pos + len; | |
305 rest -= len; | |
306 } | |
307 | |
308 out[0].hunk = h0; | |
309 out[0].next = &out[1]; | |
310 i = 0; | |
311 | |
312 } else { | |
313 i = -1; | |
314 } | |
315 | |
316 if (rest) { | |
317 h1->file_pos = p->cache->ctx.file_start + len; | |
318 h1->file_last = h1->file_pos + rest; | |
319 h1->type = NGX_HUNK_FILE; | |
320 | |
321 h1->file->fd = p->cache->ctx.file.fd; | |
322 h1->file->log = r->connection->log; | |
323 | |
324 out[++i].hunk = h1; | |
325 } | |
326 | |
327 out[i].next = NULL; | |
328 if (!r->main) { | |
329 out[i].hunk->type |= NGX_HUNK_LAST; | |
330 } | |
331 | |
332 return ngx_http_output_filter(r, out); | |
264 } | 333 } |
265 | 334 |
266 | 335 |
267 int ngx_http_proxy_is_cachable(ngx_http_proxy_ctx_t *p) | 336 int ngx_http_proxy_is_cachable(ngx_http_proxy_ctx_t *p) |
268 { | 337 { |
291 date = ngx_http_parse_time(h->date->value.data, h->date->value.len); | 360 date = ngx_http_parse_time(h->date->value.data, h->date->value.len); |
292 } | 361 } |
293 if (date == NGX_ERROR) { | 362 if (date == NGX_ERROR) { |
294 date = ngx_time(); | 363 date = ngx_time(); |
295 } | 364 } |
296 p->cache->ctx.header.date = date; | 365 p->cache->ctx.date = date; |
297 | 366 |
298 last_modified = NGX_ERROR; | 367 last_modified = NGX_ERROR; |
299 if (h->last_modified) { | 368 if (h->last_modified) { |
300 last_modified = ngx_http_parse_time(h->last_modified->value.data, | 369 last_modified = ngx_http_parse_time(h->last_modified->value.data, |
301 h->last_modified->value.len); | 370 h->last_modified->value.len); |
302 p->cache->ctx.header.last_modified = last_modified; | 371 p->cache->ctx.last_modified = last_modified; |
303 } | 372 } |
304 | 373 |
305 if (h->x_accel_expires) { | 374 if (h->x_accel_expires) { |
306 expires = ngx_atoi(h->x_accel_expires->value.data, | 375 expires = ngx_atoi(h->x_accel_expires->value.data, |
307 h->x_accel_expires->value.len); | 376 h->x_accel_expires->value.len); |
308 if (expires != NGX_ERROR) { | 377 if (expires != NGX_ERROR) { |
309 p->state->reason = NGX_HTTP_PROXY_CACHE_XAE; | 378 p->state->reason = NGX_HTTP_PROXY_CACHE_XAE; |
310 p->cache->ctx.header.expires = date + expires; | 379 p->cache->ctx.expires = date + expires; |
311 return (expires > 0); | 380 return (expires > 0); |
312 } | 381 } |
313 } | 382 } |
314 | 383 |
315 if (!p->lcf->ignore_expires) { | 384 if (!p->lcf->ignore_expires) { |
319 if (h->expires) { | 388 if (h->expires) { |
320 expires = ngx_http_parse_time(h->expires->value.data, | 389 expires = ngx_http_parse_time(h->expires->value.data, |
321 h->expires->value.len); | 390 h->expires->value.len); |
322 if (expires != NGX_ERROR) { | 391 if (expires != NGX_ERROR) { |
323 p->state->reason = NGX_HTTP_PROXY_CACHE_EXP; | 392 p->state->reason = NGX_HTTP_PROXY_CACHE_EXP; |
324 p->cache->ctx.header.expires = expires; | 393 p->cache->ctx.expires = expires; |
325 return (date < expires); | 394 return (date < expires); |
326 } | 395 } |
327 } | 396 } |
328 } | 397 } |
329 | 398 |
330 if (p->upstream->status == NGX_HTTP_MOVED_PERMANENTLY) { | 399 if (p->upstream->status == NGX_HTTP_MOVED_PERMANENTLY) { |
331 p->state->reason = NGX_HTTP_PROXY_CACHE_MVD; | 400 p->state->reason = NGX_HTTP_PROXY_CACHE_MVD; |
332 p->cache->ctx.header.expires = /* STUB: 1 hour */ 60 * 60; | 401 p->cache->ctx.expires = /* STUB: 1 hour */ 60 * 60; |
333 return 1; | 402 return 1; |
334 } | 403 } |
335 | 404 |
336 if (p->upstream->status == NGX_HTTP_MOVED_TEMPORARILY) { | 405 if (p->upstream->status == NGX_HTTP_MOVED_TEMPORARILY) { |
337 return 1; | 406 return 1; |
338 } | 407 } |
339 | 408 |
340 if (last_modified != NGX_ERROR && p->lcf->lm_factor > 0) { | 409 if (last_modified != NGX_ERROR && p->lcf->lm_factor > 0) { |
341 | 410 |
342 /* FIXME: time_t == int_64_t */ | 411 /* FIXME: time_t == int_64_t, we can use fpu */ |
343 | 412 |
344 p->state->reason = NGX_HTTP_PROXY_CACHE_LMF; | 413 p->state->reason = NGX_HTTP_PROXY_CACHE_LMF; |
345 p->cache->ctx.header.expires = ngx_time() | 414 p->cache->ctx.expires = ngx_time() |
346 + (((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100; | 415 + (((int64_t) (date - last_modified)) * p->lcf->lm_factor) / 100; |
347 return 1; | 416 return 1; |
348 } | 417 } |
349 | 418 |
350 if (p->lcf->default_expires > 0) { | 419 if (p->lcf->default_expires > 0) { |
351 p->state->reason = NGX_HTTP_PROXY_CACHE_PDE; | 420 p->state->reason = NGX_HTTP_PROXY_CACHE_PDE; |
352 p->cache->ctx.header.expires = p->lcf->default_expires; | 421 p->cache->ctx.expires = p->lcf->default_expires; |
353 return 1; | 422 return 1; |
354 } | 423 } |
355 | 424 |
356 return 0; | 425 return 0; |
357 } | 426 } |