Soul网关源码阅读番外篇(一) HTTP参数请求错误

在Soul网关2.2.1版本源码阅读中,遇到了HTTP请求加上参数返回404的错误,此篇文章基于此进行探索
摘要由CSDN通过智能技术生成

Soul网关源码阅读番外篇(一) HTTP参数请求错误


  • 共同作者:石立 萧 *

简介

    在Soul网关2.2.1版本源码阅读中,遇到了HTTP请求加上参数返回404的错误,此篇文章基于此进行探索

Bug复现

相关环境配置

    首先把代码拉下来,然后切换到2.2.1版本,命令大致如下:

# 加速拉取
git clone https://github.com.cnpmjs.org/lw1243925457/soul.git

# 切换到2.2.1版本
git fetch origin 2.2.1:2.2.1
git checkout 2.2.1

    如果之前运行过Soul网关的,需要清理下数据库,这里删除原来的soul数据库,让2.2.1版本自己重新建立一个

# 使用docker启动mysql
docker run --name mysql -p 3306:3306 -e MYSQL_ROOT_PASSWORD=root -d mysql:latest

# 重启,需要删除soul数据库,然后让程序自己重建
docker restart mysql
# 使用命令登录,删除原来的数据库
docker exec -ti mysql mysql -u root -p
> drop database soul;

Soul——Admin启动

    修改Soul-admin模块下的配置文件:soul-admin --> application-local.yml

    修改mysql用户和密码: root root

    修改链接配置:jdbc:mysql://localhost:3306/soul?useUnicode=true&characterEncoding=utf-8&allowPublicKeyRetrieval=true&&useSSL=false

    启动soul-admin --> SoulAdminBootstrap

    如果出现SelectorTypeEnum相关的错误,请切换到jdk8

启动Soul-Bootstrap

    启动soul-bootstrap --> SoulBootstrapApplication

启动HTTP test

    首先右键soul-test根目录下的pom.xml,选择 add as maven project,导入工程
    可能会出现依赖错误,将其版本替换为2.2.1,大致如下:

        <dependency>
            <groupId>org.dromara</groupId>
            <artifactId>soul-spring-boot-starter-client-springmvc</artifactId>
            <version>2.2.1</version>
        </dependency>

    启动soul-test --> soul-test-http --> SoulTestHttpApplication

请求复现

    访问管理界面: http://localhost:9095/ ,查看插件列表 --> divide ,表现正常

    访问问题链接: http://localhost:9195/http/order/findById?id=1 ,可以看到出现了404

{
   
    "timestamp": "2021-01-18T02:18:19.557+0000",
    "path": "/",
    "status": 404,
    "error": "Not Found",
    "message": null,
    "requestId": "84752141"
}

    直接访问: http://localhost:8187/order/findById?id=11 ,正常的

{
   
    "id": "11",
    "name": "hello world findById"
}

    OK,到这问题基本复现,下面开始debug

源码Debug

查看日志进行切入

    根据老哥的提示,我们也看到了这个问题请求的相关日志,大致如下

o.d.soul.plugin.base.AbstractSoulPlugin  : divide selector success match , selector name :/http
o.d.soul.plugin.base.AbstractSoulPlugin  : divide rule success match ,rule name :/http/order/findById
o.d.s.plugin.httpclient.WebClientPlugin  : you request,The resulting urlPath is :http://192.168.101.104:8187?id=1111

    最后一句urlpath非常的诡异,完整路径不对。我们就直接看下这个类: WebClientPlugin

    # WebClientPlugin
    public Mono<Void> execute(final ServerWebExchange exchange, final SoulPluginChain chain) {
   
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        assert soulContext != null;
        # 在这里debug看到取出来的路径是: http://192.168.101.104:8187?id=1111
        String urlPath = exchange.getAttribute(Constants.HTTP_URL);
        if (StringUtils.isEmpty(urlPath)) {
   
            Object error = SoulResultWarp.error(SoulResultEnum.CANNOT_FIND_URL.getCode(), SoulResultEnum.CANNOT_FIND_URL.getMsg(), null);
            return WebFluxResultUtils.result(exchange, error);
        }
        long timeout = (long) Optional.ofNullable(exchange.getAttribute(Constants.HTTP_TIME_OUT)).orElse(3000L);
        log.info("you request,The resulting urlPath is :{}", urlPath);
        HttpMethod method = HttpMethod.valueOf(exchange.getRequest().getMethodValue());
        WebClient.RequestBodySpec requestBodySpec = webClient.method(method).uri(urlPath);
        return handleRequestBody(requestBodySpec, exchange, timeout, chain);
    }

    在上面这个类中,可以看到就是单纯取路径,我们需要跟踪这个路径的来源

Divide查看

    在前面几篇分析中,我们知道divide plugin 是进行路由配置,并写入真实路径到exchange中的,我们去 DividePlugin 看看

    # DividePlugin
    protected Mono<Void> doExecute(final ServerWebExchange exchange, final SoulPluginChain chain, final SelectorData selector, final RuleData rule) {
   
        final SoulContext soulContext = exchange.getAttribute(Constants.CONTEXT);
        assert soulContext != null;
        final DivideRuleHandle ruleHandle = GsonUtils.getInstance().fromJson(rule.getHandle(), DivideRuleHandle.class);
        final List<DivideUpstream> upstreamList = UpstreamCacheManager.getInstance().findUpstreamListBySelectorId(selector.getId
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值