annotate src/http/modules/ngx_http_split_clients_module.c @ 7676:d225b70d38b6

Proxy: detection of data after final chunk. Previously, additional data after final chunk was either ignored (in the same buffer, or during unbuffered proxying) or sent to the client (in the next buffer already if it was already read from the socket). Now additional data are properly detected and ignored in all cases. Additionally, a warning is now logged and keepalive is disabled in the connection.
author Maxim Dounin <mdounin@mdounin.ru>
date Mon, 06 Jul 2020 18:36:20 +0300
parents b78cf2414fda
children
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
4412
d620f497c50f Copyright updated.
Maxim Konovalov <maxim@nginx.com>
parents: 3918
diff changeset
4 * Copyright (C) Nginx, Inc.
3513
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
8 #include <ngx_config.h>
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
9 #include <ngx_core.h>
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
10 #include <ngx_http.h>
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
13 typedef struct {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
14 uint32_t percent;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
15 ngx_http_variable_value_t value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
16 } ngx_http_split_clients_part_t;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
19 typedef struct {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
20 ngx_http_complex_value_t value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
21 ngx_array_t parts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
22 } ngx_http_split_clients_ctx_t;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
25 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
26 void *conf);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
27 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
28 void *conf);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
29
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
30 static ngx_command_t ngx_http_split_clients_commands[] = {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
31
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
32 { ngx_string("split_clients"),
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
33 NGX_HTTP_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34 ngx_conf_split_clients_block,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
35 NGX_HTTP_MAIN_CONF_OFFSET,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
36 0,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
37 NULL },
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
38
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
39 ngx_null_command
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
43 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
44 NULL, /* preconfiguration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
45 NULL, /* postconfiguration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
46
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
47 NULL, /* create main configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
48 NULL, /* init main configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
49
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
50 NULL, /* create server configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
51 NULL, /* merge server configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
52
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
53 NULL, /* create location configuration */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54 NULL /* merge location configuration */
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
58 ngx_module_t ngx_http_split_clients_module = {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
59 NGX_MODULE_V1,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 &ngx_http_split_clients_module_ctx, /* module context */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 ngx_http_split_clients_commands, /* module directives */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62 NGX_HTTP_MODULE, /* module type */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63 NULL, /* init master */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 NULL, /* init module */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65 NULL, /* init process */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 NULL, /* init thread */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 NULL, /* exit thread */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 NULL, /* exit process */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69 NULL, /* exit master */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
70 NGX_MODULE_V1_PADDING
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 static ngx_int_t
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
75 ngx_http_split_clients_variable(ngx_http_request_t *r,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
76 ngx_http_variable_value_t *v, uintptr_t data)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
78 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
79
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
80 uint32_t hash;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
81 ngx_str_t val;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
82 ngx_uint_t i;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
83 ngx_http_split_clients_part_t *part;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
85 *v = ngx_http_variable_null_value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
86
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87 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
88 return NGX_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
89 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
90
3892
12d8d2f30205 use MurmurHash2 for split_clients, because
Igor Sysoev <igor@sysoev.ru>
parents: 3607
diff changeset
91 hash = ngx_murmur_hash2(val.data, val.len);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
92
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
93 part = ctx->parts.elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
95 for (i = 0; i < ctx->parts.nelts; i++) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
96
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
97 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
98 "http split: %uD %uD", hash, part[i].percent);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
100 if (hash < part[i].percent || part[i].percent == 0) {
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
101 *v = part[i].value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
102 return NGX_OK;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
106 return NGX_OK;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
110 static char *
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 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
112 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113 char *rv;
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
114 uint32_t sum, last;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 ngx_str_t *value, name;
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
116 ngx_uint_t i;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
117 ngx_conf_t save;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
118 ngx_http_variable_t *var;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
119 ngx_http_split_clients_ctx_t *ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
120 ngx_http_split_clients_part_t *part;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
121 ngx_http_compile_complex_value_t ccv;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
122
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
123 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
124 if (ctx == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
125 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
126 }
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 value = cf->args->elts;
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 ngx_memzero(&ccv, sizeof(ngx_http_compile_complex_value_t));
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
131
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
132 ccv.cf = cf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
133 ccv.value = &value[1];
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
134 ccv.complex_value = &ctx->value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
135
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
136 if (ngx_http_compile_complex_value(&ccv) != NGX_OK) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
137 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
138 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
139
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
140 name = value[2];
4635
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
141
4972
8b635cf36ccc Added checks that disallow adding a variable with an empty name.
Ruslan Ermilov <ru@nginx.com>
parents: 4635
diff changeset
142 if (name.data[0] != '$') {
4635
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
143 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
144 "invalid variable name \"%V\"", &name);
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
145 return NGX_CONF_ERROR;
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
146 }
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
147
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148 name.len--;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
149 name.data++;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151 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
152 if (var == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
153 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
154 }
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 var->get_handler = ngx_http_split_clients_variable;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
157 var->data = (uintptr_t) ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
158
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
159 if (ngx_array_init(&ctx->parts, cf->pool, 2,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
160 sizeof(ngx_http_split_clients_part_t))
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
161 != NGX_OK)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
162 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
163 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
164 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
165
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
166 save = *cf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
167 cf->ctx = ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
168 cf->handler = ngx_http_split_clients;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
169 cf->handler_conf = conf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
170
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
171 rv = ngx_conf_parse(cf, NULL);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
172
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
173 *cf = save;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
174
3607
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
175 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
176 return rv;
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
177 }
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
178
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179 sum = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
180 last = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
181 part = ctx->parts.elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
182
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
183 for (i = 0; i < ctx->parts.nelts; i++) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
184 sum = part[i].percent ? sum + part[i].percent : 10000;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
185 if (sum > 10000) {
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
186 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
4593
834049edae24 Fixed grammar in error messages.
Ruslan Ermilov <ru@nginx.com>
parents: 4561
diff changeset
187 "percent total is greater than 100%%");
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
188 return NGX_CONF_ERROR;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
189 }
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 if (part[i].percent) {
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
192 last += part[i].percent * (uint64_t) 0xffffffff / 10000;
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
193 part[i].percent = last;
3513
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
197 return rv;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
200
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
201 static char *
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
202 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
203 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
204 ngx_int_t n;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
205 ngx_str_t *value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
206 ngx_http_split_clients_ctx_t *ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
207 ngx_http_split_clients_part_t *part;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
208
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
209 ctx = cf->ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
210 value = cf->args->elts;
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 part = ngx_array_push(&ctx->parts);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
213 if (part == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
214 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
215 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
216
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
217 if (value[0].len == 1 && value[0].data[0] == '*') {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
218 part->percent = 0;
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 } else {
5128
b78cf2414fda Split clients: check length when parsing configuration.
Ruslan Ermilov <ru@nginx.com>
parents: 4972
diff changeset
221 if (value[0].len == 0 || value[0].data[value[0].len - 1] != '%') {
3513
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 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
226 if (n == NGX_ERROR || n == 0) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
227 goto invalid;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
228 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
229
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
230 part->percent = (uint32_t) n;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
232
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233 part->value.len = value[1].len;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
234 part->value.valid = 1;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
235 part->value.no_cacheable = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
236 part->value.not_found = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237 part->value.data = value[1].data;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
238
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
239 return NGX_CONF_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
240
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
241 invalid:
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
242
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
243 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
244 "invalid percent value \"%V\"", &value[0]);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
245 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
246 }