yhs0092 opened a new issue, #4461: URL: https://github.com/apache/servicecomb-java-chassis/issues/4461
## 问题现象 业务发送 `x-www-form-urlencoded` 格式的body, 在升级 Java-Chassis 2.8.17 后遇到报错. ## 代码分析 代码位置:  如上图, Vert.x的`HttpServerOptions` 中新增了 `maxFormFields` 和 `maxFormBufferedBytes` 配置, CSE目前没有适配, 取的是默认值 `maxFormFields=256` 和 `maxFormBufferedBytes=1024`. 如果业务发送的是表单请求, 表单参数的名字或值长度大于`1024`, 则**可能**触发 Netty 报 `TooLongFormFieldException` 异常, 报错位置如下: https://github.com/netty/netty/blob/2e218bbd0a416d6e8a7abb5e2d180fe9f19a9968/codec-http/src/main/java/io/netty/handler/codec/http/multipart/HttpPostStandardRequestDecoder.java#L321-L342 ```java public HttpPostStandardRequestDecoder offer(HttpContent content) { checkDestroyed(); if (content instanceof LastHttpContent) { isLastChunk = true; } ByteBuf buf = content.content(); if (undecodedChunk == null) { undecodedChunk = // Since the Handler will release the incoming later on, we need to copy it // // We are explicit allocate a buffer and NOT calling copy() as otherwise it may set a maxCapacity // which is not really usable for us as we may exceed it once we add more bytes. buf.alloc().buffer(buf.readableBytes()).writeBytes(buf); } else { undecodedChunk.writeBytes(buf); } parseBody(); if (maxBufferedBytes > 0 && undecodedChunk != null && undecodedChunk.readableBytes() > maxBufferedBytes) { throw new TooLongFormFieldException(); // <---- 会从这个位置抛异常 } ``` **注意, 是可能触发**. 因为Netty是分段读取 socket buffer 进行处理的. 有可能出现表单参数的名字或值超过了限制, 但由于Netty分段读取的buffer长度仍小于`1024`, 处理完成之后Netty将缓存长度清零准备迎接下一段buffer, 此时`undecodedChunk.readableBytes()`仍不会超过限制. 实际触发时可以选一个远远超过`1024`的长度进行测试. ## 次生问题 Java-Chassis的`RestBodyHandler`中处理这种异常时, 判断如果捕获的异常是 `DecoderException` 就获取它的 cause 作为异常信息. 但是在这种故障场景下, `DecoderException` 的 cause 为 null, 导致最终打出来的异常显示为一个空指针异常, 很有迷惑性. https://github.com/apache/servicecomb-java-chassis/blob/86a682e42365f595746d37d2f5fab22380b1f684/transports/transport-rest/transport-rest-vertx/src/main/java/org/apache/servicecomb/transport/rest/vertx/RestBodyHandler.java#L312-L317  最终Java-Chassis打印的日志片段样例: ``` 2024-08-07 09:12:22.899 [transport-vert.x-eventloop-thread-5] ERROR - [VertxRestDispatcher.java:failureHandler:87] - [] - http server failed. java.lang.NullPointerException: null at io.vertx.ext.web.impl.RoutingContextImpl.fail(RoutingContextImpl.java:196) ~[vertx-web-4.4.9.jar!/:4.4.9] at org.apache.servicecomb.transport.rest.vertx.RestBodyHandler$BHandler.lambda$new$2(RestBodyHandler.java:316) ~[transport-rest-vertx-2.8.17.jar!/:2.8.17] at io.vertx.core.impl.ContextInternal.dispatch(ContextInternal.java:277) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.http.impl.HttpEventHandler.handleException(HttpEventHandler.java:89) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.http.impl.Http1xServerRequest.handleException(Http1xServerRequest.java:679) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.http.impl.Http1xServerRequest.onData(Http1xServerRequest.java:566) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.http.impl.Http1xServerRequest.lambda$pendingQueue$1(Http1xServerRequest.java:136) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.streams.impl.InboundBuffer.handleEvent(InboundBuffer.java:255) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.streams.impl.InboundBuffer.write(InboundBuffer.java:134) ~[vertx-core-4.4.9.jar!/:4.4.9] at io.vertx.core.http.impl.Http1xServerRequest.handleContent(Http1xServerRequest.java:150) ~[vertx-core-4.4.9.jar!/:4.4.9] ``` ## 期望 Java-Chassis 增加配置项适配 Vert.x 新开放的配置项, 包括: - io.vertx.core.http.HttpServerOptions#maxFormBufferedBytes - io.vertx.core.http.HttpServerOptions#maxFormFields 优化日志, 避免在报错时只打印空指针异常信息. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
