Netty 4.1.55版本文件上传参数接受时死循环 cpu100%的bug记录

于使用了2.4.1版本的springbootstarter,声明的netty版本为4.1.55 在使用netty进行http服务时,接受参数get方法一切正常 但post方法中的form-data方式一直无法接受参数,程序会卡在

new HttpPostRequestDecoder(request)

这一句,同时cpu观察到100%,猜测为死循环。跟踪代码发现在

private static int findDelimiter(ByteBuf undecodedChunk, String delimiter, int offset) {
        ....
        while (delimiterNotFound && newOffset + delimeterLength <= toRead) {

 处一直循环无法退出,搜索到相同问题:https://github.com/netty/netty/issues/10851

只有form-data方式存在这个问题,x-www-form-urlencoded可以正常使用。

最终升级了netty到当前最新的4.1.65 问题解决。

另附接受参数代码:

private Map<String, String> getParamMap(ChannelHandlerContext ctx, FullHttpRequest request) throws IOException, TipException {
        Map<String, String> paramMap = new HashMap<>();
        paramMap.put("url", StrUtil.subBefore(request.uri(), "?", false));
        if (HttpMethod.GET == request.method()) {
            try {
                QueryStringDecoder decoder = new QueryStringDecoder(request.uri());
                decoder.parameters().forEach((k, v) -> paramMap.put(k, v.get(0)));
            } catch (Exception e) {
                log.error(request.uri() + " 解析参数出错");
                throw new ParamErrorException();
            }
        } else if (HttpMethod.POST == request.method()) {
            final String contentType = request.headers().get(HttpHeaderNames.CONTENT_TYPE);
            if (StrUtil.equals(HttpHeaderValues.APPLICATION_JSON, contentType)) {
                String json = request.content().toString(Charsets.toCharset(CharEncoding.UTF_8));
                try {
                    Map<String, String> map = JsonUtil.fromJson(json, JsonUtil.getMapType(String.class, String.class));
                    if (map != null) {
                        paramMap.putAll(map);
                    }
                } catch (Exception e) {
                    log.error(request.uri() + " 解析参数出错:" + json);
                    throw new ParamErrorException();
                }
            } else {
                HttpPostRequestDecoder decoder = new HttpPostRequestDecoder(request);
                List<InterfaceHttpData> httpPostData = decoder.getBodyHttpDatas();
                for (InterfaceHttpData data : httpPostData) {
                    if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.Attribute) {
                        Attribute attribute = (Attribute) data;
                        paramMap.put(attribute.getName(), attribute.getValue());
                    } else if (data.getHttpDataType() == InterfaceHttpData.HttpDataType.FileUpload) {
                        final FileUpload fileUpload = (FileUpload) data;
                        //这里处理文件参数逻辑
                    }
                }
            }
        } else {
            throw new TipException("不支持的请求方法");
        }
        return paramMap;

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值