【问题标题】:Jetty: java.lang.IllegalArgumentException: Not valid encoding码头:java.lang.IllegalArgumentException:无效的编码
【发布时间】:2017-11-04 19:42:41
【问题描述】:

使用嵌入式 Jetty (9.4.5.v20170502),使用 servlet 处理程序和 URL:

http://localhost:8081/?para=%u65E5

(当流量被嗅探到另一个生产服务器时,此 URL 由 Chrome 发送)。

我需要有一个使用 Jetty 的场景的测试用例。

有一个错误:

org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query
    at org.eclipse.jetty.server.Request.getParameters(Request.java:388)
    at org.eclipse.jetty.server.Request.getParameterNames(Request.java:1036)
    at MyServlet.service(MyServlet.java:15)
    at javax.servlet.http.HttpServlet.service(HttpServlet.java:790)
    at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:841)

源自:

java.lang.IllegalArgumentException: Not valid encoding '%u6'
    at org.eclipse.jetty.util.UrlEncoded.decodeHexByte(UrlEncoded.java:889)
    at org.eclipse.jetty.util.UrlEncoded.decodeUtf8To(UrlEncoded.java:354)
    at org.eclipse.jetty.util.UrlEncoded.decodeUtf8To(UrlEncoded.java:296)
    at org.eclipse.jetty.http.HttpURI.decodeQueryTo(HttpURI.java:615)
    at org.eclipse.jetty.server.Request.extractQueryParameters(Request.java:420)
    at org.eclipse.jetty.server.Request.getParameters(Request.java:384)
    at org.eclipse.jetty.server.Request.getParameterNames(Request.java:1036)
    at MyServlet.service(MyServlet.java:15)

但是,当使用HelloWorld Handler时,调用request.getParameterNames()时相同的URL不会出错。

主类:

public class JettyTest {

    public static void main(String[] args) throws Exception {
        final Server server = new Server(8081);

        // doesn't work
        server.setHandler(getServletHandler());

        // works
        // server.setHandler(new HelloHandler());
        server.start();
    }

    private static Handler getServletHandler() throws IOException {
        final WebAppContext context = new WebAppContext();
        context.setContextPath("/");
        context.setResourceBase(".");

        final String pathSpec = "/*";
        final Class<? extends Servlet> servlet = MyServlet.class;
        context.addServlet(servlet, pathSpec);

        final WebAppClassLoader loader = new WebAppClassLoader(context);
        context.setClassLoader(loader);
        return context;
    }
}

MyServlet:

public class MyServlet extends HttpServlet {

    @Override
    protected void service(final HttpServletRequest request, final HttpServletResponse response)
            throws ServletException, IOException {

        for (final Enumeration<String> paramNames = request.getParameterNames();
                paramNames.hasMoreElements();) {
            final String name = paramNames.nextElement();
            final String[] values = request.getParameterValues(name);
            for (final String value : values) {
                System.out.println(name + " " + value);
            }
        }
        response.getWriter().write("something");
    }
}

HelloHandler:

public class HelloHandler extends AbstractHandler {
    final String greeting;
    final String body;

    public HelloHandler() {
        this("Hello World");
    }

    public HelloHandler(String greeting) {
        this(greeting, null);
    }

    public HelloHandler(String greeting, String body) {
        this.greeting = greeting;
        this.body = body;
    }

    @Override
    public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response)
            throws IOException, ServletException {
        response.setContentType("text/html; charset=utf-8");
        response.setStatus(HttpServletResponse.SC_OK);

        for (Enumeration<String> en = request.getParameterNames(); en.hasMoreElements();) {
            System.out.println("name " + en.nextElement());
        }
        PrintWriter out = response.getWriter();

        out.println("<h1>" + greeting + "</h1>");
        if (body != null) {
            out.println(body);
        }

        baseRequest.setHandled(true);
    }
}

【问题讨论】:

  • 您的网址未经过属性编码。试试这个网址http://localhost:8081/?para=%25u65E5
  • Chrome按原样发送参数值,其他生产服务器不报错。

标签: java jetty


【解决方案1】:

简单的解决方案:我只是在浏览器应用程序中的 javascript 中使用 'encodeURI(url)'(在 ajax 函数之前),问题就解决了

【讨论】:

    【解决方案2】:

    这似乎是 Jetty 中的一个错误。用户可以制作一个导致 Jetty 无法处理请求的 URL。

    在 Jetty 9.4.15 上,我发现它就像将 ?%%0 附加到 URL 一样简单。一旦处理 URL 的代码尝试访问查询参数,Jetty 就会抛出异常:

    org.eclipse.jetty.http.BadMessageException: 400: Unable to parse URI query
    

    目前,我想说没有好的解决方案或变通方法。

    这可能仅在恶意人员测试您网站的弱点时才会发生。在这种情况下,Jetty 停止处理而不是继续处理不良数据可能是可以接受的。

    【讨论】:

      猜你喜欢
      • 2017-12-13
      • 1970-01-01
      • 2016-11-18
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-19
      • 2019-07-24
      • 1970-01-01
      相关资源
      最近更新 更多