mirror of
https://github.com/Rain-kl/OpenFlare.git
synced 2026-10-13 18:36:37 +08:00
feat(rate-limit): 站点级请求频率限制支持继承与自定义
在站点详情流量限制中配置 limit_req_per_ip;渲染按 effective rate 生成多 limit_req_zone,并以站点+IP 隔离计数。
This commit is contained in:
@@ -19,7 +19,9 @@ import type { ProxyRouteItem } from '@/lib/services/openflare';
|
||||
|
||||
import {
|
||||
normalizeLimitRate,
|
||||
normalizeLimitReqPerIP,
|
||||
validateLimitRate,
|
||||
validateLimitReqPerIP,
|
||||
} from '../../components/helpers';
|
||||
import { proxyRouteFormIds } from '../helpers';
|
||||
import { useRouteSectionSave } from '../hooks/use-route-section-save';
|
||||
@@ -30,6 +32,7 @@ const rateLimitSchema = z
|
||||
limit_conn_per_server: z.string(),
|
||||
limit_conn_per_ip: z.string(),
|
||||
limit_rate: z.string(),
|
||||
limit_req_per_ip: z.string(),
|
||||
})
|
||||
.superRefine((value, context) => {
|
||||
for (const field of [
|
||||
@@ -57,6 +60,15 @@ const rateLimitSchema = z
|
||||
message: limitRateError,
|
||||
});
|
||||
}
|
||||
|
||||
const limitReqError = validateLimitReqPerIP(value.limit_req_per_ip);
|
||||
if (limitReqError) {
|
||||
context.addIssue({
|
||||
code: z.ZodIssueCode.custom,
|
||||
path: ['limit_req_per_ip'],
|
||||
message: limitReqError,
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
type RateLimitValues = z.infer<typeof rateLimitSchema>;
|
||||
@@ -99,6 +111,7 @@ export function LimitsSection({
|
||||
limit_conn_per_server: formatConnValue(route.limit_conn_per_server),
|
||||
limit_conn_per_ip: formatConnValue(route.limit_conn_per_ip),
|
||||
limit_rate: route.limit_rate || '',
|
||||
limit_req_per_ip: route.limit_req_per_ip || '',
|
||||
},
|
||||
});
|
||||
|
||||
@@ -107,6 +120,7 @@ export function LimitsSection({
|
||||
limit_conn_per_server: formatConnValue(route.limit_conn_per_server),
|
||||
limit_conn_per_ip: formatConnValue(route.limit_conn_per_ip),
|
||||
limit_rate: route.limit_rate || '',
|
||||
limit_req_per_ip: route.limit_req_per_ip || '',
|
||||
});
|
||||
}, [form, route]);
|
||||
|
||||
@@ -129,6 +143,9 @@ export function LimitsSection({
|
||||
),
|
||||
limit_conn_per_ip: parseConnValue(values.limit_conn_per_ip),
|
||||
limit_rate: normalizeLimitRate(values.limit_rate),
|
||||
limit_req_per_ip: normalizeLimitReqPerIP(
|
||||
values.limit_req_per_ip,
|
||||
),
|
||||
},
|
||||
'流量限制已保存',
|
||||
);
|
||||
@@ -172,7 +189,7 @@ export function LimitsSection({
|
||||
control={form.control}
|
||||
name='limit_rate'
|
||||
render={({ field }) => (
|
||||
<FormItem className='md:col-span-2'>
|
||||
<FormItem>
|
||||
<FormLabel>限速</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder='512k/1m 或 -1' {...field} />
|
||||
@@ -184,6 +201,24 @@ export function LimitsSection({
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name='limit_req_per_ip'
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>单 IP 请求频率</FormLabel>
|
||||
<FormControl>
|
||||
<Input placeholder='10r/s / 100r/m 或 -1' {...field} />
|
||||
</FormControl>
|
||||
<FormDescription>
|
||||
空或 0 继承全局默认;-1 关闭;例如 10r/s、100r/m
|
||||
为自定义频率。
|
||||
</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</form>
|
||||
</Form>
|
||||
</SectionShell>
|
||||
|
||||
Reference in New Issue
Block a user