Mercurial > hg > ngx_http_bytes_filter_module
comparison ngx_http_bytes_filter_module.c @ 0:8aec31ab4d52
Bytes filter module skeleton, currently does nothing.
Bytes module designed to return only specific range of file as requested in
arguments. It's intended to replace flv module as more generic alternative.
author | Maxim Dounin <mdounin@mdounin.ru> |
---|---|
date | Thu, 26 Jun 2008 04:49:22 +0400 |
parents | |
children | 6b995d5251ec |
comparison
equal
deleted
inserted
replaced
-1:000000000000 | 0:8aec31ab4d52 |
---|---|
1 | |
2 /* | |
3 * Copyright (C) Maxim Dounin | |
4 */ | |
5 | |
6 #include <ngx_config.h> | |
7 #include <ngx_core.h> | |
8 #include <ngx_http.h> | |
9 | |
10 | |
11 typedef struct { | |
12 ngx_flag_t enable; | |
13 } ngx_http_bytes_conf_t; | |
14 | |
15 | |
16 typedef struct { | |
17 off_t start; | |
18 off_t end; | |
19 } ngx_http_bytes_t; | |
20 | |
21 | |
22 typedef struct { | |
23 off_t offset; | |
24 ngx_array_t ranges; | |
25 } ngx_http_bytes_ctx_t; | |
26 | |
27 | |
28 static void *ngx_http_bytes_create_conf(ngx_conf_t *cf); | |
29 static char *ngx_http_bytes_merge_conf(ngx_conf_t *cf, void *parent, | |
30 void *child); | |
31 static ngx_int_t ngx_http_bytes_init(ngx_conf_t *cf); | |
32 | |
33 | |
34 static ngx_command_t ngx_http_bytes_commands[] = { | |
35 | |
36 { ngx_string("bytes"), | |
37 NGX_HTTP_MAIN_CONF|NGX_HTTP_SRV_CONF|NGX_HTTP_LOC_CONF|NGX_CONF_FLAG, | |
38 ngx_conf_set_flag_slot, | |
39 NGX_HTTP_LOC_CONF_OFFSET, | |
40 offsetof(ngx_http_bytes_conf_t, enable), | |
41 NULL }, | |
42 | |
43 ngx_null_command | |
44 }; | |
45 | |
46 | |
47 static ngx_http_module_t ngx_http_bytes_module_ctx = { | |
48 NULL, /* preconfiguration */ | |
49 ngx_http_bytes_init, /* postconfiguration */ | |
50 | |
51 NULL, /* create main configuration */ | |
52 NULL, /* init main configuration */ | |
53 | |
54 NULL, /* create server configuration */ | |
55 NULL, /* merge server configuration */ | |
56 | |
57 ngx_http_bytes_create_conf, /* create location configuration */ | |
58 ngx_http_bytes_merge_conf /* merge location configuration */ | |
59 }; | |
60 | |
61 | |
62 ngx_module_t ngx_http_bytes_filter_module = { | |
63 NGX_MODULE_V1, | |
64 &ngx_http_bytes_module_ctx, /* module context */ | |
65 ngx_http_bytes_commands, /* module directives */ | |
66 NGX_HTTP_MODULE, /* module type */ | |
67 NULL, /* init master */ | |
68 NULL, /* init module */ | |
69 NULL, /* init process */ | |
70 NULL, /* init thread */ | |
71 NULL, /* exit thread */ | |
72 NULL, /* exit process */ | |
73 NULL, /* exit master */ | |
74 NGX_MODULE_V1_PADDING | |
75 }; | |
76 | |
77 | |
78 static ngx_http_output_header_filter_pt ngx_http_next_header_filter; | |
79 static ngx_http_output_body_filter_pt ngx_http_next_body_filter; | |
80 | |
81 | |
82 static ngx_int_t | |
83 ngx_http_bytes_header_filter(ngx_http_request_t *r) | |
84 { | |
85 u_char *p; | |
86 ngx_http_bytes_conf_t *conf; | |
87 ngx_http_bytes_ctx_t *ctx; | |
88 | |
89 conf = ngx_http_get_module_loc_conf(r, ngx_http_bytes_filter_module); | |
90 | |
91 if (!conf->enable || r->args.len == 0) { | |
92 return ngx_http_next_header_filter(r); | |
93 } | |
94 | |
95 p = (u_char *) ngx_strnstr(r->args.data, "bytes=", r->args.len); | |
96 | |
97 if (p == NULL) { | |
98 return ngx_http_next_header_filter(r); | |
99 } | |
100 | |
101 ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
102 "bytes header filter: r %p", r); | |
103 | |
104 p += sizeof("bytes=") - 1; | |
105 | |
106 /* create context */ | |
107 | |
108 ctx = ngx_pcalloc(r->pool, sizeof(ngx_http_bytes_ctx_t)); | |
109 if (ctx == NULL) { | |
110 return NGX_ERROR; | |
111 } | |
112 | |
113 if (ngx_array_init(&ctx->ranges, r->pool, 1, sizeof(ngx_http_bytes_t)) | |
114 == NGX_ERROR) | |
115 { | |
116 return NGX_ERROR; | |
117 } | |
118 | |
119 /* | |
120 * bytes= contain ranges compatible with RFC 2616, "14.35.1 Byte Ranges", | |
121 * but no whitespaces permitted | |
122 */ | |
123 | |
124 #if 0 | |
125 for ( ;; ) { | |
126 start = 0; | |
127 end = 0; | |
128 suffix = 0; | |
129 | |
130 if (*p != '-') { | |
131 if (*p < '0' || *p > '9') { | |
132 break; | |
133 } | |
134 | |
135 while (*p >= '0' && *p <= '9') { | |
136 start = start * 10 + *p++ - '0'; | |
137 } | |
138 | |
139 if (*p != '-') { | |
140 break; | |
141 } | |
142 | |
143 if (*p == ',' || *p == '\0') { | |
144 /* no last-byte-pos, assume end of file */ | |
145 end = len - 1; | |
146 } | |
147 | |
148 } else { | |
149 suffix = 1; | |
150 p++; | |
151 } | |
152 } | |
153 #endif | |
154 | |
155 /* ... */ | |
156 | |
157 ngx_http_set_ctx(r, ctx, ngx_http_bytes_filter_module); | |
158 | |
159 return ngx_http_next_header_filter(r); | |
160 } | |
161 | |
162 | |
163 static ngx_int_t | |
164 ngx_http_bytes_body_filter(ngx_http_request_t *r, ngx_chain_t *in) | |
165 { | |
166 ngx_http_bytes_ctx_t *ctx; | |
167 | |
168 ctx = ngx_http_get_module_ctx(r, ngx_http_bytes_filter_module); | |
169 | |
170 if (ctx == NULL) { | |
171 return ngx_http_next_body_filter(r, in); | |
172 } | |
173 | |
174 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, | |
175 "bytes body filter: r %p, in %p", r, in); | |
176 | |
177 return ngx_http_next_body_filter(r, in); | |
178 } | |
179 | |
180 | |
181 static void * | |
182 ngx_http_bytes_create_conf(ngx_conf_t *cf) | |
183 { | |
184 ngx_http_bytes_conf_t *conf; | |
185 | |
186 conf = ngx_pcalloc(cf->pool, sizeof(ngx_http_bytes_conf_t)); | |
187 if (conf == NULL) { | |
188 return NGX_CONF_ERROR; | |
189 } | |
190 | |
191 conf->enable = NGX_CONF_UNSET; | |
192 | |
193 return conf; | |
194 } | |
195 | |
196 | |
197 static char * | |
198 ngx_http_bytes_merge_conf(ngx_conf_t *cf, void *parent, void *child) | |
199 { | |
200 ngx_http_bytes_conf_t *prev = parent; | |
201 ngx_http_bytes_conf_t *conf = child; | |
202 | |
203 ngx_conf_merge_value(conf->enable, prev->enable, 0); | |
204 | |
205 return NGX_CONF_OK; | |
206 } | |
207 | |
208 | |
209 static ngx_int_t | |
210 ngx_http_bytes_init(ngx_conf_t *cf) | |
211 { | |
212 ngx_http_next_header_filter = ngx_http_top_header_filter; | |
213 ngx_http_top_header_filter = ngx_http_bytes_header_filter; | |
214 | |
215 ngx_http_next_body_filter = ngx_http_top_body_filter; | |
216 ngx_http_top_body_filter = ngx_http_bytes_body_filter; | |
217 | |
218 return NGX_OK; | |
219 } |