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