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>