1 2 Previous Next 23 Replies Latest reply on Sep 5, 2017 6:24 PM by Jon Morgan

    Does Wildfly/Undertow support byte-range requests?

    David Cardozo Newbie

      Hello everyone,

       

      I'm using Wildfly 8.1.0.Final (among other things) for retrieving static content (web optimized PDF files). I've placed those PDFs under $JBOSS_HOME/standalone/deployments/ROOT.war/. However, when I request them passing the "Range:bytes=1-100" request header, I always get the entire document as opposed to the first 100 bytes. Previous to Wildfly I used to successfully do byte-range requests under JBoss/Tomcat. Here are a couple of examples of a unsuccessful and successful request:

       

      Unsuccessful request in Wildfly 8.1.0:

       

      $ curl -H Range:bytes=1-100 -I http://localhost:8080/test.pdf

      HTTP/1.1 200 OK

      Connection: keep-alive

      Last-Modified: Tue, 25 Mar 2014 15:39:37 GMT

      X-Powered-By: Undertow/1

      Server: WildFly/8

      Content-Type: application/pdf

      Content-Length: 14658

      Date: Thu, 02 Oct 2014 21:08:25 GMT

       

       

      Successful request in JBoss 4.2.2:

       

      $ curl -H Range:bytes=1-100 -I http://localhost:8080/test.pdf

      HTTP/1.1 206 Partial Content

      Server: Apache-Coyote/1.1

      X-Powered-By: Servlet 2.4; JBoss-4.2.2.GA (build: SVNTag=JBoss_4_2_2_GA date=200710221139)/Tomcat-5.5

      ETag: W/"14658-1395761977000"

      Last-Modified: Tue, 25 Mar 2014 15:39:37 GMT

      Content-Range: bytes 1-100/14658

      Content-Type: application/pdf

      Content-Length: 100

      Date: Thu, 02 Oct 2014 21:15:12 GMT

       

      Notice that JBoss successfully returns a "206 Partial Content" response and appropriate "Content-Length: 100" and "Content-Range:1-100/14658" response headers while Wildfly returns back a "200 OK" and "Content-Length: 14658".

       

      Is there a place in the configuration for enabling byte-range requests in Wildlfy/Undertow? I could not find an answer by searching the documentation, this forum or the web in general.

       

      Thanks in advance for your help,

       

      David.

        • 1. Re: Does Wildfly/Undertow support byte-range requests?
          Ricardo Villar Newbie

          Hi David,

          It's been over a year since you made this post.

          Were you able to solve it?

          I'm having the same problem with the JBoss Application Server 9.0.1 (and 9.0.2).

          Thanks for your help.

          • 2. Re: Does Wildfly/Undertow support byte-range requests?
            Tomaz Cerar Master

            Yes Undertow in WildFly supports that see https://issues.jboss.org/browse/UNDERTOW-324

             

            Which is used in WildFly 9+, so 8.x wont work but, 9 and newer have support for range requests.

            • 3. Re: Does Wildfly/Undertow support byte-range requests?
              Ricardo Villar Newbie

              Unfortunately, is not working for me.

              This is the response I get from a simple request like. curl -I http://localhost:8080/stairs.mp4

               

              HTTP/1.1 200 OK

              Connection: keep-alive

              Last-Modified: Mon, 09 Nov 2015 13:35:29 GMT

              X-Powered-By: Undertow/1

              Server: WildFly/9

              Content-Type: video/mp4

              Content-Length: 2890554

              Date: Thu, 12 Nov 2015 17:29:53 GMT

               

               

              There is no "Accept-Rage: bytes".

              • 4. Re: Does Wildfly/Undertow support byte-range requests?
                Jason Holmberg Newbie

                Did you every find an answer to this question?  I am having the same issue.

                 

                We are using WildFly 10 and attempting to serve a simple page with one video using the HTML5 <video > tag.  This all works fine in all browsers except Safari.  It seems that Safari required the "Accept-Ranges: bytes" header in the response. WildFly is not responding with that header.  Incidentally, Tomcat does response with the "Accept-Ranges: bytes" header (verified by the `curl` test from above) and the video is served correctly to Safari by Tomcat.

                 

                It seems that without real support for Accept-Range we will not be able to deliver this content via WildFly to any Safari users including those on iPads and iPhones.  This is a big problem.

                 

                Here are the results of my `curl` test.  Notice the missing Accept-Ranges header

                 

                $ curl -I http://localhost:8080/vidtest/video.mp4

                HTTP/1.1 200 OK

                Connection: keep-alive

                Last-Modified: Tue, 15 Mar 2016 19:01:16 GMT

                X-Powered-By: Undertow/1

                Server: WildFly/10

                Content-Type: application/octet-stream

                Content-Length: 97453981

                Date: Wed, 16 Mar 2016 14:08:45 GMT

                 

                 

                $ curl -I http://localhost:8080/vidtest/video.mp4

                HTTP/1.1 200 OK

                Server: Apache-Coyote/1.1

                Accept-Ranges: bytes

                ETag: W/"97453981-1458128929000"

                Last-Modified: Wed, 16 Mar 2016 11:48:49 GMT

                Content-Type: video/mp4

                Content-Length: 97453981

                Date: Wed, 16 Mar 2016 14:12:00 GMT

                 

                I attempted to "force" the inclusion of the "Accept-Ranges: bytes" header by adding a <filter-ref > to the undertow subsystem and the header was returned, but it had not effect.

                • 5. Re: Does Wildfly/Undertow support byte-range requests?
                  Tomaz Cerar Master

                  try adding this to configuration

                   

                  <host name="default-host" alias="localhost">

                                      <location name="/" handler="welcome-content"/>

                  ...

                                      <filter-ref name="byte-range"/>

                                  </host>

                  ...

                  ...

                   

                  <filter name="byte-range" class-name="io.undertow.server.handlers.ByteRangeHandler" module="io.undertow.core">

                        <param name="sendAcceptRanges" value="true"/>

                  </filter>

                  • 6. Re: Does Wildfly/Undertow support byte-range requests?
                    Jason Holmberg Newbie

                    Adding that to the configuration produces this exception when making a request:

                     

                    11:09:46,832 ERROR [io.undertow.request] (default I/O-7) UT005071: Undertow request failed HttpServerExchange{ GET /vidtest/ request {Accept=[text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,*/*;q=0.8], Accept-Language=[en-US,en;q=0.8], Cache-Control=[max-age=0], Accept-Encoding=[gzip, deflate, sdch], User-Agent=[Mozilla/5.0 (Macintosh; Intel Mac OS X 10_11_3) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/49.0.2623.87 Safari/537.36], If-Modified-Since=[Wed, 16 Mar 2016 14:48:13 GMT], Connection=[keep-alive], If-None-Match=[W/"266-1458139693000"], Upgrade-Insecure-Requests=[1], Host=[localhost:8080]} response {}}: java.lang.RuntimeException: WFLYUT0064: Failed to configure handler class io.undertow.server.handlers.ByteRangeHandler

                      at org.wildfly.extension.undertow.deployment.ConfiguredHandlerWrapper.wrap(ConfiguredHandlerWrapper.java:78)

                      at org.wildfly.extension.undertow.filters.CustomFilterDefinition.createHttpHandler(CustomFilterDefinition.java:100)

                      at org.wildfly.extension.undertow.filters.FilterService.createHttpHandler(FilterService.java:57)

                      at org.wildfly.extension.undertow.filters.FilterRef.createHttpHandler(FilterRef.java:69)

                      at org.wildfly.extension.undertow.LocationService.configureHandlerChain(LocationService.java:96)

                      at org.wildfly.extension.undertow.Host.configureRootHandler(Host.java:117)

                      at org.wildfly.extension.undertow.Host.getOrCreateRootHandler(Host.java:171)

                      at org.wildfly.extension.undertow.Host$HostRootHandler.handleRequest(Host.java:285)

                      at io.undertow.server.handlers.NameVirtualHostHandler.handleRequest(NameVirtualHostHandler.java:54)

                      at io.undertow.server.handlers.error.SimpleErrorPageHandler.handleRequest(SimpleErrorPageHandler.java:76)

                      at io.undertow.server.handlers.CanonicalPathHandler.handleRequest(CanonicalPathHandler.java:49)

                      at io.undertow.server.handlers.ChannelUpgradeHandler.handleRequest(ChannelUpgradeHandler.java:158)

                      at io.undertow.server.Connectors.executeRootHandler(Connectors.java:202)

                      at io.undertow.server.protocol.http.HttpReadListener.handleEventWithNoRunningRequest(HttpReadListener.java:232)

                      at io.undertow.server.protocol.http.HttpReadListener.handleEvent(HttpReadListener.java:130)

                      at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:145)

                      at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:92)

                      at io.undertow.server.protocol.http.HttpOpenListener.handleEvent(HttpOpenListener.java:51)

                      at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)

                      at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:291)

                      at org.xnio.ChannelListeners$10.handleEvent(ChannelListeners.java:286)

                      at org.xnio.ChannelListeners.invokeChannelListener(ChannelListeners.java:92)

                      at org.xnio.nio.QueuedNioTcpServer$1.run(QueuedNioTcpServer.java:121)

                      at org.xnio.nio.WorkerThread.safeRun(WorkerThread.java:580)

                      at org.xnio.nio.WorkerThread.run(WorkerThread.java:464)

                    Caused by: java.lang.NoSuchMethodException: io.undertow.server.handlers.ByteRangeHandler.<init>(io.undertow.server.HttpHandler)

                      at java.lang.Class.getConstructor0(Class.java:3082)

                      at java.lang.Class.getConstructor(Class.java:1825)

                      at org.wildfly.extension.undertow.deployment.ConfiguredHandlerWrapper.wrap(ConfiguredHandlerWrapper.java:55)

                      ... 24 more


                    My undertow subsystem looks like this:


                    <subsystem xmlns="urn:jboss:domain:undertow:3.0">
                        <buffer-cache name="default"/>
                        <server name="default-server">
                            <http-listener name="default" socket-binding="http" redirect-socket="https"/>
                            <host name="default-host" alias="localhost">
                                <location name="/" handler="welcome-content"/>
                                <access-log/>
                                <filter-ref name="server-header"/>
                                <filter-ref name="x-powered-by-header"/>
                                <filter-ref name="byte-range" />
                            </host>
                        </server>
                        <servlet-container name="default">
                            <jsp-config/>
                            <websockets/>
                        </servlet-container>
                        <handlers>
                            <file name="welcome-content" path="${jboss.home.dir}/welcome-content"/>
                        </handlers>
                        <filters>
                             <filter name="byte-range" class-name="io.undertow.server.handlers.ByteRangeHandler" module="io.undertow.core">
                                  <param name="sendAcceptRanges" value="true"/>
                             </filter>
                            <response-header name="server-header" header-name="Server" header-value="WildFly/10"/>
                            <response-header name="x-powered-by-header" header-name="X-Powered-By" header-value="Undertow/1"/>
                        </filters>
                    </subsystem>
                    


                    • 7. Re: Does Wildfly/Undertow support byte-range requests?
                      Jason Holmberg Newbie

                      I've debugged through this a little and it seems that this is breaking on line 55 in org.wildfly.extension.undertow.deployment.ConfiguredHandlerWrapper, which looks like:

                       

                      Constructor<?> ctor = handlerClass.getConstructor(HttpHandler.class);
                      

                       

                      Well, the ByteRangeHandler does not have a matching constructor and it is not the only Handler to not have a matching constructor. Configuring RequestBufferingHandler like this:

                       

                      <filter name="request-buffer" class-name="io.undertow.server.handlers.RequestBufferingHandler" module="io.undertow.core">
                           <param name="maxBuffers" value="200"/>
                      </filter>
                      

                       

                      Produces the same error.

                       

                      This seems to be a bug.

                      • 9. Re: Does Wildfly/Undertow support byte-range requests?
                        Tomaz Cerar Master

                        btw, where are your files you are streaming with byte ranges?

                        part of your war application and served by some servlet or are they served by some file handler?

                        • 10. Re: Does Wildfly/Undertow support byte-range requests?
                          Jason Holmberg Newbie

                          Just static content that I am serving from an "exploded" war in WildFly.  As simple as it gets:

                           

                          $ tree vidtest.war

                          vidtest.war

                          ├── index.html

                          ├── video.jpg

                          └── video.mp4


                          Where the html looks like this:

                          <!DOCTYPE html>
                          <html>
                          <body>
                            <div>
                                <video width="900" controls preload="auto" poster="video.jpg" >
                                    <source src="video.mp4" type="video/mp4">
                                </video>
                            </div>
                          </body>
                          </html>
                          
                          
                          
                          • 11. Re: Does Wildfly/Undertow support byte-range requests?
                            Jason Holmberg Newbie

                            While there is definitely a problem with the way the Handlers are constructed, fixing the ByteRangeHandler does not seem to fix my issue.  Admittedly this was a shot-in-the-dark solution to find a way to server video content from WildFly to Safari.  Simply enabling the Byte Range headers does not do the trick and in fact (for some reason unknown to me) prevent the videos from playing in Chrome.

                             

                            I am still searching for a solution to server this content from WildFly to devices that support Safari.  This is a potential critical issue for some of our applications.

                            • 12. Re: Does Wildfly/Undertow support byte-range requests?
                              Jason Holmberg Newbie

                              I did a small test on my ByteRangeHandle hackery and it does seem to operate as it should.

                               

                              Tested this with curl as this suggests: http://stackoverflow.com/questions/3397241/does-iphone-ipad-safari-require-accept-ranges-header-for-video

                               

                              ByteRangeHandler configured:

                              $ curl --range 0-99 http://localhost:8080/vidtest/video.mp4 -o /dev/null

                                % Total    % Received % Xferd  Average Speed  Time    Time    Time  Current

                                                              Dload  Upload  Total  Spent    Left  Speed

                              100  100  100  100    0    0    597      0 --:--:-- --:--:-- --:--:--  598

                              Notice only 100 bytes were received, respecting the specified range


                              ByteRangeHandler NOT configured:

                              $ curl --range 0-99 http://localhost:8080/vidtest/video.mp4 -o /dev/null

                                % Total    % Received % Xferd  Average Speed  Time    Time    Time  Current

                                                              Dload  Upload  Total  Spent    Left  Speed

                              100 92.9M  100 92.9M    0    0  501M      0 --:--:-- --:--:-- --:--:--  502M

                              Notice 92.9M were received regardless of the range specified

                              • 13. Re: Does Wildfly/Undertow support byte-range requests?
                                Tomaz Cerar Master

                                How did you configure handler than? by modifying the ByteRangeHandler's constructor and adding property?

                                Just curious if there is any difference with setting sendAcceptRanges to true|false?

                                • 14. Re: Does Wildfly/Undertow support byte-range requests?
                                  Jason Holmberg Newbie

                                  Yes, I modified the class:

                                   

                                  WFLY-6386 - added single arg constructor and setter for the sendAccep… · slowtrailrunner/undertow@887bf91 · GitHub

                                   

                                  I made my change default to true for sendAcceptRanges.  So you can essentially skip configuring that param in the <filter /> config.

                                   

                                  There still seem to be some issues, that I am close to working out.  Even if sendAcceptRanges is true it is not always being returned, and I think that is a problem.

                                  1 2 Previous Next