Can you change your implementation a bit so that we can understand what's going on?
(the below code can be found at https://gist.github.com/joakime/ca3bf453cd946e47a8a09181ef3a0dd7 as well, and might be slightly more up to date) package jetty.http2; import java.io.IOException; import javax.servlet.ServletException; import javax.servlet.ServletRequest; import javax.servlet.ServletRequestWrapper; import javax.servlet.http.HttpServlet; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.PushBuilder; import org.eclipse.jetty.server.Request; public class Http2PushBuilderServlet extends HttpServlet { @Override protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException { dumpRequestDetail(request); Request req = Request.getBaseRequest(request); if (req != null) { System.out.printf("req: (%s) %s%n", req.getClass().getName(), req); System.out.printf("req.isPushSupported() = %b%n", req.isPushSupported()); PushBuilder pushBuilder = req.getPushBuilder(); pushBuilder.path("/res").push(); } } private void dumpRequestDetail(HttpServletRequest request) { System.out.printf("HttpServletRequest is implemented by %s%n", request.getClass().getName()); System.out.printf("HttpServletRequest is instanceof Request = %b%n", request instanceof Request); // some relevant virtual attributes dumpAttribute(request, "org.eclipse.jetty.server.Server"); dumpAttribute(request, "org.eclipse.jetty.server.HttpChannel"); dumpAttribute(request, "org.eclipse.jetty.server.HttpConnection"); // the state of the wrapping of the request if (request instanceof ServletRequestWrapper) { System.out.printf(" + is a HttpServletRequestWrapper%n"); ServletRequest servletRequest = request; while (servletRequest instanceof ServletRequestWrapper) { servletRequest = ((ServletRequestWrapper)servletRequest).getRequest(); System.out.printf(" + Wrapped by %s%n", servletRequest.getClass().getName()); } System.out.printf("Unwrapped ServletRequest is instanceof Request = %b%n", servletRequest instanceof Request); } } private void dumpAttribute(HttpServletRequest request, String attrName) { System.out.printf(".getAttribute(%s) = ", attrName); Object value = request.getAttribute(attrName); if (value == null) { System.out.println("<null>"); } else { System.out.printf("(%s) %s%n", value.getClass().getName(), value); } } } Joakim Erdfelt / [email protected] On Tue, Sep 10, 2019 at 9:35 PM John Jiang <[email protected]> wrote: > On Tue, Sep 10, 2019 at 11:32 PM Simone Bordet <[email protected]> > wrote: > >> Hi, >> >> On Tue, Sep 10, 2019 at 2:05 PM John Jiang <[email protected]> >> wrote: >> > I would have tried that with curl, like the below, >> > $ curl -v --http2 http://localhost:9020/push >> > * Trying ::1:9020... >> > * TCP_NODELAY set >> > * Connected to localhost (::1) port 9020 (#0) >> > > GET /push HTTP/1.1 >> > > Host: localhost:9020 >> > > User-Agent: curl/7.65.3 >> > > Accept: */* >> > > Connection: Upgrade, HTTP2-Settings >> > > Upgrade: h2c >> > > HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA >> > > >> > * Mark bundle as not supporting multiuse >> > < HTTP/1.1 101 Switching Protocols >> > * Received 101 >> > * Using HTTP2, server supports multi-use >> > * Connection state changed (HTTP/2 confirmed) >> > * Copying HTTP/2 data in stream buffer to connection buffer after >> upgrade: len=0 >> > * Connection state changed (MAX_CONCURRENT_STREAMS == 1024)! >> > < HTTP/2 500 >> > < cache-control: must-revalidate,no-cache,no-store >> > < content-type: text/html;charset=iso-8859-1 >> > < >> > <html> >> > <head> >> > <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> >> > <title>Error 500 Server Error</title> >> > </head> >> > <body><h2>HTTP ERROR 500</h2> >> > <p>Problem accessing /push. Reason: >> > <pre> Server Error</pre></p><h3>Caused >> by:</h3><pre>java.lang.NullPointerException >> > at httptest.ServerPushServlet.doGet(Unknown Source) >> > at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) >> > at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) >> > at >> org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:844) >> > at >> org.eclipse.jetty.servlet.ServletHandler$CachedChain.doFilter(ServletHandler.java:1604) >> > ... >> > >> > I think they talked HTTP/2. >> > And I suppose this issue may not related to HTTP/2. If used HTTP/1.1, >> that Request still was null. >> >> The SETTINGS frame sent during the upgrade is: >> >> HTTP2-Settings: AAMAAABkAARAAAAAAAIAAAAA >> >> when decoded, it yields this map: >> >> { >> max_concurrent_streams: 100, >> initial_window_size: 32768, >> enable_push: 0 >> } >> >> So cURL does not support pushes, so it disables them in the upgrade >> SETTINGS frame. >> >> Yes, curl tool doesn't support server push yet, even though libcurl > supports that. > But as I mentioned in my last reply, this failure may not be related to > server push or HTTP/2. > That servlet didn't get the instance of org.eclipse.jetty.server.Request. > It didn't touch org.eclipse.jetty.server.PushBuilder yet. > > For clarification, please consider the below simple servlet, > package test; > > import java.io.IOException; > import javax.servlet.ServletException; > import javax.servlet.http.HttpServlet; > import javax.servlet.http.HttpServletRequest; > import javax.servlet.http.HttpServletResponse; > import org.eclipse.jetty.server.Request; > > public class TestServlet extends HttpServlet { > > private static final long serialVersionUID = 5222793251610509039L; > > @Override > public void doGet(HttpServletRequest request, HttpServletResponse > response) > throws ServletException, IOException { > if(Request.getBaseRequest(request) == null) { > throw new RuntimeException( > "Cannot get org.eclipse.jetty.server.Request > instance"); > } > } > } > > and the curl output as the below, > $ curl -v --http1.1 http://localhost:9020/test > * Trying ::1:9020... > * TCP_NODELAY set > * Connected to localhost (::1) port 9020 (#0) > > GET /test HTTP/1.1 > > Host: localhost:9020 > > User-Agent: curl/7.65.3 > > Accept: */* > > > * Mark bundle as not supporting multiuse > < HTTP/1.1 500 Server Error > < Cache-Control: must-revalidate,no-cache,no-store > < Content-Type: text/html;charset=iso-8859-1 > < Content-Length: 3096 > < Connection: close > < Server: Jetty(9.4.20.v20190813) > < > <html> > <head> > <meta http-equiv="Content-Type" content="text/html;charset=utf-8"/> > <title>Error 500 Server Error</title> > </head> > <body><h2>HTTP ERROR 500</h2> > <p>Problem accessing /test. Reason: > <pre> Server Error</pre></p><h3>Caused > by:</h3><pre>java.lang.RuntimeException: Cannot get > org.eclipse.jetty.server.Request instance > at test.TestServlet.doGet(TestServlet.java:20) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:687) > at javax.servlet.http.HttpServlet.service(HttpServlet.java:790) > at org.eclipse.jetty.servlet.ServletHolder.handle(ServletHolder.java:844) > ... > > The dependencies, like jetty-server-9.4.20.v20190813.jar, are in the web > application, say test.war/WEB-INF/lib. > Should I enable some modules for this case? > The enabled modules in my base are the followings, > Enabled Modules: > ================ > 0) alpn-impl/alpn-1.8.0_221 transitive provider of > alpn-impl/alpn-1.8.0_221 for alpn-impl/alpn-8 > dynamic dependency of alpn-impl/alpn-8 > 1) alpn-impl/alpn-8 transitive provider of alpn-impl/alpn-8 for > alpn-impl > dynamic dependency of alpn-impl > 2) alpn-impl transitive provider of alpn-impl for alpn > 3) bytebufferpool transitive provider of bytebufferpool for server > init template available with > --add-to-start=bytebufferpool > 4) ext ${jetty.base}/start.ini > 5) resources ${jetty.base}/start.ini > 6) threadpool transitive provider of threadpool for server > init template available with > --add-to-start=threadpool > 7) server ${jetty.base}/start.ini > ${jetty.base}/start.d/server.ini > 8) ssl ${jetty.base}/start.d/ssl.ini > 9) alpn ${jetty.base}/start.d/alpn.ini > 10) mail transitive provider of mail for jndi > 11) jndi ${jetty.base}/start.ini > 12) security transitive provider of security for webapp > transitive provider of security for plus > 13) transactions transitive provider of transactions for plus > 14) servlet transitive provider of servlet for webapp > transitive provider of servlet for servlets > 15) webapp transitive provider of webapp for plus > transitive provider of webapp for deploy > init template available with --add-to-start=webapp > 16) plus transitive provider of plus for annotations > 17) annotations ${jetty.base}/start.ini > 18) client ${jetty.base}/start.ini > 19) continuation ${jetty.base}/start.ini > 20) deploy ${jetty.base}/start.ini > ${jetty.base}/start.d/deploy.ini > 21) http ${jetty.base}/start.d/http.ini > 22) http2 ${jetty.base}/start.d/http2.ini > 23) http2c ${jetty.base}/start.d/http2c.ini > 24) https ${jetty.base}/start.d/https.ini > 25) servlets ${jetty.base}/start.ini > 26) websocket ${jetty.base}/start.ini > ${jetty.base}/start.d/websocket.ini > _______________________________________________ > jetty-users mailing list > [email protected] > To change your delivery options, retrieve your password, or unsubscribe > from this list, visit > https://www.eclipse.org/mailman/listinfo/jetty-users
_______________________________________________ jetty-users mailing list [email protected] To change your delivery options, retrieve your password, or unsubscribe from this list, visit https://www.eclipse.org/mailman/listinfo/jetty-users
