Servlet service() method not getting called for CO

2019-03-03 13:56发布

问题:

I am trying to write a forward proxy in Jetty using Servlet 3.0.

I've a simple code-

public class testServlet extends HttpServlet {

   @Override
    protected  void service (HttpServletRequest req, HttpServletResponse resp) throws   ServletException, IOException {
       System.out.println(req.toString());        

  }

}

If client requests a HTTP site, above service method gets called but when HTTPS site is requested (using HTTP Connect method), above method is not being called. Why?

I can obviously use Jetty's handlers but I would rather prefer to use servlet so that code remains somewhat portable (I can run it under Glassfish, Tomat, Jetty etc)

Any idea what might be wrong?

回答1:

It is possible to deliver a CONNECT request to a Servlet service method, but it is ultimately futile to do so because it is impossible to handle a CONNECT inside a servlet. You don't really have access to the raw IO streams, only the HTTP content of the request/response. You can almost make his work, but never efficiently (no async IO etc.) So ultimately you will end up falling back to Jetty APIs anyway.

Also, why not just build on the support already provided by Jetty:

http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/proxy/ConnectHandler.html http://download.eclipse.org/jetty/stable-9/xref/org/eclipse/jetty/proxy/ProxyServlet.html



回答2:

Not sure this will be possible.

Generally speaking, Servlets require a context from the request to know which servlet to execute. This is the mapping of a pathSpec to a Servlet that exists in the Servlet descriptors.

With CONNECT requests, there isn't really a context to use for looking up this mapping. (Said another way, the Servlet Container would have a hard time knowing which Servlet to execute based on the information in a CONNECT request)

Some ideas:

  • Try setting up a Filter instead, with pathSpec "/*" (for all pathspecs).
  • Set your Servlet to pathSpec "/" (for default servlet). Note: might need to disable the standard DefaultServlet in ${jetty.home}/etc/webdefault.xml first.


回答3:

You're doing this wrong. The Servlet API and framework is for writing servlets, i.e. endpoints. Not for writing HTTP proxies. HTTP proxies are fundamentally very simple things that understand one command, CONNECT, and then just copy bytes in both directions. Even if you could make this work as a servlet, which you almost certainly can't, the performance impact would be atrocious, as the container would read the entire request before calling you, and probably buffer the response as well. You don't want all that added latency.



回答4:

@Override
protected void service(HttpServletRequest arg0, HttpServletResponse arg1)
        throws ServletException, IOException {
    // TODO Auto-generated method stub
    super.service(arg0, arg1);
}

@Override
public void service(ServletRequest arg0, ServletResponse arg1)
        throws ServletException, IOException {
    // TODO Auto-generated method stub
    super.service(arg0, arg1);
}

You can compare the similarities and differences between these two methods. But these two methods are all subclasses of method parameters are different

Or you can try to use the doPOST, doGET method.

Can't speak English really good pain... Hehe I need to use translation tools to answer your question