14
14
#include " ngx_http_polaris_limit_module.h"
15
15
16
16
typedef struct {
17
- ngx_str_t service_namespace; // 命名空间
18
-
19
- ngx_str_t service_name; // 服务名
17
+ ngx_int_t enable; // 是否启用限流
20
18
21
19
ngx_int_t status_code; // 返回码
22
20
21
+ std::string service_namespace; // 命名空间
22
+
23
+ std::string service_name; // 服务名
24
+
23
25
} ngx_http_polaris_limit_conf_t ;
24
26
25
27
static ngx_int_t ngx_http_polaris_limit_handler (ngx_http_request_t *r);
@@ -82,20 +84,18 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
82
84
std::map<std::string, std::string> labels;
83
85
const std::set<std::string> *label_keys;
84
86
85
- ngx_str_t service_namespace_str;
86
- ngx_str_t service_name_str;
87
87
plcf = reinterpret_cast <ngx_http_polaris_limit_conf_t *>(
88
88
ngx_http_get_module_loc_conf (r, ngx_http_polaris_limit_module));
89
- service_namespace_str = plcf->service_namespace ;
90
- service_name_str =plcf->service_name ;
91
89
90
+ if (plcf->enable == 0 ) {
91
+ return NGX_DECLINED;
92
+ }
92
93
polaris::LimitApi* limit_api = Limit_API_SINGLETON.GetLimitApi ();
93
94
if (NULL == limit_api) {
94
- return NGX_OK ;
95
+ return NGX_DECLINED ;
95
96
}
96
- std::string service_namespace (reinterpret_cast <char *>(service_namespace_str.data ), service_namespace_str.len );
97
- std::string service_name (reinterpret_cast <char *>(service_name_str.data ), service_name_str.len );
98
- polaris::ServiceKey serviceKey = {service_namespace, service_name};
97
+
98
+ polaris::ServiceKey serviceKey = {plcf->service_namespace , plcf->service_name };
99
99
std::string method = std::string (reinterpret_cast <char *>(r->uri .data ), r->uri .len );
100
100
ret = Limit_API_SINGLETON.GetLimitApi ()->FetchRuleLabelKeys (serviceKey, label_keys);
101
101
@@ -105,22 +105,22 @@ static ngx_int_t ngx_http_polaris_limit_handler(ngx_http_request_t *r) {
105
105
}
106
106
ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 , " [PolarisRateLimiting] FetchRuleLabelKeys return is: %d, labels %s" , ret, labels_key_str.c_str ());
107
107
if (ret == polaris::kReturnTimeout ) {
108
- return NGX_DECLINED; // 拉取labelkey超时,不限流
108
+ return NGX_DECLINED; // 拉取labelkey超时,不限流
109
109
} else if (ret != polaris::kReturnOk ) {
110
110
return plcf->status_code ; // 返回为限流配置的状态码
111
111
}
112
112
113
113
get_labels_from_request (r, label_keys, labels); // 从http 请求中获取labels
114
114
std::string uri (reinterpret_cast <char *>(r->uri .data ), r->uri .len );
115
- quota_request.SetServiceNamespace (service_namespace); // 设置限流规则对应服务的命名空间
116
- quota_request.SetServiceName (service_name); // 设置限流规则对应的服务名
115
+ quota_request.SetServiceNamespace (plcf-> service_namespace ); // 设置限流规则对应服务的命名空间
116
+ quota_request.SetServiceName (plcf-> service_name ); // 设置限流规则对应的服务名
117
117
quota_request.SetMethod (uri);
118
118
quota_request.SetLabels (labels); // 设置label用于匹配限流规则
119
119
120
120
std::string labels_values_str;
121
121
join_map_str (r->connection ->log , labels, labels_values_str);
122
122
ngx_log_debug (NGX_LOG_DEBUG_HTTP, r->connection ->log , 0 ,
123
- " [PolarisRateLimiting] quota_request namespace %s, service %s, method %s, labels %s" , service_namespace.c_str (), service_name.c_str (), uri.c_str (), labels_values_str.c_str ());
123
+ " [PolarisRateLimiting] quota_request namespace %s, service %s, method %s, labels %s" , plcf-> service_namespace .c_str (), plcf-> service_name .c_str (), uri.c_str (), labels_values_str.c_str ());
124
124
125
125
ret = Limit_API_SINGLETON.GetLimitApi ()->GetQuota (quota_request, result);
126
126
@@ -160,6 +160,10 @@ static void join_map_str(const ngx_log_t *log, const std::map<std::string, std::
160
160
}
161
161
}
162
162
163
+ bool string2bool (const std::string & v) {
164
+ return !v.empty () && (strcasecmp (v.c_str (), " true" ) == 0 || atoi (v.c_str ()) != 0 );
165
+ }
166
+
163
167
/* 读取配置参数 polaris_limit */
164
168
static char *ngx_http_polaris_limit_conf_set (ngx_conf_t *cf, ngx_command_t *cmd, void *conf) {
165
169
ngx_http_polaris_limit_conf_t *plcf;
@@ -168,34 +172,80 @@ static char *ngx_http_polaris_limit_conf_set(ngx_conf_t *cf, ngx_command_t *cmd,
168
172
plcf = reinterpret_cast <ngx_http_polaris_limit_conf_t *>(conf);
169
173
value = reinterpret_cast <ngx_str_t *>(cf->args ->elts );
170
174
175
+ bool has_namespace = false ;
176
+ bool has_service = false ;
177
+ bool has_enable = false ;
178
+
171
179
for (i = 1 ; i < cf->args ->nelts ; i++) {
172
180
if (ngx_strncmp (value[i].data , KEY_NAMESPACE, KEY_NAMESPACE_SIZE) == 0 ) {
173
181
size_t ns_size = value[i].len - KEY_NAMESPACE_SIZE;
174
- if (ns_size <= 0 ) {
175
- ngx_str_t namespace_str = {DEFAULT_NAMESPACE_SIZE, (u_char *)DEFAULT_NAMESPACE};
176
- plcf->service_namespace = namespace_str;
177
- ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] nginx namespace not set, use 'default' as namespace" );
178
- } else {
182
+ if (ns_size > 0 ) {
179
183
ngx_str_t namespace_str = {value[i].len - KEY_NAMESPACE_SIZE, &value[i].data [KEY_NAMESPACE_SIZE]};
180
- plcf->service_namespace = namespace_str;
181
184
ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %V as nginx namespace" , &namespace_str);
185
+ plcf->service_namespace = std::string (reinterpret_cast <char *>(namespace_str.data ), namespace_str.len );
186
+ has_namespace = true ;
182
187
}
183
188
continue ;
184
189
}
185
190
186
191
if (ngx_strncmp (value[i].data , KEY_SERVICE_NAME, KEY_SERVICE_NAME_SIZE) == 0 ) {
187
- ngx_str_t svc_name_str = {value[i].len - KEY_SERVICE_NAME_SIZE, &value[i].data [KEY_SERVICE_NAME_SIZE]};
188
- plcf->service_name = svc_name_str;
189
- if (plcf->service_name .len <= 0 ) {
190
- plcf->service_name .data = NULL ;
191
- plcf->service_name .len = 0 ;
192
- ngx_conf_log_error (NGX_LOG_ERR, cf, 0 , " [PolarisRateLimiting] service name not set" );
193
- return static_cast <char *>(NGX_CONF_ERROR);
194
- } else {
195
- ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %V as service" , &svc_name_str);
192
+ size_t svc_size = value[i].len - KEY_SERVICE_NAME_SIZE;
193
+ if (svc_size > 0 ) {
194
+ ngx_str_t svc_name_str = {value[i].len - KEY_SERVICE_NAME_SIZE, &value[i].data [KEY_SERVICE_NAME_SIZE]};
195
+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %V as nginx service name" , &svc_name_str);
196
+ plcf->service_name = std::string (reinterpret_cast <char *>(svc_name_str.data ), svc_name_str.len );
197
+ has_service = true ;
198
+ }
199
+ continue ;
200
+ }
201
+
202
+ if (ngx_strncmp (value[i].data , KEY_ENABLE, KEY_ENABLE_SIZE) == 0 ) {
203
+ size_t enable_size = value[i].len - KEY_ENABLE_SIZE;
204
+ if (enable_size > 0 ) {
205
+ ngx_str_t enable_str = {value[i].len - KEY_ENABLE_SIZE, &value[i].data [KEY_ENABLE_SIZE]};
206
+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %V as nginx ratelimit enable value" , &enable_str);
207
+ std::string enable_str_value = std::string (reinterpret_cast <char *>(enable_str.data ), enable_str.len );
208
+ if (string2bool (enable_str_value)) {
209
+ plcf->enable = 1 ;
210
+ } else {
211
+ plcf->enable = 0 ;
212
+ }
213
+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %V as nginx ratelimit enable" , plcf->enable );
214
+ has_enable = true ;
196
215
}
197
216
continue ;
198
217
}
218
+
219
+ if (!has_namespace) {
220
+ char *namespace_env_value = getenv (ENV_NAMESPACE.c_str ());
221
+ if (NULL != namespace_env_value) {
222
+ plcf->service_namespace = std::string (namespace_env_value);
223
+ } else {
224
+ plcf->service_namespace = DEFAULT_NAMESPACE;
225
+ }
226
+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %s as nginx namespace" , plcf->service_namespace .c_str ());
227
+ }
228
+
229
+ if (!has_service) {
230
+ char *service_env_value = getenv (ENV_SERVICE.c_str ());
231
+ if (NULL != service_env_value) {
232
+ plcf->service_name = std::string (service_env_value);
233
+ } else {
234
+ plcf->service_name = DEFAULT_SERVICE;
235
+ }
236
+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %s as nginx service name" , plcf->service_name .c_str ());
237
+ }
238
+
239
+ if (!has_enable) {
240
+ char *enable_env_value = getenv (ENV_RATELIMIT_ENABLE.c_str ());
241
+ if (NULL != enable_env_value) {
242
+ std::string enable_str = std::string (enable_env_value);
243
+ plcf->enable = string2bool (enable_str) ? 1 : 0 ;
244
+ } else {
245
+ plcf->enable = 0 ;
246
+ }
247
+ ngx_conf_log_error (NGX_LOG_NOTICE, cf, 0 , " [PolarisRateLimiting] use %V as nginx ratelimit enable" , plcf->enable );
248
+ }
199
249
}
200
250
201
251
return static_cast <char *>(NGX_CONF_OK);
0 commit comments