annotate src/http/modules/ngx_http_split_clients_module.c @ 4377:726a1ca9b52b

Proxy: made proxy_pass with variables more consistent. If proxy_pass was used with variables and there was no URI component, nginx always used unparsed URI. This isn't consistent with "no variables" case, where e.g. rewrites are applied even if there is no URI component. Fix is to use the same logic in both cases, i.e. only use unparsed URI if it's valid and request is the main one.
author Maxim Dounin <mdounin@mdounin.ru>
date Fri, 23 Dec 2011 16:04:09 +0000
parents eccd0b66a4ab
children d620f497c50f
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
1
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
2 /*
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
3 * Copyright (C) Igor Sysoev
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
4 */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
5
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
6
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
7 #include <ngx_config.h>
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_core.h>
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #include <ngx_http.h>
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
11
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
12 typedef struct {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 uint32_t percent;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
14 ngx_http_variable_value_t value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
15 } ngx_http_split_clients_part_t;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
17
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
18 typedef struct {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 ngx_http_complex_value_t value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20 ngx_array_t parts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21 } ngx_http_split_clients_ctx_t;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
23
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
24 static char *ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25 void *conf);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
26 static char *ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27 void *conf);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
28
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
29 static ngx_command_t ngx_http_split_clients_commands[] = {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
30
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31 { ngx_string("split_clients"),
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33 ngx_conf_split_clients_block,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34 NGX_HTTP_MAIN_CONF_OFFSET,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35 0,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 NULL },
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38 ngx_null_command
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39 };
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
40
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
41
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
42 static ngx_http_module_t ngx_http_split_clients_module_ctx = {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43 NULL, /* preconfiguration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
44 NULL, /* postconfiguration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46 NULL, /* create main configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
47 NULL, /* init main configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
48
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49 NULL, /* create server configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 NULL, /* merge server configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52 NULL, /* create location configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53 NULL /* merge location configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54 };
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
55
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
57 ngx_module_t ngx_http_split_clients_module = {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58 NGX_MODULE_V1,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 &ngx_http_split_clients_module_ctx, /* module context */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 ngx_http_split_clients_commands, /* module directives */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 NGX_HTTP_MODULE, /* module type */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62 NULL, /* init master */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63 NULL, /* init module */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 NULL, /* init process */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65 NULL, /* init thread */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 NULL, /* exit thread */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 NULL, /* exit process */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 NULL, /* exit master */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 NGX_MODULE_V1_PADDING
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 };
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
71
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
72
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
73 static ngx_int_t
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 ngx_http_split_clients_variable(ngx_http_request_t *r,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 ngx_http_variable_value_t *v, uintptr_t data)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77 ngx_http_split_clients_ctx_t *ctx = (ngx_http_split_clients_ctx_t *) data;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
79 uint32_t hash;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
80 ngx_str_t val;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
81 ngx_uint_t i;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
82 ngx_http_split_clients_part_t *part;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
83
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84 *v = ngx_http_variable_null_value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
86 if (ngx_http_complex_value(r, &ctx->value, &val) != NGX_OK) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87 return NGX_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89
3892
12d8d2f30205 use MurmurHash2 for split_clients, because
Igor Sysoev <igor@sysoev.ru>
parents: 3607
diff changeset
90 hash = ngx_murmur_hash2(val.data, val.len);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
91
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
92 part = ctx->parts.elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94 for (i = 0; i < ctx->parts.nelts; i++) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
95
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
96 ngx_log_debug2(NGX_LOG_DEBUG_HTTP, r->connection->log, 0,
3918
eccd0b66a4ab fix debug logging
Igor Sysoev <igor@sysoev.ru>
parents: 3892
diff changeset
97 "http split: %uD %uD", hash, part[i].percent);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
98
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99 if (hash < part[i].percent) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
100 *v = part[i].value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
101 return NGX_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
102 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
103 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
104
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
105 return NGX_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
106 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
107
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
108
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
109 static char *
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110 ngx_conf_split_clients_block(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
112 char *rv;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113 ngx_str_t *value, name;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
114 ngx_uint_t i, sum, last;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 ngx_conf_t save;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
116 ngx_http_variable_t *var;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
117 ngx_http_split_clients_ctx_t *ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
118 ngx_http_split_clients_part_t *part;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
119 ngx_http_compile_complex_value_t ccv;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
120
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
121 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_http_split_clients_ctx_t));
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
122 if (ctx == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
123 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
124 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
125
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
126 value = cf->args->elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
127
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
128 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
129
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
130 ccv.cf = cf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
131 ccv.value = &value[1];
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
132 ccv.complex_value = &ctx->value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
133
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
134 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
135 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
136 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
137
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
138 name = value[2];
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
139 name.len--;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
140 name.data++;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
141
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
142 var = ngx_http_add_variable(cf, &name, NGX_HTTP_VAR_CHANGEABLE);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
143 if (var == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
144 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
145 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
146
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
147 var->get_handler = ngx_http_split_clients_variable;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148 var->data = (uintptr_t) ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
149
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150 if (ngx_array_init(&ctx->parts, cf->pool, 2,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151 sizeof(ngx_http_split_clients_part_t))
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
152 != NGX_OK)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
153 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
154 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
155 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
156
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
157 save = *cf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
158 cf->ctx = ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
159 cf->handler = ngx_http_split_clients;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
160 cf->handler_conf = conf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
161
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
162 rv = ngx_conf_parse(cf, NULL);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
163
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
164 *cf = save;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
165
3607
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
166 if (rv != NGX_CONF_OK) {
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
167 return rv;
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
168 }
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
169
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
170 sum = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
171 last = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
172 part = ctx->parts.elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
173
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174 for (i = 0; i < ctx->parts.nelts; i++) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
175 sum = part[i].percent ? sum + part[i].percent : 10000;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
176 if (sum > 10000) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
177 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
178 "percent sum is more than 100%%");
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
180 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
181
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
182 if (part[i].percent) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
183 part[i].percent = (uint32_t)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
184 (last + 0xffffffff / 10000 * part[i].percent);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
185 } else {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
186 part[i].percent = 0xffffffff;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
187 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
188
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
189 last = part[i].percent;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
190 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
191
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
192 return rv;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
193 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
194
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
195
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
196 static char *
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
197 ngx_http_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
198 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
199 ngx_int_t n;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
200 ngx_str_t *value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
201 ngx_http_split_clients_ctx_t *ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
202 ngx_http_split_clients_part_t *part;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
203
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
204 ctx = cf->ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
205 value = cf->args->elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
206
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
207 part = ngx_array_push(&ctx->parts);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
208 if (part == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
209 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
210 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
211
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
212 if (value[0].len == 1 && value[0].data[0] == '*') {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
213 part->percent = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
214
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
215 } else {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
216 if (value[0].data[value[0].len - 1] != '%') {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
217 goto invalid;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
218 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
219
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
220 n = ngx_atofp(value[0].data, value[0].len - 1, 2);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
221 if (n == NGX_ERROR || n == 0) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
222 goto invalid;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
223 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
224
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
225 part->percent = (uint32_t) n;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
226 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
228 part->value.len = value[1].len;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
229 part->value.valid = 1;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
230 part->value.no_cacheable = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231 part->value.not_found = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
232 part->value.data = value[1].data;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
234 return NGX_CONF_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
235
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
236 invalid:
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
238 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
239 "invalid percent value \"%V\"", &value[0]);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
240 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
241 }