annotate src/stream/ngx_stream_split_clients_module.c @ 7690:8253424d1aff

Added size check to ngx_http_alloc_large_header_buffer(). This ensures that copying won't write more than the buffer size even if the buffer comes from hc->free and it is smaller than the large client header buffer size in the virtual host configuration. This might happen if size of large client header buffers is different in name-based virtual hosts, similarly to the problem with number of buffers fixed in 6926:e662cbf1b932.
author Maxim Dounin <mdounin@mdounin.ru>
date Thu, 06 Aug 2020 05:02:22 +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 }