Mercurial > hg > nginx-ranges
comparison src/http/ngx_http_copy_filter_module.c @ 539:5f4de8cf0d9d
Merge with current.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Tue, 15 Sep 2009 03:43:40 +0400 |
parents | 0161f3197817 |
children | 2b9e388c61f1 |
comparison
equal
deleted
inserted
replaced
522:40fd8d7b82f9 | 539:5f4de8cf0d9d |
---|---|
11 | 11 |
12 typedef struct { | 12 typedef struct { |
13 ngx_bufs_t bufs; | 13 ngx_bufs_t bufs; |
14 } ngx_http_copy_filter_conf_t; | 14 } ngx_http_copy_filter_conf_t; |
15 | 15 |
16 | |
17 #if (NGX_HAVE_FILE_AIO) | |
18 static void ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, | |
19 ngx_file_t *file); | |
20 static void ngx_http_copy_aio_event_handler(ngx_event_t *ev); | |
21 #if (NGX_HAVE_AIO_SENDFILE) | |
22 static void ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev); | |
23 #endif | |
24 #endif | |
16 | 25 |
17 static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf); | 26 static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf); |
18 static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, | 27 static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, |
19 void *parent, void *child); | 28 void *parent, void *child); |
20 static ngx_int_t ngx_http_copy_filter_init(ngx_conf_t *cf); | 29 static ngx_int_t ngx_http_copy_filter_init(ngx_conf_t *cf); |
71 ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in) | 80 ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in) |
72 { | 81 { |
73 ngx_int_t rc; | 82 ngx_int_t rc; |
74 ngx_connection_t *c; | 83 ngx_connection_t *c; |
75 ngx_output_chain_ctx_t *ctx; | 84 ngx_output_chain_ctx_t *ctx; |
85 ngx_http_core_loc_conf_t *clcf; | |
76 ngx_http_copy_filter_conf_t *conf; | 86 ngx_http_copy_filter_conf_t *conf; |
77 | 87 |
78 c = r->connection; | 88 c = r->connection; |
79 | 89 |
80 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, | 90 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0, |
81 "copy filter: \"%V?%V\"", &r->uri, &r->args); | 91 "http copy filter: \"%V?%V\"", &r->uri, &r->args); |
82 | 92 |
83 ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); | 93 ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module); |
84 | 94 |
85 if (ctx == NULL) { | 95 if (ctx == NULL) { |
86 conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module); | |
87 | |
88 ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); | 96 ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t)); |
89 if (ctx == NULL) { | 97 if (ctx == NULL) { |
90 return NGX_ERROR; | 98 return NGX_ERROR; |
91 } | 99 } |
92 | 100 |
93 ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module); | 101 ngx_http_set_ctx(r, ctx, ngx_http_copy_filter_module); |
102 | |
103 conf = ngx_http_get_module_loc_conf(r, ngx_http_copy_filter_module); | |
104 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); | |
94 | 105 |
95 ctx->sendfile = c->sendfile; | 106 ctx->sendfile = c->sendfile; |
96 ctx->need_in_memory = r->main_filter_need_in_memory | 107 ctx->need_in_memory = r->main_filter_need_in_memory |
97 || r->filter_need_in_memory; | 108 || r->filter_need_in_memory; |
98 ctx->need_in_temp = r->filter_need_temporary; | 109 ctx->need_in_temp = r->filter_need_temporary; |
99 | 110 |
111 ctx->alignment = clcf->directio_alignment; | |
112 | |
100 ctx->pool = r->pool; | 113 ctx->pool = r->pool; |
101 ctx->bufs = conf->bufs; | 114 ctx->bufs = conf->bufs; |
102 ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module; | 115 ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module; |
103 | 116 |
104 ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter; | 117 ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter; |
105 ctx->filter_ctx = r; | 118 ctx->filter_ctx = r; |
106 | 119 |
120 #if (NGX_HAVE_FILE_AIO) | |
121 if (clcf->aio) { | |
122 ctx->aio_handler = ngx_http_copy_aio_handler; | |
123 #if (NGX_HAVE_AIO_SENDFILE) | |
124 c->aio_sendfile = (clcf->aio == NGX_HTTP_AIO_SENDFILE); | |
125 #endif | |
126 } | |
127 #endif | |
128 | |
107 r->request_output = 1; | 129 r->request_output = 1; |
108 } | 130 } |
109 | 131 |
110 rc = ngx_output_chain(ctx, in); | 132 #if (NGX_HAVE_FILE_AIO) |
111 | 133 ctx->aio = r->aio; |
112 if (!c->destroyed) { | 134 #endif |
135 | |
136 for ( ;; ) { | |
137 rc = ngx_output_chain(ctx, in); | |
113 | 138 |
114 if (ctx->in == NULL) { | 139 if (ctx->in == NULL) { |
115 r->buffered &= ~NGX_HTTP_COPY_BUFFERED; | 140 r->buffered &= ~NGX_HTTP_COPY_BUFFERED; |
141 | |
116 } else { | 142 } else { |
117 r->buffered |= NGX_HTTP_COPY_BUFFERED; | 143 r->buffered |= NGX_HTTP_COPY_BUFFERED; |
118 } | 144 } |
119 | 145 |
120 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | 146 ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0, |
121 "copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args); | 147 "http copy filter: %i \"%V?%V\"", rc, &r->uri, &r->args); |
148 | |
149 #if (NGX_HAVE_FILE_AIO && NGX_HAVE_AIO_SENDFILE) | |
150 | |
151 if (c->busy_sendfile) { | |
152 ssize_t n; | |
153 off_t offset; | |
154 ngx_file_t *file; | |
155 ngx_http_ephemeral_t *e; | |
156 | |
157 file = c->busy_sendfile->file; | |
158 offset = c->busy_sendfile->file_pos; | |
159 | |
160 if (file->aio) { | |
161 c->aio_sendfile = (offset != file->aio->last_offset); | |
162 file->aio->last_offset = offset; | |
163 | |
164 if (c->aio_sendfile == 0) { | |
165 ngx_log_error(NGX_LOG_ALERT, c->log, 0, | |
166 "sendfile(%V) returned busy again", | |
167 &file->name); | |
168 } | |
169 } | |
170 | |
171 c->busy_sendfile = NULL; | |
172 e = (ngx_http_ephemeral_t *) &r->uri_start; | |
173 | |
174 n = ngx_file_aio_read(file, &e->aio_preload, 1, offset, r->pool); | |
175 | |
176 if (n > 0) { | |
177 in = NULL; | |
178 continue; | |
179 } | |
180 | |
181 rc = n; | |
182 | |
183 if (file->aio) { | |
184 file->aio->data = r; | |
185 file->aio->handler = ngx_http_copy_aio_sendfile_event_handler; | |
186 | |
187 r->main->blocked++; | |
188 r->aio = 1; | |
189 } | |
190 } | |
191 #endif | |
192 | |
193 return rc; | |
122 } | 194 } |
123 | 195 } |
124 return rc; | 196 |
125 } | 197 |
198 #if (NGX_HAVE_FILE_AIO) | |
199 | |
200 static void | |
201 ngx_http_copy_aio_handler(ngx_output_chain_ctx_t *ctx, ngx_file_t *file) | |
202 { | |
203 ngx_http_request_t *r; | |
204 | |
205 r = ctx->filter_ctx; | |
206 | |
207 file->aio->data = r; | |
208 file->aio->handler = ngx_http_copy_aio_event_handler; | |
209 | |
210 r->main->blocked++; | |
211 r->aio = 1; | |
212 } | |
213 | |
214 | |
215 static void | |
216 ngx_http_copy_aio_event_handler(ngx_event_t *ev) | |
217 { | |
218 ngx_event_aio_t *aio; | |
219 ngx_http_request_t *r; | |
220 | |
221 aio = ev->data; | |
222 r = aio->data; | |
223 | |
224 r->main->blocked--; | |
225 r->aio = 0; | |
226 | |
227 r->connection->write->handler(r->connection->write); | |
228 } | |
229 | |
230 | |
231 #if (NGX_HAVE_AIO_SENDFILE) | |
232 | |
233 static void | |
234 ngx_http_copy_aio_sendfile_event_handler(ngx_event_t *ev) | |
235 { | |
236 ngx_event_aio_t *aio; | |
237 ngx_http_request_t *r; | |
238 | |
239 aio = ev->data; | |
240 r = aio->data; | |
241 | |
242 r->main->blocked--; | |
243 r->aio = 0; | |
244 ev->complete = 0; | |
245 | |
246 r->connection->write->handler(r->connection->write); | |
247 } | |
248 | |
249 #endif | |
250 #endif | |
126 | 251 |
127 | 252 |
128 static void * | 253 static void * |
129 ngx_http_copy_filter_create_conf(ngx_conf_t *cf) | 254 ngx_http_copy_filter_create_conf(ngx_conf_t *cf) |
130 { | 255 { |