Tomcat 9 HTTP / 2图像随机获取"损坏

时间:2018-04-24 09:53:51

标签: tomcat http2

通过HTTP / 2向Tomcat 9提供页面时遇到问题。图像是随机的"已损坏或根本不显示。 Google Chome对ERR_SPDY_PROTOCOL_ERROR和Tomcat日志的抱怨充满了以下错误:

java.lang.IllegalArgumentException: The Unicode character [Č] at code point [268] cannot be encoded as it is outside the permitted range of 0 to 255.
at org.apache.coyote.http2.HPackHuffman.encode(HPackHuffman.java:448)
at org.apache.coyote.http2.HpackEncoder.writeHuffmanEncodableValue(HpackEncoder.java:223)
at org.apache.coyote.http2.HpackEncoder.encode(HpackEncoder.java:185)
at org.apache.coyote.http2.Http2UpgradeHandler.doWriteHeaders(Http2UpgradeHandler.java:579)
at org.apache.coyote.http2.Http2UpgradeHandler.writeHeaders(Http2UpgradeHandler.java:533)
at org.apache.coyote.http2.Stream.writeHeaders(Stream.java:422)
at org.apache.coyote.http2.StreamProcessor.prepareResponse(StreamProcessor.java:111)
at org.apache.coyote.AbstractProcessor.action(AbstractProcessor.java:323)
at org.apache.coyote.Response.action(Response.java:211)
at org.apache.coyote.Response.sendHeaders(Response.java:441)
at org.apache.coyote.http2.Http2OutputBuffer.doWrite(Http2OutputBuffer.java:57)
at org.apache.coyote.Response.doWrite(Response.java:603)
at org.apache.catalina.connector.OutputBuffer.realWriteBytes(OutputBuffer.java:328)
at org.apache.catalina.connector.OutputBuffer.flushByteBuffer(OutputBuffer.java:748)
at org.apache.catalina.connector.OutputBuffer.append(OutputBuffer.java:653)
at org.apache.catalina.connector.OutputBuffer.writeBytes(OutputBuffer.java:368)
at org.apache.catalina.connector.OutputBuffer.write(OutputBuffer.java:346)
at org.apache.catalina.connector.CoyoteOutputStream.write(CoyoteOutputStream.java:96)
at org.springframework.util.StreamUtils.copy(StreamUtils.java:140)
at org.springframework.http.converter.ResourceHttpMessageConverter.writeContent(ResourceHttpMessageConverter.java:132)
at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:124)
at org.springframework.http.converter.ResourceHttpMessageConverter.writeInternal(ResourceHttpMessageConverter.java:45)
at org.springframework.http.converter.AbstractHttpMessageConverter.write(AbstractHttpMessageConverter.java:230)
at org.springframework.web.servlet.resource.ResourceHttpRequestHandler.handleRequest(ResourceHttpRequestHandler.java:381)
at org.springframework.web.servlet.mvc.HttpRequestHandlerAdapter.handle(HttpRequestHandlerAdapter.java:53)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:64)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.ApplicationDispatcher.invoke(ApplicationDispatcher.java:712)
at org.apache.catalina.core.ApplicationDispatcher.processRequest(ApplicationDispatcher.java:459)
at org.apache.catalina.core.ApplicationDispatcher.doForward(ApplicationDispatcher.java:384)
at org.apache.catalina.core.ApplicationDispatcher.forward(ApplicationDispatcher.java:312)
at com.m2000.shop.controllers.DefaultController.image(DefaultController.java:1113)
at jdk.internal.reflect.GeneratedMethodAccessor111.invoke(Unknown Source)
at java.base/jdk.internal.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at org.springframework.web.method.support.InvocableHandlerMethod.doInvoke(InvocableHandlerMethod.java:209)
at org.springframework.web.method.support.InvocableHandlerMethod.invokeForRequest(InvocableHandlerMethod.java:136)
at org.springframework.web.servlet.mvc.method.annotation.ServletInvocableHandlerMethod.invokeAndHandle(ServletInvocableHandlerMethod.java:102)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.invokeHandlerMethod(RequestMappingHandlerAdapter.java:871)
at org.springframework.web.servlet.mvc.method.annotation.RequestMappingHandlerAdapter.handleInternal(RequestMappingHandlerAdapter.java:777)
at org.springframework.web.servlet.mvc.method.AbstractHandlerMethodAdapter.handle(AbstractHandlerMethodAdapter.java:87)
at org.springframework.web.servlet.DispatcherServlet.doDispatch(DispatcherServlet.java:991)
at org.springframework.web.servlet.DispatcherServlet.doService(DispatcherServlet.java:925)
at org.springframework.web.servlet.FrameworkServlet.processRequest(FrameworkServlet.java:978)
at org.springframework.web.servlet.FrameworkServlet.doGet(FrameworkServlet.java:870)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:634)
at org.springframework.web.servlet.FrameworkServlet.service(FrameworkServlet.java:855)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:741)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:231)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.tomcat.websocket.server.WsFilter.doFilter(WsFilter.java:53)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.m2000.shop.filters.RedirectFilter.doFilter(RedirectFilter.java:35)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at com.m2000.shop.filters.CacheFilter.doFilter(CacheFilter.java:24)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.logging.log4j.web.Log4jServletFilter.doFilter(Log4jServletFilter.java:71)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:193)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:166)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:199)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:96)
at org.apache.catalina.authenticator.AuthenticatorBase.invoke(AuthenticatorBase.java:494)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:137)
at psiprobe.Tomcat90AgentValve.invoke(Tomcat90AgentValve.java:45)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:92)
at org.apache.catalina.valves.AbstractAccessLogValve.invoke(AbstractAccessLogValve.java:651)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:87)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:343)
at org.apache.coyote.http2.StreamProcessor.service(StreamProcessor.java:324)
at org.apache.coyote.AbstractProcessorLight.process(AbstractProcessorLight.java:66)
at org.apache.coyote.http2.StreamProcessor.process(StreamProcessor.java:72)
at org.apache.coyote.http2.StreamRunnable.run(StreamRunnable.java:35)
at java.base/java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1167)
at java.base/java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:641)
at org.apache.tomcat.util.threads.TaskThread$WrappingRunnable.run(TaskThread.java:61)
at java.base/java.lang.Thread.run(Thread.java:844)

1 个答案:

答案 0 :(得分:2)

at org.apache.coyote.http2.HPackHuffman.encode(HPackHuffman.java:448)是编码HTTP标头的部分。它抱怨它被要求编码非ASCII字符(Č)。

您看到was introduced by a patch修正其他问题的行为:https://bz.apache.org/bugzilla/show_bug.cgi?id=60451 该补丁具有有效禁止非ASCII字符的不幸副作用。另一个修复方法是将字符串视为一系列字节,而不是使用String.charAt并拒绝高于255的值。

RFC 7320 3.2允许标头值介于128和255之间的字节为obs-text,并且Web服务器允许它们,因为实际上许多标头使用UTF-8来使用该范围。 (Č编码为0xC4 0x8C)

为了解决这个问题,我会在上面的bug跟踪器中向Tomcat项目报告此问题。在此期间,如果您能够识别并删除包含非ASCII字符的标题,则可以解决该问题。