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

Reply via email to