comparison src/http/modules/ngx_http_flv_module.c @ 1454:f497ed7682a7

open_file_cache in HTTP
author Igor Sysoev <igor@sysoev.ru>
date Sat, 01 Sep 2007 12:12:48 +0000
parents aabbf66b61ea
children 223e92651ca5
comparison
equal deleted inserted replaced
1453:f2feed5bffe1 1454:f497ed7682a7
58 58
59 59
60 static ngx_int_t 60 static ngx_int_t
61 ngx_http_flv_handler(ngx_http_request_t *r) 61 ngx_http_flv_handler(ngx_http_request_t *r)
62 { 62 {
63 u_char *p; 63 u_char *p, *last;
64 off_t start, len; 64 off_t start, len;
65 size_t root; 65 size_t root;
66 ngx_fd_t fd; 66 ngx_fd_t fd;
67 ngx_int_t rc; 67 ngx_int_t rc;
68 ngx_uint_t level, i; 68 ngx_uint_t level, i;
69 ngx_str_t path; 69 ngx_str_t path;
70 ngx_err_t err;
71 ngx_log_t *log; 70 ngx_log_t *log;
72 ngx_buf_t *b; 71 ngx_buf_t *b;
73 ngx_chain_t out[2]; 72 ngx_chain_t out[2];
74 ngx_file_info_t fi; 73 ngx_open_file_info_t of;
75 ngx_pool_cleanup_t *cln;
76 ngx_pool_cleanup_file_t *clnf;
77 ngx_http_core_loc_conf_t *clcf; 74 ngx_http_core_loc_conf_t *clcf;
78 75
79 if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) { 76 if (!(r->method & (NGX_HTTP_GET|NGX_HTTP_HEAD))) {
80 return NGX_HTTP_NOT_ALLOWED; 77 return NGX_HTTP_NOT_ALLOWED;
81 } 78 }
93 90
94 if (rc != NGX_OK) { 91 if (rc != NGX_OK) {
95 return rc; 92 return rc;
96 } 93 }
97 94
98 if (ngx_http_map_uri_to_path(r, &path, &root, 0) == NULL) { 95 last = ngx_http_map_uri_to_path(r, &path, &root, 0);
96 if (last == NULL) {
99 return NGX_HTTP_INTERNAL_SERVER_ERROR; 97 return NGX_HTTP_INTERNAL_SERVER_ERROR;
100 } 98 }
101 99
102 log = r->connection->log; 100 log = r->connection->log;
103 101
102 path.len = last - path.data;
103
104 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0, 104 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, log, 0,
105 "http flv filename: \"%s\"", path.data); 105 "http flv filename: \"%V\"", &path);
106 106
107 cln = ngx_pool_cleanup_add(r->pool, sizeof(ngx_pool_cleanup_file_t)); 107 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
108 if (cln == NULL) { 108
109 return NGX_HTTP_INTERNAL_SERVER_ERROR; 109 of.test_dir = 0;
110 } 110 of.retest = clcf->open_file_cache_retest;
111 111 of.errors = clcf->open_file_cache_errors;
112 fd = ngx_open_file(path.data, NGX_FILE_RDONLY, NGX_FILE_OPEN, 0); 112
113 113 rc = ngx_open_cached_file(clcf->open_file_cache, &path, &of, r->pool);
114 if (fd == NGX_INVALID_FILE) { 114
115 err = ngx_errno; 115 if (rc == NGX_ERROR) {
116 116
117 if (err == NGX_ENOENT 117 switch (of.err) {
118 || err == NGX_ENOTDIR 118
119 || err == NGX_ENAMETOOLONG) 119 case 0:
120 { 120 return NGX_HTTP_INTERNAL_SERVER_ERROR;
121
122 case NGX_ENOENT:
123 case NGX_ENOTDIR:
124 case NGX_ENAMETOOLONG:
125
121 level = NGX_LOG_ERR; 126 level = NGX_LOG_ERR;
122 rc = NGX_HTTP_NOT_FOUND; 127 rc = NGX_HTTP_NOT_FOUND;
123 128 break;
124 } else if (err == NGX_EACCES) { 129
130 case NGX_EACCES:
131
125 level = NGX_LOG_ERR; 132 level = NGX_LOG_ERR;
126 rc = NGX_HTTP_FORBIDDEN; 133 rc = NGX_HTTP_FORBIDDEN;
127 134 break;
128 } else { 135
136 default:
137
129 level = NGX_LOG_CRIT; 138 level = NGX_LOG_CRIT;
130 rc = NGX_HTTP_INTERNAL_SERVER_ERROR; 139 rc = NGX_HTTP_INTERNAL_SERVER_ERROR;
131 } 140 break;
132 141 }
133 clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module);
134 142
135 if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) { 143 if (rc != NGX_HTTP_NOT_FOUND || clcf->log_not_found) {
136 ngx_log_error(level, log, err, 144 ngx_log_error(level, log, of.err,
137 ngx_open_file_n " \"%s\" failed", path.data); 145 ngx_open_file_n " \"%s\" failed", path.data);
138 } 146 }
139 147
140 return rc; 148 return rc;
141 } 149 }
142 150
143 if (ngx_fd_info(fd, &fi) == NGX_FILE_ERROR) { 151 fd = of.fd;
144 ngx_log_error(NGX_LOG_CRIT, log, ngx_errno, 152
145 ngx_fd_info_n " \"%s\" failed", path.data); 153 if (!of.is_file) {
146 154
147 if (ngx_close_file(fd) == NGX_FILE_ERROR) { 155 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
148 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno, 156 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
149 ngx_close_file_n " \"%s\" failed", path.data); 157 ngx_close_file_n " \"%s\" failed", path.data);
150 } 158 }
151 159
152 return NGX_HTTP_INTERNAL_SERVER_ERROR;
153 }
154
155 if (!ngx_is_file(&fi)) {
156
157 if (ngx_close_file(fd) == NGX_FILE_ERROR) {
158 ngx_log_error(NGX_LOG_ALERT, log, ngx_errno,
159 ngx_close_file_n " \"%s\" failed", path.data);
160 }
161
162 return NGX_DECLINED; 160 return NGX_DECLINED;
163 } 161 }
164 162
165 start = 0; 163 start = 0;
166 len = ngx_file_size(&fi); 164 len = of.size;
167 i = 1; 165 i = 1;
168 166
169 if (r->args.len) { 167 if (r->args.len) {
170 p = (u_char *) ngx_strstr(r->args.data, "start="); 168 p = (u_char *) ngx_strstr(r->args.data, "start=");
171 169
185 } 183 }
186 } 184 }
187 185
188 log->action = "sending flv to client"; 186 log->action = "sending flv to client";
189 187
190 cln->handler = ngx_pool_cleanup_file;
191 clnf = cln->data;
192
193 clnf->fd = fd;
194 clnf->name = path.data;
195 clnf->log = r->pool->log;
196
197 r->headers_out.status = NGX_HTTP_OK; 188 r->headers_out.status = NGX_HTTP_OK;
198 r->headers_out.content_length_n = len; 189 r->headers_out.content_length_n = len;
199 r->headers_out.last_modified_time = ngx_file_mtime(&fi); 190 r->headers_out.last_modified_time = of.mtime;
200 191
201 if (ngx_http_set_content_type(r) != NGX_OK) { 192 if (ngx_http_set_content_type(r) != NGX_OK) {
202 return NGX_HTTP_INTERNAL_SERVER_ERROR; 193 return NGX_HTTP_INTERNAL_SERVER_ERROR;
203 } 194 }
204 195
235 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) { 226 if (rc == NGX_ERROR || rc > NGX_OK || r->header_only) {
236 return rc; 227 return rc;
237 } 228 }
238 229
239 b->file_pos = start; 230 b->file_pos = start;
240 b->file_last = ngx_file_size(&fi); 231 b->file_last = of.size;
241 232
242 b->in_file = b->file_last ? 1: 0; 233 b->in_file = b->file_last ? 1: 0;
243 b->last_buf = 1; 234 b->last_buf = 1;
244 b->last_in_chain = 1; 235 b->last_in_chain = 1;
245 236