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 }