2

I have a Spring Boot 2.0 WAR using WebMVC with an embedded Tomcat 8.5, and I host my static resources from within the WAR.

A request for a static resource that includes a Range: bytes=0- fails with HTTP 416 (Range Not Satisfiable), whereas the same request without the Range header works fine.

Just for context, the static file in question is an .mp4 video, which the browser is requesting with the Range header because the file is referenced by a video element.

Stepping through in the debugger, I see the cause is that HttpRange.toResourceRegion() fails to determine the length of the resource. (Or rather, the length returned is -1.) The reason is that since the resource's URL is not a file URL it tries opening a connection to the URL and calling getContentLength() on the connection, and WarURLConnection doesn't override URLConnection's default implementation of returning -1.

I want to call this a bug in Spring and/or embedded Tomcat, but if that were the case I feel like someone else would have reported it by now (and I can't find any evidence of that). Am I doing something unusual here?

Or maybe it actually works for everyone else? Maybe there's some magic Spring config that I missed? (I doubt this is related to Spring Boot's auto-configuration, but I should mention here that I have most of that disabled for now as I'm migrating a non-Boot app to Boot.)

I realize I can probably work around the issue by handling this resource request "manually" (and using a custom implementation of Resource if necessary), but it seems like I shouldn't have to do that. This seems like something that should just work out of the box.

Doug Paul
  • 1,221
  • 12
  • 16

1 Answers1

2

I believe I've figured it out. It turns out I was doing something slightly different from the way most people probably are, and there is also (what I consider) a bug in Spring Boot that manifests itself in this case.

Specifically, I was hosting these resources from the WAR instead of from the classpath as Spring Boot seems to encourage these days. The fact that the content length can't be determined for war: URLs is in my opinion, a bug in Spring Boot and/or embedded Tomcat.

The fix was simply to move the video resources from src/main/webapp/videos/ to src/main/resources/static/videos/ and update my resource handler registry config accordingly (e.g. addResourceLocations("/videos/") became addResourceLocations("classpath:/static/videos/")).

I plan on filing a bug report with Spring Boot, which I'll link to here when I do.

Edit: Here's the bug report.

Doug Paul
  • 1,221
  • 12
  • 16