3
3
#include <ngx_core.h>
4
4
#include <ngx_http.h>
5
5
/*
6
- * This module is used to split a normal http request to multiple Range request to upstreams
7
- * We do this by modifing the http header and adding the Range header to issue multiple range reqeusts .
6
+ * This module is used to split a normal http request to multiple Range requests to upstreams
7
+ * We do this by modifing the http header and adding the Range header to issue multiple range subreqeusts .
8
8
* This is insensitive to client.
9
9
*
10
10
* We send the output of main request first which is different from the default behavior that
11
- * at last. So there is three problems we should pay attention to:
11
+ * at last. So there are three problems we should pay attention to:
12
12
* 1.We should clear the buf->last_buf flag after the main request because this is not the last
13
13
* buffer in our case.
14
14
* 2.Set buf->last_buf of the last subrequest's last buf. Nginx do not set buf->last_buf of
@@ -20,6 +20,7 @@ static ngx_int_t ngx_http_subrange_init(ngx_conf_t *cf);
20
20
static ngx_int_t ngx_http_subrange_filter_init (ngx_conf_t * cf );
21
21
static void * ngx_http_subrange_create_loc_conf (ngx_conf_t * cf );
22
22
static char * ngx_http_subrange_merge_loc_conf (ngx_conf_t * cf , void * parent , void * child );
23
+ static char * ngx_http_subrange_subrange_cmd (ngx_conf_t * cf , ngx_command_t * cmd , void * conf );
23
24
static ngx_http_output_header_filter_pt ngx_http_next_header_filter ;
24
25
static ngx_http_output_body_filter_pt ngx_http_next_body_filter ;
25
26
@@ -31,7 +32,7 @@ static ngx_int_t ngx_http_subrange_post_subrequest(ngx_http_request_t *r, void *
31
32
static ngx_command_t ngx_http_subrange_commands [] = {
32
33
{ ngx_string ("subrange" ),
33
34
NGX_HTTP_MAIN_CONF |NGX_HTTP_SRV_CONF |NGX_HTTP_LOC_CONF |NGX_CONF_TAKE1 ,
34
- ngx_conf_set_size_slot ,
35
+ ngx_http_subrange_subrange_cmd ,
35
36
NGX_HTTP_LOC_CONF_OFFSET ,
36
37
0 ,
37
38
NULL },
@@ -96,8 +97,13 @@ ngx_module_t ngx_http_subrange_filter_module = {
96
97
};
97
98
98
99
/*------------- the api implements ------------*/
100
+ typedef struct ngx_http_subrange_script_s {
101
+ ngx_array_t * lengths ;
102
+ ngx_array_t * values ;
103
+ }ngx_http_subrange_script_t ;
99
104
typedef struct ngx_http_subrange_loc_conf_s {
100
105
ngx_int_t size ;
106
+ ngx_http_subrange_script_t * script ;
101
107
}ngx_http_subrange_loc_conf_t ;
102
108
103
109
typedef struct ngx_http_subrange_s {
@@ -169,20 +175,69 @@ static ngx_int_t ngx_http_subrange_filter_init(ngx_conf_t *cf){
169
175
return NGX_OK ;
170
176
}
171
177
178
+ static char * ngx_http_subrange_subrange_cmd (ngx_conf_t * cf , ngx_command_t * cmd , void * conf ){
179
+ ngx_str_t * value ;
180
+ ngx_uint_t n ;
181
+ ngx_http_script_compile_t sc ;
182
+ ngx_http_subrange_loc_conf_t * slcf ;
183
+ ngx_array_t * lengths , * values ;
184
+
185
+ lengths = NULL ;
186
+ values = NULL ;
187
+ slcf = conf ;
188
+
189
+ value = cf -> args -> elts ;
190
+
191
+ n = ngx_http_script_variables_count (& value [1 ]);
192
+ if (n == 0 ){
193
+ return ngx_conf_set_size_slot (cf , cmd , conf );
194
+ }else {
195
+ if (slcf -> script != NULL ){
196
+ return "is duplicated" ;
197
+ }
198
+ slcf -> script = ngx_pcalloc (cf -> pool , sizeof (ngx_http_subrange_script_t ));
199
+ if (slcf -> script == NULL ){
200
+ return NGX_CONF_ERROR ;
201
+ }
202
+ /*
203
+ * slcf->script->lengths = NULL;
204
+ * slcf->script->values = NULL;
205
+ * set by ngx_pcalloc
206
+ * */
207
+ ngx_memzero (& sc , sizeof (ngx_http_script_compile_t ));
208
+ sc .cf = cf ;
209
+ sc .source = & value [1 ];
210
+ sc .variables = n ;
211
+ sc .lengths = & slcf -> script -> lengths ;
212
+ sc .values = & slcf -> script -> values ;
213
+ sc .complete_lengths = 1 ;
214
+ sc .complete_values = 1 ;
215
+ slcf -> size = NGX_CONF_UNSET ;
216
+ if (ngx_http_script_compile (& sc ) != NGX_OK ){
217
+ return NGX_CONF_ERROR ;
218
+ }
219
+ }
220
+ return NGX_CONF_OK ;
221
+ }
172
222
static void * ngx_http_subrange_create_loc_conf (ngx_conf_t * cf ){
173
223
ngx_http_subrange_loc_conf_t * rlcf ;
174
224
rlcf = ngx_palloc (cf -> pool , sizeof (ngx_http_subrange_loc_conf_t ));
175
225
if (rlcf == NULL ){
176
226
return NULL ;
177
227
}
178
228
rlcf -> size = NGX_CONF_UNSET ;
229
+ rlcf -> script = NULL ;
179
230
return rlcf ;
180
231
}
181
232
static char * ngx_http_subrange_merge_loc_conf (ngx_conf_t * cf , void * parent , void * child ){
182
233
ngx_http_subrange_loc_conf_t * prev ,* conf ;
183
234
prev = parent ;
184
235
conf = child ;
185
236
ngx_conf_merge_value (conf -> size , prev -> size , 0 );
237
+ if (conf -> script == NULL ){
238
+ conf -> script = prev -> script ;
239
+ }
240
+
186
241
return NGX_CONF_OK ;
187
242
}
188
243
static ngx_int_t ngx_http_subrange_parse (ngx_http_request_t * r , ngx_http_subrange_filter_ctx_t
@@ -558,6 +613,9 @@ static ngx_int_t ngx_http_subrange_set_header_handler(ngx_http_request_t *r){
558
613
ngx_int_t rstart ,rend ;
559
614
ngx_str_t key = ngx_string ("Range" );
560
615
616
+ ngx_str_t subrange ;
617
+ size_t size ;
618
+
561
619
rstart = 0 ;
562
620
rend = 0 ;
563
621
@@ -566,6 +624,19 @@ static ngx_int_t ngx_http_subrange_set_header_handler(ngx_http_request_t *r){
566
624
return NGX_DECLINED ;
567
625
}
568
626
rlcf = ngx_http_get_module_loc_conf (r , ngx_http_subrange_module );
627
+ if (rlcf -> script ){
628
+ if (ngx_http_script_run (r , & subrange , rlcf -> script -> lengths -> elts , 0 , rlcf -> script -> values -> elts )
629
+ == NULL ){
630
+ ngx_log_error (NGX_LOG_WARN , r -> connection -> log , 0 , "http subrange module: subrange variable get failed, subrange disabled" );
631
+ return NGX_DECLINED ;
632
+ }
633
+ size = ngx_parse_size (& subrange );
634
+ if (size == (size_t ) NGX_ERROR ){
635
+ ngx_log_error (NGX_LOG_WARN , r -> connection -> log , 0 , "http subrange module: subrange value parse failed, subrange disabled" );
636
+ return NGX_DECLINED ;
637
+ }
638
+ rlcf -> size = size ;
639
+ }
569
640
if (rlcf -> size == NGX_CONF_UNSET || rlcf -> size == 0 ){
570
641
return NGX_DECLINED ;
571
642
}
0 commit comments