Line data Source code
1 : #ifndef DDEBUG
2 : #define DDEBUG 0
3 : #endif
4 : #include "ddebug.h"
5 :
6 : #include "ngx_http_set_hashed_upstream.h"
7 :
8 :
9 : ngx_uint_t
10 0 : ngx_http_set_misc_apply_distribution(ngx_log_t *log, ngx_uint_t hash,
11 : ndk_upstream_list_t *ul, ngx_http_set_misc_distribution_t type)
12 : {
13 0 : switch (type) {
14 0 : case ngx_http_set_misc_distribution_modula:
15 0 : return (uint32_t) hash % (uint32_t) ul->nelts;
16 :
17 0 : default:
18 0 : ngx_log_error(NGX_LOG_ERR, log, 0, "apply_distribution: "
19 : "unknown distribution: %d", type);
20 :
21 0 : return 0;
22 : }
23 :
24 : /* impossible to reach here */
25 : }
26 :
27 :
28 : ngx_int_t
29 0 : ngx_http_set_misc_set_hashed_upstream(ngx_http_request_t *r, ngx_str_t *res,
30 : ngx_http_variable_value_t *v, void *data)
31 : {
32 : ngx_str_t **u;
33 0 : ndk_upstream_list_t *ul = data;
34 : ngx_str_t ulname;
35 : ngx_uint_t hash, index;
36 : ngx_http_variable_value_t *key;
37 :
38 0 : if (ul == NULL) {
39 0 : ulname.data = v->data;
40 0 : ulname.len = v->len;
41 :
42 : dd("ulname: %.*s", (int) ulname.len, ulname.data);
43 :
44 0 : ul = ndk_get_upstream_list(ndk_http_get_main_conf(r),
45 : ulname.data, ulname.len);
46 :
47 0 : if (ul == NULL) {
48 0 : ngx_log_error(NGX_LOG_ERR, r->connection->log, 0,
49 : "set_hashed_upstream: upstream list \"%V\" "
50 : "not defined yet", &ulname);
51 0 : return NGX_ERROR;
52 : }
53 :
54 0 : key = v + 1;
55 : } else {
56 0 : key = v;
57 : }
58 :
59 0 : if (ul->nelts == 0) {
60 0 : res->data = NULL;
61 0 : res->len = 0;
62 :
63 0 : return NGX_OK;
64 : }
65 :
66 0 : u = ul->elts;
67 :
68 : dd("upstream list: %d upstreams found", (int) ul->nelts);
69 :
70 0 : if (ul->nelts == 1) {
71 : dd("only one upstream found in the list");
72 :
73 0 : res->data = u[0]->data;
74 0 : res->len = u[0]->len;
75 :
76 0 : return NGX_OK;
77 : }
78 :
79 : dd("key: \"%.*s\"", key->len, key->data);
80 :
81 0 : hash = ngx_hash_key_lc(key->data, key->len);
82 :
83 0 : index = ngx_http_set_misc_apply_distribution(r->connection->log, hash, ul,
84 : ngx_http_set_misc_distribution_modula);
85 :
86 0 : res->data = u[index]->data;
87 0 : res->len = u[index]->len;
88 :
89 0 : return NGX_OK;
90 : }
91 :
92 :
93 : char *
94 0 : ngx_http_set_hashed_upstream(ngx_conf_t *cf, ngx_command_t *cmd, void *conf)
95 : {
96 : ngx_str_t *value;
97 : ndk_set_var_t filter;
98 : ngx_uint_t n;
99 : ngx_str_t *var;
100 : ngx_str_t *ulname;
101 : ndk_upstream_list_t *ul;
102 : ngx_str_t *v;
103 :
104 0 : value = cf->args->elts;
105 :
106 0 : var = &value[1];
107 0 : ulname = &value[2];
108 :
109 0 : n = ngx_http_script_variables_count(ulname);
110 :
111 0 : filter.func = (void *) ngx_http_set_misc_set_hashed_upstream;
112 :
113 0 : if (n) {
114 : /* upstream list name contains variables */
115 0 : v = &value[2];
116 0 : filter.size = 2;
117 0 : filter.data = NULL;
118 0 : filter.type = NDK_SET_VAR_MULTI_VALUE_DATA;
119 :
120 0 : return ndk_set_var_multi_value_core(cf, var, v, &filter);
121 : }
122 :
123 0 : ul = ndk_get_upstream_list(ndk_http_conf_get_main_conf(cf),
124 : ulname->data, ulname->len);
125 0 : if (ul == NULL) {
126 0 : ngx_log_error(NGX_LOG_ERR, cf->log, 0,
127 : "set_hashed_upstream: upstream list \"%V\" "
128 : "not defined yet", ulname);
129 0 : return NGX_CONF_ERROR;
130 : }
131 :
132 0 : v = &value[3];
133 :
134 0 : filter.size = 1;
135 0 : filter.data = ul;
136 0 : filter.type = NDK_SET_VAR_VALUE_DATA;
137 :
138 0 : return ndk_set_var_value_core(cf, var, v, &filter);
139 : }
140 :
|