Back to home page

Nginx displayed by LXR

Source navigation ]
Diff markup ]
Identifier search ]
general search ]
 
 
Version: nginx-1.15.11 ]​[ nginx-1.14.2 ]​

0001 
0002 /*
0003  * Copyright (C) Igor Sysoev
0004  * Copyright (C) Nginx, Inc.
0005  */
0006 
0007 #include <ngx_config.h>
0008 #include <ngx_core.h>
0009 #include <ngx_http.h>
0010 
0011 
0012 static char *ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf);
0013 
0014 static ngx_command_t  ngx_http_flv_commands[] = {
0015 
0016     { ngx_string("flv"),
0017       NGX_HTTP_LOC_CONF|NGX_CONF_NOARGS,
0018       ngx_http_flv,
0019       0,
0020       0,
0021       NULL },
0022 
0023       ngx_null_command
0024 };
0025 
0026 
0027 static u_char  ngx_flv_header[] = "FLV\x1\x5\0\0\0\x9\0\0\0\0";
0028 
0029 
0030 static ngx_http_module_t  ngx_http_flv_module_ctx = {
0031     NULL,                          /* preconfiguration */
0032     NULL,                          /* postconfiguration */
0033 
0034     NULL,                          /* create main configuration */
0035     NULL,                          /* init main configuration */
0036 
0037     NULL,                          /* create server configuration */
0038     NULL,                          /* merge server configuration */
0039 
0040     NULL,                          /* create location configuration */
0041     NULL                           /* merge location configuration */
0042 };
0043 
0044 
0045 ngx_module_t  ngx_http_flv_module = {
0046     NGX_MODULE_V1,
0047     &ngx_http_flv_module_ctx,      /* module context */
0048     ngx_http_flv_commands,         /* module directives */
0049     NGX_HTTP_MODULE,               /* module type */
0050     NULL,                          /* init master */
0051     NULL,                          /* init module */
0052     NULL,                          /* init process */
0053     NULL,                          /* init thread */
0054     NULL,                          /* exit thread */
0055     NULL,                          /* exit process */
0056     NULL,                          /* exit master */
0057     NGX_MODULE_V1_PADDING
0058 };
0059 
0060 
0061 static ngx_int_t
0062 ngx_http_flv_handler(ngx_http_request_t *r)
0063 {
0064     u_char                    *last;
0065     off_t                      start, len;
0066     size_t                     root;
0067     ngx_int_t                  rc;
0068     ngx_uint_t                 level, i;
0069     ngx_str_t                  path, value;
0070     ngx_log_t                 *log;
0071     ngx_buf_t                 *b;
0072     ngx_chain_t                out[2];
0073     ngx_open_file_info_t       of;
0074     ngx_http_core_loc_conf_t  *clcf;
0075 
0076     if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
0077         return NGX_HTTP_NOT_ALLOWED;
0078     }
0079 
0080     if (r->uri.data[r->uri.len - 1] == '/') {
0081         return NGX_DECLINED;
0082     }
0083 
0084     rc = ngx_http_discard_request_body(r);
0085 
0086     if (rc != NGX_OK) {
0087         return rc;
0088     }
0089 
0090     last = ngx_http_map_uri_to_path(r, &path, &root, 0);
0091     if (last == NULL) {
0092         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0093     }
0094 
0095     log = r->connection->log;
0096 
0097     path.len = last - path.data;
0098 
0099     ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
0100                    "http flv filename: \"%V\"", &path);
0101 
0102     clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
0103 
0104     ngx_memzero(&of, sizeof(ngx_open_file_info_t));
0105 
0106     of.read_ahead = clcf->read_ahead;
0107     of.directio = clcf->directio;
0108     of.valid = clcf->open_file_cache_valid;
0109     of.min_uses = clcf->open_file_cache_min_uses;
0110     of.errors = clcf->open_file_cache_errors;
0111     of.events = clcf->open_file_cache_events;
0112 
0113     if (ngx_http_set_disable_symlinks(r, clcf, &path, &of) != NGX_OK) {
0114         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0115     }
0116 
0117     if (ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool)
0118         != NGX_OK)
0119     {
0120         switch (of.err) {
0121 
0122         case 0:
0123             return NGX_HTTP_INTERNAL_SERVER_ERROR;
0124 
0125         case NGX_ENOENT:
0126         case NGX_ENOTDIR:
0127         case NGX_ENAMETOOLONG:
0128 
0129             level = NGX_LOG_ERR;
0130             rc = NGX_HTTP_NOT_FOUND;
0131             break;
0132 
0133         case NGX_EACCES:
0134 #if (NGX_HAVE_OPENAT)
0135         case NGX_EMLINK:
0136         case NGX_ELOOP:
0137 #endif
0138 
0139             level = NGX_LOG_ERR;
0140             rc = NGX_HTTP_FORBIDDEN;
0141             break;
0142 
0143         default:
0144 
0145             level = NGX_LOG_CRIT;
0146             rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
0147             break;
0148         }
0149 
0150         if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
0151             ngx_log_error(level, log, of.err,
0152                           "%s \"%s\" failed", of.failed, path.data);
0153         }
0154 
0155         return rc;
0156     }
0157 
0158     if (!of.is_file) {
0159 
0160         if (ngx_close_file(of.fd) == NGX_FILE_ERROR) {
0161             ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
0162                           ngx_close_file_n " \"%s\" failed", path.data);
0163         }
0164 
0165         return NGX_DECLINED;
0166     }
0167 
0168     r->root_tested = !r->error_page;
0169 
0170     start = 0;
0171     len = of.size;
0172     i = 1;
0173 
0174     if (r->args.len) {
0175 
0176         if (ngx_http_arg(r, (u_char *) "start", 5, &value) == NGX_OK) {
0177 
0178             start = ngx_atoof(value.data, value.len);
0179 
0180             if (start == NGX_ERROR || start >= len) {
0181                 start = 0;
0182             }
0183 
0184             if (start) {
0185                 len = sizeof(ngx_flv_header) - 1 + len - start;
0186                 i = 0;
0187             }
0188         }
0189     }
0190 
0191     log->action = "sending flv to client";
0192 
0193     r->headers_out.status = NGX_HTTP_OK;
0194     r->headers_out.content_length_n = len;
0195     r->headers_out.last_modified_time = of.mtime;
0196 
0197     if (ngx_http_set_etag(r) != NGX_OK) {
0198         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0199     }
0200 
0201     if (ngx_http_set_content_type(r) != NGX_OK) {
0202         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0203     }
0204 
0205     if (i == 0) {
0206         b = ngx_calloc_buf(r->pool);
0207         if (b == NULL) {
0208             return NGX_HTTP_INTERNAL_SERVER_ERROR;
0209         }
0210 
0211         b->pos = ngx_flv_header;
0212         b->last = ngx_flv_header + sizeof(ngx_flv_header) - 1;
0213         b->memory = 1;
0214 
0215         out[0].buf = b;
0216         out[0].next = &out[1];
0217     }
0218 
0219 
0220     b = ngx_calloc_buf(r->pool);
0221     if (b == NULL) {
0222         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0223     }
0224 
0225     b->file = ngx_pcalloc(r->pool, sizeof(ngx_file_t));
0226     if (b->file == NULL) {
0227         return NGX_HTTP_INTERNAL_SERVER_ERROR;
0228     }
0229 
0230     r->allow_ranges = 1;
0231 
0232     rc = ngx_http_send_header(r);
0233 
0234     if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
0235         return rc;
0236     }
0237 
0238     b->file_pos = start;
0239     b->file_last = of.size;
0240 
0241     b->in_file = b->file_last ? 1: 0;
0242     b->last_buf = (r == r->main) ? 1 : 0;
0243     b->last_in_chain = 1;
0244 
0245     b->file->fd = of.fd;
0246     b->file->name = path;
0247     b->file->log = log;
0248     b->file->directio = of.is_directio;
0249 
0250     out[1].buf = b;
0251     out[1].next = NULL;
0252 
0253     return ngx_http_output_filter(r, &out[i]);
0254 }
0255 
0256 
0257 static char *
0258 ngx_http_flv(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
0259 {
0260     ngx_http_core_loc_conf_t  *clcf;
0261 
0262     clcf = ngx_http_conf_get_module_loc_conf(cf, ngx_http_core_module);
0263     clcf->handler = ngx_http_flv_handler;
0264 
0265     return NGX_CONF_OK;
0266 }