Mercurial > hg > nginx
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 |