Mercurial > hg > nginx
comparison src/http/modules/proxy/ngx_http_proxy_cache.c @ 171:aff0e5d32af8
nginx-0.0.1-2003-11-03-20:33:31 import
author | Igor Sysoev <igor@sysoev.ru> |
---|---|
date | Mon, 03 Nov 2003 17:33:31 +0000 |
parents | c42be4185301 |
children | caa57ddf6d77 |
comparison
equal
deleted
inserted
replaced
170:c42be4185301 | 171:aff0e5d32af8 |
---|---|
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_header(ngx_http_proxy_ctx_t *p); | |
9 | |
10 | |
8 int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p) | 11 int ngx_http_proxy_get_cached_response(ngx_http_proxy_ctx_t *p) |
9 { | 12 { |
10 int rc; | 13 int rc; |
11 char *last; | 14 char *last; |
12 ngx_http_request_t *r; | 15 ngx_http_request_t *r; |
13 ngx_http_proxy_cache_t *c; | 16 ngx_http_proxy_cache_t *c; |
14 ngx_http_proxy_upstream_t *u; | 17 ngx_http_proxy_upstream_conf_t *u; |
15 | 18 |
16 r = p->request; | 19 r = p->request; |
17 | 20 |
18 if (!(c = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_cache_t)))) { | 21 if (!(c = ngx_pcalloc(r->pool, sizeof(ngx_http_proxy_cache_t)))) { |
19 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 22 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
20 } | 23 } |
24 | |
25 p->cache = c; | |
21 | 26 |
22 c->ctx.file.fd = NGX_INVALID_FILE; | 27 c->ctx.file.fd = NGX_INVALID_FILE; |
23 c->ctx.file.log = r->connection->log; | 28 c->ctx.file.log = r->connection->log; |
24 c->ctx.path = p->lcf->cache_path; | 29 c->ctx.path = p->lcf->cache_path; |
25 | 30 |
46 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 51 return NGX_HTTP_INTERNAL_SERVER_ERROR; |
47 } | 52 } |
48 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; | 53 p->header_in->tag = (ngx_hunk_tag_t) &ngx_http_proxy_module; |
49 | 54 |
50 c->ctx.buf = p->header_in; | 55 c->ctx.buf = p->header_in; |
51 p->cache = c; | |
52 | 56 |
53 rc = ngx_http_cache_get_file(r, &c->ctx); | 57 rc = ngx_http_cache_get_file(r, &c->ctx); |
54 | 58 |
59 if (rc == NGX_STALE) { | |
60 p->stale = 1; | |
61 } | |
62 | |
55 if (rc == NGX_OK || rc == NGX_STALE) { | 63 if (rc == NGX_OK || rc == NGX_STALE) { |
56 p->header_in->pos += c->ctx.header.size; | 64 p->header_in->pos += c->ctx.header_size; |
65 if (ngx_http_proxy_process_cached_header(p) == NGX_ERROR) { | |
66 return NGX_HTTP_INTERNAL_SERVER_ERROR; | |
67 } | |
57 | 68 |
58 } else if (rc == NGX_DECLINED) { | 69 } else if (rc == NGX_DECLINED) { |
59 p->header_in->pos += c->ctx.header.size; | 70 p->header_in->pos += c->ctx.header_size; |
60 p->header_in->last = p->header_in->pos; | 71 p->header_in->last = p->header_in->pos; |
61 } | 72 } |
62 | 73 |
63 return rc; | 74 return rc; |
64 } | 75 } |
65 | 76 |
66 | 77 |
67 int ngx_http_proxy_process_cached_response(ngx_http_proxy_ctx_t *p) | 78 static int ngx_http_proxy_process_cached_header(ngx_http_proxy_ctx_t *p) |
68 { | 79 { |
69 int rc, i; | 80 int rc, i; |
70 ngx_table_elt_t *h; | 81 ngx_table_elt_t *h; |
71 ngx_http_request_t *r; | 82 ngx_http_request_t *r; |
72 ngx_http_proxy_cache_t *c; | 83 ngx_http_proxy_cache_t *c; |
79 if (rc == NGX_AGAIN) { | 90 if (rc == NGX_AGAIN) { |
80 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 91 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
81 "\"proxy_header_buffer_size\" " | 92 "\"proxy_header_buffer_size\" " |
82 "is too small to read header from \"%s\"", | 93 "is too small to read header from \"%s\"", |
83 c->ctx.file.name.data); | 94 c->ctx.file.name.data); |
84 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 95 return NGX_ERROR; |
85 } | 96 } |
86 | 97 |
87 if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { | 98 if (rc == NGX_HTTP_PROXY_PARSE_NO_HEADER) { |
88 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 99 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
89 "no valid HTTP/1.0 header in \"%s\"", | 100 "no valid HTTP/1.0 header in \"%s\"", |
90 c->ctx.file.name.data); | 101 c->ctx.file.name.data); |
91 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 102 return NGX_ERROR; |
92 } | 103 } |
93 | 104 |
94 /* rc == NGX_OK */ | 105 /* rc == NGX_OK */ |
95 | 106 |
96 c->status = p->status; | 107 c->status = p->status; |
97 c->status_line.len = p->status_end - p->status_start; | 108 c->status_line.len = p->status_end - p->status_start; |
98 c->status_line.data = ngx_palloc(r->pool, c->status_line.len + 1); | 109 c->status_line.data = ngx_palloc(r->pool, c->status_line.len + 1); |
99 if (c->status_line.data == NULL) { | 110 if (c->status_line.data == NULL) { |
100 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 111 return NGX_ERROR; |
101 } | 112 } |
102 | 113 |
103 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1); | 114 ngx_cpystrn(c->status_line.data, p->status_start, c->status_line.len + 1); |
104 | 115 |
105 ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ | 116 ngx_log_debug(r->connection->log, "http cache status %d '%s'" _ |
114 | 125 |
115 /* a header line has been parsed successfully */ | 126 /* a header line has been parsed successfully */ |
116 | 127 |
117 h = ngx_http_add_header(&c->headers_in, ngx_http_proxy_headers_in); | 128 h = ngx_http_add_header(&c->headers_in, ngx_http_proxy_headers_in); |
118 if (h == NULL) { | 129 if (h == NULL) { |
119 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 130 return NGX_ERROR; |
120 } | 131 } |
121 | 132 |
122 h->key.len = r->header_name_end - r->header_name_start; | 133 h->key.len = r->header_name_end - r->header_name_start; |
123 h->value.len = r->header_end - r->header_start; | 134 h->value.len = r->header_end - r->header_start; |
124 | 135 |
125 h->key.data = ngx_palloc(r->pool, | 136 h->key.data = ngx_palloc(r->pool, |
126 h->key.len + 1 + h->value.len + 1); | 137 h->key.len + 1 + h->value.len + 1); |
127 if (h->key.data == NULL) { | 138 if (h->key.data == NULL) { |
128 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 139 return NGX_ERROR; |
129 } | 140 } |
130 | 141 |
131 h->value.data = h->key.data + h->key.len + 1; | 142 h->value.data = h->key.data + h->key.len + 1; |
132 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); | 143 ngx_cpystrn(h->key.data, r->header_name_start, h->key.len + 1); |
133 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); | 144 ngx_cpystrn(h->value.data, r->header_start, h->value.len + 1); |
155 | 166 |
156 /* a whole header has been parsed successfully */ | 167 /* a whole header has been parsed successfully */ |
157 | 168 |
158 ngx_log_debug(r->connection->log, "HTTP header done"); | 169 ngx_log_debug(r->connection->log, "HTTP header done"); |
159 | 170 |
160 return ngx_http_proxy_send_cached_response(p); | 171 return NGX_OK; |
161 | 172 |
162 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { | 173 } else if (rc == NGX_HTTP_PARSE_INVALID_HEADER) { |
163 | 174 |
164 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 175 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
165 "invalid header in \"%s\"", | 176 "invalid header in \"%s\"", |
166 c->ctx.file.name.data); | 177 c->ctx.file.name.data); |
167 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 178 return NGX_ERROR; |
168 } | 179 } |
169 | 180 |
170 /* rc == NGX_AGAIN || rc == NGX_HTTP_PARSE_TOO_LONG_HEADER */ | 181 /* rc == NGX_AGAIN || rc == NGX_HTTP_PARSE_TOO_LONG_HEADER */ |
171 | 182 |
172 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, | 183 ngx_log_error(NGX_LOG_ERR, r->connection->log, 0, |
173 "\"proxy_header_buffer_size\" " | 184 "\"proxy_header_buffer_size\" " |
174 "is too small to read header from \"%s\"", | 185 "is too small to read header from \"%s\"", |
175 c->ctx.file.name.data); | 186 c->ctx.file.name.data); |
176 return NGX_HTTP_INTERNAL_SERVER_ERROR; | 187 return NGX_ERROR; |
177 } | 188 } |
178 } | 189 } |
179 | 190 |
180 | 191 |
181 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) | 192 int ngx_http_proxy_send_cached_response(ngx_http_proxy_ctx_t *p) |
185 ngx_chain_t out; | 196 ngx_chain_t out; |
186 ngx_http_request_t *r; | 197 ngx_http_request_t *r; |
187 | 198 |
188 r = p->request; | 199 r = p->request; |
189 | 200 |
190 r->headers_out.status = p->status; | 201 r->headers_out.status = p->cache->status; |
191 | 202 |
192 #if 0 | 203 #if 0 |
193 r->headers_out.content_length_n = -1; | 204 r->headers_out.content_length_n = -1; |
194 r->headers_out.content_length = NULL; | 205 r->headers_out.content_length = NULL; |
195 #endif | 206 #endif |
231 out.hunk = h; | 242 out.hunk = h; |
232 out.next = NULL; | 243 out.next = NULL; |
233 | 244 |
234 return ngx_http_output_filter(r, &out); | 245 return ngx_http_output_filter(r, &out); |
235 } | 246 } |
247 | |
248 | |
249 int ngx_http_proxy_update_cache(ngx_http_proxy_ctx_t *p) | |
250 { | |
251 if (p->cache == NULL) { | |
252 return NGX_OK; | |
253 } | |
254 | |
255 return ngx_http_cache_update_file(p->request, &p->cache->ctx, | |
256 &p->upstream->event_pipe->temp_file->file.name); | |
257 } |