Смешивание OutputCache и запросов динамического диапазона в ASP.NET MVC

Я использую RangeFilePathResult класс для обслуживания mp3 файлов с контроллера MVC.

Действие определяется следующим образом:

[CacheFilter]
[OutputCache(CacheProfile = "Mp3Cache")]
public RangeFilePathResult Mp3Completed(string f)
{
    FileInfo info = new FileInfo(string.Format("C:\\test\\{0}.mp3", f));
    return new RangeFilePathResult("audio/mpeg", info.FullName, info.LastWriteTimeUtc, info.Length);
}

И политика кэширования выглядит следующим образом:

<caching>
  <outputCacheSettings>
    <outputCacheProfiles>
      <add name="Mp3Cache" duration="3600" varyByParam="f" location="Any" />
    </outputCacheProfiles>
  </outputCacheSettings>
</caching> 

Почему это работает правильно, как есть? Кажется, что вам нужно явно varyByHeader убедиться, что запросы диапазона работают с кэшированием вывода? Проблема, к которой я обращался, заключалась в том, что jPlayer на iOS не мог отображать длительность файлов MP3 и отображал NaN при использовании с традиционным FilePathResult - он работает в этой реализации.

1 ответ

Решение

Самое главное, что ответ на запрос диапазона не типичный 200 OK, а 206 Partial Content.

В случае частичного содержания 206 необходимо выполнить несколько дополнительных условий:

  • Запрос должен включать Range поле заголовка, указывающее желаемый диапазон, и может включать If-Range поле заголовка, чтобы сделать запрос условным
  • Ответ должен включать либо Content-Range поле заголовка, указывающее диапазон, включенный в этот ответ, или multipart/byterangesContent-Type в том числе Content-Range поля для каждой части.
  • Ответ должен включать ETag и / или Content-Location (если заголовок был бы отправлен в ответе 200 на тот же запрос)
  • Ответ должен включать Date

Теперь каждый механизм кэширования (в случае location="Any" это браузер, прокси-сервер и IIS вашего хостинга), который поддерживает протокол HTTP, должен знать, что 206 Частичное содержимое отличается от 200 ОК, и обращаться с ним соответствующим образом. Ниже вы можете найти наиболее важные правила кэширования 206 Частичное содержимое ответа:

  • Кэш не должен объединять ответ 206 с другим ранее кэшированным содержимым, если ETag или же Last-Modified заголовки не совпадают точно
  • Кэш, который не поддерживает Range а также Content-Range заголовки не должны кэшировать 206 ответов

Подводя итог, вам не нужно использовать varyByHeader потому что каждый кеш, который следует протоколу HTTP, знает, что в случае частичного содержимого Range а также Content-Range Заголовки являются частью варианта.

Другие вопросы по тегам