使用Mojolicious::Plugin::OpenAPI时,能否在URL路径中包含IP地址?
使用Mojolicious::Plugin::OpenAPI时,能否在URL路径中包含IP地址?
当然可以!你遇到的404问题并不是因为IP地址里的.违反了RFC规则,而是Mojolicious路由的默认行为在搞鬼——它会把路径中的.当成文件扩展名的分隔符,导致192.168.1.1被拆成192.168.1(路径部分)和1(扩展名),完全匹配不到你定义的/echo/{ip}路由,所以返回了404。
下面给你两种解决方法,任选其一就能解决问题:
方法1:在OpenAPI定义中指定占位符匹配规则
修改你的api.yaml,给ip参数添加x-mojo-placeholder属性,明确告诉Mojolicious这个占位符可以包含.:
paths: /echo/{ip}: get: x-mojo-to: Example#echo parameters: - name: ip in: path required: true schema: type: string format: ipv4 pattern: ^(?:\d{1,3}\.){3}\d{1,3}$ # 可选,更严谨的IPv4格式校验 x-mojo-placeholder: '(.+)' # 允许匹配任意字符(包括.)
如果想更严谨,也可以把x-mojo-placeholder的值设为(\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}),精确匹配IPv4地址格式。
方法2:全局禁用路由的扩展名解析
在MyApp.pm的startup方法中,给OpenAPI生成的路由添加detour(ext => undef),直接关闭扩展名解析功能:
sub startup ($self) { # 先获取OpenAPI插件返回的路由对象 my $api_route = $self->plugin(OpenAPI => {url=>$self->home->rel_file("api.yaml")}); # 禁用扩展名解析 $api_route->detour(ext => undef); $self->plugin(SwaggerUI => {route=>$self->routes()->any('/swagger'),url=>"/api"}); }
修改完成后,再运行你的测试命令:
curl 'localhost:3000/api/echo/192.168.1.1'
就能得到你预期的响应:
{"ip": "192.168.1.1"}
备注:内容来源于stack exchange,提问作者h q
相关产品推荐
相关产品推荐

