18
18
use think \Response ;
19
19
use think \Session ;
20
20
use TypeError ;
21
- use function sprintf ;
22
21
23
22
/**
24
23
* 访问频率限制中间件
27
26
*/
28
27
class Throttle
29
28
{
29
+ const WAIT = '__WAIT__ ' ;
30
30
/**
31
31
* 默认配置参数
32
32
* @var array
@@ -38,7 +38,7 @@ class Throttle
38
38
'visit_rate ' => '' , // 节流频率, 空字符串表示不限制 eg: '', '10/m', '20/h', '300/d'
39
39
'visit_enable_show_rate_limit ' => true , // 在响应体中设置速率限制的头部信息
40
40
'visit_fail_code ' => 429 , // 访问受限时返回的 http 状态码,当没有 visit_fail_response 时生效
41
- 'visit_fail_text ' => 'Too many requests, try again after __WAIT__ seconds. ' , // 访问受限时访问的文本信息
41
+ 'visit_fail_text ' => 'Too many requests, try again after ' . self :: WAIT . ' seconds. ' , // 访问受限时访问的文本信息
42
42
'visit_fail_response ' => null , // 访问受限时的响应信息闭包回调
43
43
'driver_name ' => CounterFixed::class, // 限流算法驱动
44
44
];
@@ -175,13 +175,14 @@ protected function getCacheKey(Request $request, string|bool|Closure $key, strin
175
175
if ($ key === true ) {
176
176
$ key = $ request ->ip ();
177
177
} elseif (is_string ($ key ) && str_contains ($ key , '__ ' )) {
178
- $ key = str_replace (['__CONTROLLER__ ' , '__ACTION__ ' , '__IP__ ' , '__SESSION__ ' ],
178
+ $ key = str_replace ([RateLimitAnnotation::CONTROLLER , RateLimitAnnotation::ACTION , RateLimitAnnotation::IP ,
179
+ RateLimitAnnotation::SESSION ],
179
180
[$ request ->controller (), $ request ->action (), $ request ->ip (), $ this ->session ->getId ()],
180
181
$ key );
181
182
}
182
183
183
184
if ($ annotation ) {
184
- // 注解需要以实际方法作为前缀
185
+ // 注解方式的需添加以实际方法作为前缀
185
186
$ key = $ request ->controller () . $ request ->action () . $ key ;
186
187
}
187
188
@@ -262,14 +263,14 @@ protected function allowRequestByConfig(Request $request): bool
262
263
*/
263
264
public function buildLimitException (int $ wait_seconds , Request $ request ): HttpResponseException
264
265
{
265
- $ visitFail = $ this ->config ['visit_fail_response ' ] ?? null ;
266
+ $ visitFail = $ this ->config ['visit_fail_response ' ];
266
267
if ($ visitFail instanceof Closure) {
267
268
$ response = Container::getInstance ()->invokeFunction ($ visitFail , [$ this , $ request , $ wait_seconds ]);
268
269
if (!$ response instanceof Response) {
269
- throw new TypeError (sprintf ( 'The closure must return %s instance ' , Response::class) );
270
+ throw new TypeError ('The closure must return ' . Response::class . ' instance ' );
270
271
}
271
272
} else {
272
- $ content = str_replace (' __WAIT__ ' , (string )$ wait_seconds , $ this ->getFailMessage ());
273
+ $ content = str_replace (self :: WAIT , (string )$ wait_seconds , $ this ->getFailMessage ());
273
274
$ response = Response::create ($ content )->code ($ this ->config ['visit_fail_code ' ]);
274
275
}
275
276
if ($ this ->config ['visit_enable_show_rate_limit ' ]) {
0 commit comments