Annotation of embedaddon/nginx/src/http/modules/ngx_http_flv_module.c, revision 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>