3 * Copyright (C) Igor Sysoev
4 * Copyright (C) Nginx, Inc.
7 #include <ngx_config.h>
12 static char *ngx_http_flv(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
);
14 static ngx_command_t ngx_http_flv_commands
[] = {
17 NGX_HTTP_LOC_CONF
|NGX_CONF_NOARGS
,
27 static u_char ngx_flv_header
[] = "FLV\x1\x5\0\0\0\x9\0\0\0\0";
30 static ngx_http_module_t ngx_http_flv_module_ctx
= {
31 NULL
, /* preconfiguration */
32 NULL
, /* postconfiguration */
34 NULL
, /* create main configuration */
35 NULL
, /* init main configuration */
37 NULL
, /* create server configuration */
38 NULL
, /* merge server configuration */
40 NULL
, /* create location configuration */
41 NULL
/* merge location configuration */
45 ngx_module_t ngx_http_flv_module
= {
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 */
62 ngx_http_flv_handler(ngx_http_request_t
*r
)
69 ngx_str_t path
, value
;
73 ngx_open_file_info_t of
;
74 ngx_http_core_loc_conf_t
*clcf
;
76 if (!(r
->method
& (NGX_HTTP_GET
|NGX_HTTP_HEAD
))) {
77 return NGX_HTTP_NOT_ALLOWED
;
80 if (r
->uri
.data
[r
->uri
.len
- 1] == '/') {
84 rc
= ngx_http_discard_request_body(r
);
90 last
= ngx_http_map_uri_to_path(r
, &path
, &root
, 0);
92 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
95 log
= r
->connection
->log
;
97 path
.len
= last
- path
.data
;
99 ngx_log_debug1(NGX_LOG_DEBUG_HTTP
, log
, 0,
100 "http flv filename: \"%V\"", &path
);
102 clcf
= ngx_http_get_module_loc_conf(r
, ngx_http_core_module
);
104 ngx_memzero(&of
, sizeof(ngx_open_file_info_t
));
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
;
113 if (ngx_http_set_disable_symlinks(r
, clcf
, &path
, &of
) != NGX_OK
) {
114 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
117 if (ngx_open_cached_file(clcf
->open_file_cache
, &path
, &of
, r
->pool
)
123 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
127 case NGX_ENAMETOOLONG
:
130 rc
= NGX_HTTP_NOT_FOUND
;
134 #if (NGX_HAVE_OPENAT)
140 rc
= NGX_HTTP_FORBIDDEN
;
145 level
= NGX_LOG_CRIT
;
146 rc
= NGX_HTTP_INTERNAL_SERVER_ERROR
;
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
);
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
);
168 r
->root_tested
= !r
->error_page
;
176 if (ngx_http_arg(r
, (u_char
*) "start", 5, &value
) == NGX_OK
) {
178 start
= ngx_atoof(value
.data
, value
.len
);
180 if (start
== NGX_ERROR
|| start
>= len
) {
185 len
= sizeof(ngx_flv_header
) - 1 + len
- start
;
191 log
->action
= "sending flv to client";
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
;
197 if (ngx_http_set_etag(r
) != NGX_OK
) {
198 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
201 if (ngx_http_set_content_type(r
) != NGX_OK
) {
202 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
206 b
= ngx_pcalloc(r
->pool
, sizeof(ngx_buf_t
));
208 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
211 b
->pos
= ngx_flv_header
;
212 b
->last
= ngx_flv_header
+ sizeof(ngx_flv_header
) - 1;
216 out
[0].next
= &out
[1];
220 b
= ngx_pcalloc(r
->pool
, sizeof(ngx_buf_t
));
222 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
225 b
->file
= ngx_pcalloc(r
->pool
, sizeof(ngx_file_t
));
226 if (b
->file
== NULL
) {
227 return NGX_HTTP_INTERNAL_SERVER_ERROR
;
232 rc
= ngx_http_send_header(r
);
234 if (rc
== NGX_ERROR
|| rc
> NGX_OK
|| r
->header_only
) {
239 b
->file_last
= of
.size
;
241 b
->in_file
= b
->file_last
? 1: 0;
242 b
->last_buf
= (r
== r
->main
) ? 1 : 0;
243 b
->last_in_chain
= 1;
246 b
->file
->name
= path
;
248 b
->file
->directio
= of
.is_directio
;
253 return ngx_http_output_filter(r
, &out
[i
]);
258 ngx_http_flv(ngx_conf_t
*cf
, ngx_command_t
*cmd
, void *conf
)
260 ngx_http_core_loc_conf_t
*clcf
;
262 clcf
= ngx_http_conf_get_module_loc_conf(cf
, ngx_http_core_module
);
263 clcf
->handler
= ngx_http_flv_handler
;