~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

Linux Cross Reference
Nginx/http/ngx_http_copy_filter_module.c

Version: ~ [ nginx-0.8.20 ] ~ [ nginx-0.7.62 ] ~ [ nginx-0.6.39 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 
  7 #include <ngx_config.h>
  8 #include <ngx_core.h>
  9 #include <ngx_http.h>
 10 
 11 
 12 typedef struct {
 13     ngx_bufs_t  bufs;
 14 } ngx_http_copy_filter_conf_t;
 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
 25 
 26 static void *ngx_http_copy_filter_create_conf(ngx_conf_t *cf);
 27 static char *ngx_http_copy_filter_merge_conf(ngx_conf_t *cf,
 28     void *parent, void *child);
 29 static ngx_int_t ngx_http_copy_filter_init(ngx_conf_t *cf);
 30 
 31 
 32 static ngx_command_t  ngx_http_copy_filter_commands[] = {
 33 
 34     { ngx_string("output_buffers"),
 35       NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_TAKE2,
 36       ngx_conf_set_bufs_slot,
 37       NGX_HTTP_LOC_CONF_OFFSET,
 38       offsetof(ngx_http_copy_filter_conf_t, bufs),
 39       NULL },
 40 
 41       ngx_null_command
 42 };
 43 
 44 
 45 static ngx_http_module_t  ngx_http_copy_filter_module_ctx = {
 46     NULL,                                  /* preconfiguration */
 47     ngx_http_copy_filter_init,             /* postconfiguration */
 48 
 49     NULL,                                  /* create main configuration */
 50     NULL,                                  /* init main configuration */
 51 
 52     NULL,                                  /* create server configuration */
 53     NULL,                                  /* merge server configuration */
 54 
 55     ngx_http_copy_filter_create_conf,      /* create location configuration */
 56     ngx_http_copy_filter_merge_conf        /* merge location configuration */
 57 };
 58 
 59 
 60 ngx_module_t  ngx_http_copy_filter_module = {
 61     NGX_MODULE_V1,
 62     &ngx_http_copy_filter_module_ctx,      /* module context */
 63     ngx_http_copy_filter_commands,         /* module directives */
 64     NGX_HTTP_MODULE,                       /* module type */
 65     NULL,                                  /* init master */
 66     NULL,                                  /* init module */
 67     NULL,                                  /* init process */
 68     NULL,                                  /* init thread */
 69     NULL,                                  /* exit thread */
 70     NULL,                                  /* exit process */
 71     NULL,                                  /* exit master */
 72     NGX_MODULE_V1_PADDING
 73 };
 74 
 75 
 76 static ngx_http_output_body_filter_pt    ngx_http_next_filter;
 77 
 78 
 79 static ngx_int_t
 80 ngx_http_copy_filter(ngx_http_request_t *r, ngx_chain_t *in)
 81 {
 82     ngx_int_t                     rc;
 83     ngx_connection_t             *c;
 84     ngx_output_chain_ctx_t       *ctx;
 85     ngx_http_core_loc_conf_t     *clcf;
 86     ngx_http_copy_filter_conf_t  *conf;
 87 
 88     c = r->connection;
 89 
 90     ngx_log_debug2(NGX_LOG_DEBUG_HTTP, c->log, 0,
 91                    "http copy filter: \"%V?%V\"", &r->uri, &r->args);
 92 
 93     ctx = ngx_http_get_module_ctx(r, ngx_http_copy_filter_module);
 94 
 95     if (ctx == NULL) {
 96         ctx = ngx_pcalloc(r->pool, sizeof(ngx_output_chain_ctx_t));
 97         if (ctx == NULL) {
 98             return NGX_ERROR;
 99         }
100 
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);
105 
106         ctx->sendfile = c->sendfile;
107         ctx->need_in_memory = r->main_filter_need_in_memory
108                               || r->filter_need_in_memory;
109         ctx->need_in_temp = r->filter_need_temporary;
110 
111         ctx->alignment = clcf->directio_alignment;
112 
113         ctx->pool = r->pool;
114         ctx->bufs = conf->bufs;
115         ctx->tag = (ngx_buf_tag_t) &ngx_http_copy_filter_module;
116 
117         ctx->output_filter = (ngx_output_chain_filter_pt) ngx_http_next_filter;
118         ctx->filter_ctx = r;
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 
129         r->request_output = 1;
130     }
131 
132 #if (NGX_HAVE_FILE_AIO)
133     ctx->aio = r->aio;
134 #endif
135 
136     for ( ;; ) {
137         rc = ngx_output_chain(ctx, in);
138 
139         if (ctx->in == NULL) {
140             r->buffered &= ~NGX_HTTP_COPY_BUFFERED;
141 
142         } else {
143             r->buffered |= NGX_HTTP_COPY_BUFFERED;
144         }
145 
146         ngx_log_debug3(NGX_LOG_DEBUG_HTTP, c->log, 0,
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;
194     }
195 }
196 
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
251 
252 
253 static void *
254 ngx_http_copy_filter_create_conf(ngx_conf_t *cf)
255 {
256     ngx_http_copy_filter_conf_t *conf;
257 
258     conf = ngx_palloc(cf->pool, sizeof(ngx_http_copy_filter_conf_t));
259     if (conf == NULL) {
260         return NULL;
261     }
262 
263     conf->bufs.num = 0;
264 
265     return conf;
266 }
267 
268 
269 static char *
270 ngx_http_copy_filter_merge_conf(ngx_conf_t *cf, void *parent, void *child)
271 {
272     ngx_http_copy_filter_conf_t *prev = parent;
273     ngx_http_copy_filter_conf_t *conf = child;
274 
275     ngx_conf_merge_bufs_value(conf->bufs, prev->bufs, 1, 32768);
276 
277     return NULL;
278 }
279 
280 
281 static ngx_int_t
282 ngx_http_copy_filter_init(ngx_conf_t *cf)
283 {
284     ngx_http_next_filter = ngx_http_top_body_filter;
285     ngx_http_top_body_filter = ngx_http_copy_filter;
286 
287     return NGX_OK;
288 }
289 
290 

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~ [ freetext search ] ~ [ file search ] ~

This page was automatically generated by the LXR engine.
Visit the LXR main site for more information.