Почему заголовок Range не работает для статических ресурсов, размещенных в Spring Boot WAR с использованием встроенного Tomcat?

У меня есть WAR Spring Boot 2.0, использующий WebMVC со встроенным Tomcat 8.5, и я размещаю свои статические ресурсы из WAR.

Запрос статического ресурса, который включает Range: bytes=0-, завершается с ошибкой HTTP 416 (Range Not Satisfiable), тогда как тот же запрос без заголовка Range работает нормально.

Просто для контекста рассматриваемый статический файл представляет собой видео .mp4, которое браузер запрашивает с заголовком Range, поскольку на файл ссылается элемент video.

Пройдясь по отладчику, я вижу, что причина в том, что HttpRange.toResourceRegion() не может определить длину ресурса. (Вернее, возвращаемая длина равна -1.) Причина в том, что, поскольку URL-адрес ресурса не является URL-адресом файла, он пытается открыть соединение с URL-адресом и вызвать getContentLength() для соединения, а WarURLConnection не переопределяет реализацию возврата URLConnection по умолчанию -1.

Я хочу назвать это ошибкой в ​​Spring и/или встроенном Tomcat, но если бы это было так, я чувствую, что кто-то другой уже сообщил бы об этом (и я не могу найти никаких доказательств этого). Я делаю что-то необычное здесь?

Или, может быть, это действительно работает для всех остальных? Может быть, есть какая-то волшебная конфигурация Spring, которую я пропустил? (Я сомневаюсь, что это связано с автоматической настройкой Spring Boot, но я должен упомянуть здесь, что большая часть этого отключена на данный момент, поскольку я переношу приложение без загрузки в Boot.)

Я понимаю, что, возможно, смогу обойти эту проблему, обработав этот запрос ресурсов «вручную» (и при необходимости используя пользовательскую реализацию Resource), но, похоже, мне не нужно этого делать. Это похоже на то, что должно работать из коробки.


person Doug Paul    schedule 31.08.2018    source источник


Ответы (1)


Я считаю, что понял это. Оказывается, я делал что-то немного отличное от того, как, вероятно, делает большинство людей, и есть также (что я считаю) ошибка в Spring Boot, которая проявляется в этом случае.

В частности, я размещал эти ресурсы из WAR, а не из пути к классам, как, кажется, поощряет Spring Boot в наши дни. Тот факт, что длина содержимого не может быть определена для war: URL-адресов, на мой взгляд, является ошибкой в ​​Spring Boot и/или встроенном Tomcat.

Исправление состояло в том, чтобы просто переместить видеоресурсы из src/main/webapp/videos/ в src/main/resources/static/videos/ и соответствующим образом обновить конфигурацию реестра моего обработчика ресурсов (например, addResourceLocations("/videos/") стало addResourceLocations("classpath:/static/videos/")).

Я планирую подать отчет об ошибке с помощью Spring Boot, на который я дам ссылку, когда сделаю это.

Изменить: вот отчет об ошибке.

person Doug Paul    schedule 31.08.2018