annotate src/stream/ngx_stream_split_clients_module.c @ 7660:d33e17499088

Version bump.
author Maxim Dounin <mdounin@mdounin.ru>
date Tue, 26 May 2020 22:03:00 +0300
parents 787dcc15b802
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>
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
10 #include <ngx_stream.h>
3513
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 {
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
14 uint32_t percent;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
15 ngx_stream_variable_value_t value;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
16 } ngx_stream_split_clients_part_t;
3513
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 {
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
20 ngx_stream_complex_value_t value;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
21 ngx_array_t parts;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
22 } ngx_stream_split_clients_ctx_t;
3513
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);
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
27 static char *ngx_stream_split_clients(ngx_conf_t *cf, ngx_command_t *dummy,
3513
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
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
30 static ngx_command_t ngx_stream_split_clients_commands[] = {
3513
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"),
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
33 NGX_STREAM_MAIN_CONF|NGX_CONF_BLOCK|NGX_CONF_TAKE2,
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
34 ngx_conf_split_clients_block,
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
35 NGX_STREAM_MAIN_CONF_OFFSET,
3513
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
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
43 static ngx_stream_module_t ngx_stream_split_clients_module_ctx = {
3513
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 */
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
51 NULL /* merge server configuration */
3513
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
54
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
55 ngx_module_t ngx_stream_split_clients_module = {
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
56 NGX_MODULE_V1,
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
57 &ngx_stream_split_clients_module_ctx, /* module context */
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
58 ngx_stream_split_clients_commands, /* module directives */
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
59 NGX_STREAM_MODULE, /* module type */
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
60 NULL, /* init master */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
61 NULL, /* init module */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
62 NULL, /* init process */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
63 NULL, /* init thread */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
64 NULL, /* exit thread */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
65 NULL, /* exit process */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
66 NULL, /* exit master */
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
67 NGX_MODULE_V1_PADDING
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
68 };
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
69
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 static ngx_int_t
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
72 ngx_stream_split_clients_variable(ngx_stream_session_t *s,
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
73 ngx_stream_variable_value_t *v, uintptr_t data)
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
74 {
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
75 ngx_stream_split_clients_ctx_t *ctx =
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
76 (ngx_stream_split_clients_ctx_t *) data;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
77
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
78 uint32_t hash;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
79 ngx_str_t val;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
80 ngx_uint_t i;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
81 ngx_stream_split_clients_part_t *part;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
82
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
83 *v = ngx_stream_variable_null_value;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
84
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
85 if (ngx_stream_complex_value(s, &ctx->value, &val) != NGX_OK) {
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
86 return NGX_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
87 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
88
3892
12d8d2f30205 use MurmurHash2 for split_clients, because
Igor Sysoev <igor@sysoev.ru>
parents: 3607
diff changeset
89 hash = ngx_murmur_hash2(val.data, val.len);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
90
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
91 part = ctx->parts.elts;
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 for (i = 0; i < ctx->parts.nelts; i++) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
94
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
95 ngx_log_debug2(NGX_LOG_DEBUG_STREAM, s->connection->log, 0,
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
96 "stream split: %uD %uD", hash, part[i].percent);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
97
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
98 if (hash < part[i].percent || part[i].percent == 0) {
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
99 *v = part[i].value;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
100 return NGX_OK;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
101 }
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 return NGX_OK;
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
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 static char *
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
109 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
110 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
111 char *rv;
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
112 uint32_t sum, last;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
113 ngx_str_t *value, name;
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
114 ngx_uint_t i;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
115 ngx_conf_t save;
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
116 ngx_stream_variable_t *var;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
117 ngx_stream_split_clients_ctx_t *ctx;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
118 ngx_stream_split_clients_part_t *part;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
119 ngx_stream_compile_complex_value_t ccv;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
120
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
121 ctx = ngx_pcalloc(cf->pool, sizeof(ngx_stream_split_clients_ctx_t));
3513
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
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
128 ngx_memzero(&ccv, sizeof(ngx_stream_compile_complex_value_t));
3513
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
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
134 if (ngx_stream_compile_complex_value(&ccv) != NGX_OK) {
3513
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];
4635
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
139
4972
8b635cf36ccc Added checks that disallow adding a variable with an empty name.
Ruslan Ermilov <ru@nginx.com>
parents: 4635
diff changeset
140 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
141 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
142 "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
143 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
144 }
9c9fbdbe9383 Added syntax checking of the second parameter of the "split_clients" directive.
Ruslan Ermilov <ru@nginx.com>
parents: 4593
diff changeset
145
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
146 name.len--;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
147 name.data++;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
148
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
149 var = ngx_stream_add_variable(cf, &name, NGX_STREAM_VAR_CHANGEABLE);
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
150 if (var == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
151 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
152 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
153
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
154 var->get_handler = ngx_stream_split_clients_variable;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
155 var->data = (uintptr_t) ctx;
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 if (ngx_array_init(&ctx->parts, cf->pool, 2,
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
158 sizeof(ngx_stream_split_clients_part_t))
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
159 != NGX_OK)
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
160 {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
161 return NGX_CONF_ERROR;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
164 save = *cf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
165 cf->ctx = ctx;
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
166 cf->handler = ngx_stream_split_clients;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
167 cf->handler_conf = conf;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
168
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
169 rv = ngx_conf_parse(cf, NULL);
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 *cf = save;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
172
3607
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
173 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
174 return rv;
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
175 }
8bff43217171 do not try to calculate procent sum if there was an error
Igor Sysoev <igor@sysoev.ru>
parents: 3513
diff changeset
176
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
177 sum = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
178 last = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
179 part = ctx->parts.elts;
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 for (i = 0; i < ctx->parts.nelts; i++) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
182 sum = part[i].percent ? sum + part[i].percent : 10000;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
183 if (sum > 10000) {
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
184 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
185 "percent total is greater than 100%%");
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
186 return NGX_CONF_ERROR;
3513
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 if (part[i].percent) {
4561
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
190 last += part[i].percent * (uint64_t) 0xffffffff / 10000;
ae63013cbffa Fixed calculation of range boundaries.
Ruslan Ermilov <ru@nginx.com>
parents: 4412
diff changeset
191 part[i].percent = last;
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
192 }
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 return rv;
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
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 static char *
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
200 ngx_stream_split_clients(ngx_conf_t *cf, ngx_command_t *dummy, void *conf)
3513
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
201 {
6632
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
202 ngx_int_t n;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
203 ngx_str_t *value;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
204 ngx_stream_split_clients_ctx_t *ctx;
787dcc15b802 Stream: split_clients module.
Vladimir Homutov <vl@nginx.com>
parents: 5128
diff changeset
205 ngx_stream_split_clients_part_t *part;
3513
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 ctx = cf->ctx;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
208 value = cf->args->elts;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
209
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
210 part = ngx_array_push(&ctx->parts);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
211 if (part == NULL) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
212 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
213 }
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 if (value[0].len == 1 && value[0].data[0] == '*') {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
216 part->percent = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
217
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
218 } else {
5128
b78cf2414fda Split clients: check length when parsing configuration.
Ruslan Ermilov <ru@nginx.com>
parents: 4972
diff changeset
219 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
220 goto invalid;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
221 }
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
222
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
223 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
224 if (n == NGX_ERROR || n == 0) {
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
225 goto invalid;
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->percent = (uint32_t) n;
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
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
231 part->value.len = value[1].len;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
232 part->value.valid = 1;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
233 part->value.no_cacheable = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
234 part->value.not_found = 0;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
235 part->value.data = value[1].data;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
236
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
237 return NGX_CONF_OK;
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 invalid:
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 ngx_conf_log_error(NGX_LOG_EMERG, cf, 0,
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
242 "invalid percent value \"%V\"", &value[0]);
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
243 return NGX_CONF_ERROR;
e60e00b4fe0c ngx_http_split_clients_module
Igor Sysoev <igor@sysoev.ru>
parents:
diff changeset
244 }