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

Linux Cross Reference
Nginx/http/modules/ngx_http_flv_module.c

Version: ~ [ nginx-1.0.11 ] ~ [ nginx-1.1.12 ] ~

  1 
  2 /*
  3  * Copyright (C) Igor Sysoev
  4  */
  5 
  6 #include <ngx_config.h>
  7 #include <ngx_core.h>
  8 #include <ngx_http.h>
  9 
 10 
 11 static char *ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
 12 
 13 static ngx_command_t  ngx_http_flv_commands[] = {
 14 
 15     { ngx_string("flv"),
 16       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
 17       ngx_http_flv,
 18       0,
 19       0,
 20       NULL },
 21 
 22       ngx_null_command
 23 };
 24 
 25 
 26 static u_char  ngx_flv_header[] = "FLV\x1\x5\0\0\0\x9\0\0\0\0";
 27 
 28 
 29 static ngx_http_module_t  ngx_http_flv_module_ctx = {
 30     NULL,                          /* preconfiguration */
 31     NULL,                          /* postconfiguration */
 32 
 33     NULL,                          /* create main configuration */
 34     NULL,                          /* init main configuration */
 35 
 36     NULL,                          /* create server configuration */
 37     NULL,                          /* merge server configuration */
 38 
 39     NULL,                          /* create location configuration */
 40     NULL                           /* merge location configuration */
 41 };
 42 
 43 
 44 ngx_module_t  ngx_http_flv_module = {
 45     NGX_MODULE_V1,
 46     &ngx_http_flv_module_ctx,      /* module context */
 47     ngx_http_flv_commands,         /* module directives */
 48     NGX_HTTP_MODULE,               /* module type */
 49     NULL,                          /* init master */
 50     NULL,                          /* init module */
 51     NULL,                          /* init process */
 52     NULL,                          /* init thread */
 53     NULL,                          /* exit thread */
 54     NULL,                          /* exit process */
 55     NULL,                          /* exit master */
 56     NGX_MODULE_V1_PADDING
 57 };
 58 
 59 
 60 static ngx_int_t
 61 ngx_http_flv_handler(ngx_http_request_t *r)
 62 {
 63     u_char                    *last;
 64     off_t                      start, len;
 65     size_t                     root;
 66     ngx_int_t                  rc;
 67     ngx_uint_t                 level, i;
 68     ngx_str_t                  path, value;
 69     ngx_log_t                 *log;
 70     ngx_buf_t                 *b;
 71     ngx_chain_t                out[2];
 72     ngx_open_file_info_t       of;
 73     ngx_http_core_loc_conf_t  *clcf;
 74 
 75     if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
 76         return NGX_HTTP_NOT_ALLOWED;
 77     }
 78 
 79     if (r->uri.data[r->uri.len - 1] == '/') {
 80         return NGX_DECLINED;
 81     }
 82 
 83     rc = ngx_http_discard_request_body(r);
 84 
 85     if (rc != NGX_OK) {
 86         return rc;
 87     }
 88 
 89     last = ngx_http_map_uri_to_path(r, &path, &root, 0);
 90     if (last == NULL) {
 91         return NGX_HTTP_INTERNAL_SERVER_ERROR;
 92     }
 93 
 94     log = r->connection->log;
 95 
 96     path.len = last - path.data;
 97 
 98     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
 99                    "http flv filename: \"%V\"", &path);
100 
101     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
102 
103     ngx_memzero(&of, sizeof(ngx_open_file_info_t));
104 
105     of.read_ahead = clcf->read_ahead;
106     of.directio = clcf->directio;
107     of.valid = clcf->open_file_cache_valid;
108     of.min_uses = clcf->open_file_cache_min_uses;
109     of.errors = clcf->open_file_cache_errors;
110     of.events = clcf->open_file_cache_events;
111 
112     if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
113         != NGX_OK)
114     {
115         switch (of.err) {
116 
117         case 0:
118             return NGX_HTTP_INTERNAL_SERVER_ERROR;
119 
120         case NGX_ENOENT:
121         case NGX_ENOTDIR:
122         case NGX_ENAMETOOLONG:
123 
124             level = NGX_LOG_ERR;
125             rc = NGX_HTTP_NOT_FOUND;
126             break;
127 
128         case NGX_EACCES:
129 
130             level = NGX_LOG_ERR;
131             rc = NGX_HTTP_FORBIDDEN;
132             break;
133 
134         default:
135 
136             level = NGX_LOG_CRIT;
137             rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
138             break;
139         }
140 
141         if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
142             ngx_log_error(level, log, of.err,
143                           "%s \"%s\" failed", of.failed, path.data);
144         }
145 
146         return rc;
147     }
148 
149     if (!of.is_file) {
150 
151         if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
152             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
153                           ngx_close_file_n " \"%s\" failed", path.data);
154         }
155 
156         return NGX_DECLINED;
157     }
158 
159     r->root_tested = !r->error_page;
160 
161     start = 0;
162     len = of.size;
163     i = 1;
164 
165     if (r->args.len) {
166 
167         if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) {
168 
169             start = ngx_atoof(value.data, value.len);
170 
171             if (start == NGX_ERROR || start >= len) {
172                 start = 0;
173             }
174 
175             if (start) {
176                 len = sizeof(ngx_flv_header) - 1 + len - start;
177                 i = 0;
178             }
179         }
180     }
181 
182     log->action = "sending flv to client";
183 
184     r->headers_out.status = NGX_HTTP_OK;
185     r->headers_out.content_length_n = len;
186     r->headers_out.last_modified_time = of.mtime;
187 
188     if (ngx_http_set_content_type(r) != NGX_OK) {
189         return NGX_HTTP_INTERNAL_SERVER_ERROR;
190     }
191 
192     if (i == 0) {
193         b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
194         if (b == NULL) {
195             return NGX_HTTP_INTERNAL_SERVER_ERROR;
196         }
197 
198         b->pos = ngx_flv_header;
199         b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1;
200         b->memory = 1;
201 
202         out[0].buf = b;
203         out[0].next = &out[1];
204     }
205 
206 
207     b = ngx_pcalloc(r->pool, sizeof(ngx_buf_t));
208     if (b == NULL) {
209         return NGX_HTTP_INTERNAL_SERVER_ERROR;
210     }
211 
212     b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
213     if (b->file == NULL) {
214         return NGX_HTTP_INTERNAL_SERVER_ERROR;
215     }
216 
217     r->allow_ranges = 1;
218 
219     rc = ngx_http_send_header(r);
220 
221     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
222         return rc;
223     }
224 
225     b->file_pos = start;
226     b->file_last = of.size;
227 
228     b->in_file = b->file_last ? 1: 0;
229     b->last_buf = 1;
230     b->last_in_chain = 1;
231 
232     b->file->fd = of.fd;
233     b->file->name = path;
234     b->file->log = log;
235     b->file->directio = of.is_directio;
236 
237     out[1].buf = b;
238     out[1].next = NULL;
239 
240     return ngx_http_output_filter(r, &out[i]);
241 }
242 
243 
244 static char *
245 ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
246 {
247     ngx_http_core_loc_conf_t  *clcf;
248 
249     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
250     clcf->handler = ngx_http_flv_handler;
251 
252     return NGX_CONF_OK;
253 }
254 

~ [ 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.