Есть ли способ принудительно загрузить файл Azure CDN в виде вложения в браузер?

Мы создаем веб-приложение ASP.NET, которое интегрируется с системой DAM (управление цифровыми активами). DAM хранит файлы в хранилище BLOB-объектов Azure и делает их общедоступными с помощью Azure CDN.

Мы сделаем эти файлы (в основном PDF-файлы) доступными для загрузки из нашего веб-приложения. Когда пользователь запрашивает один из этих файлов, мы предоставляем настраиваемый URL-адрес, который будет запускать некоторый код на сервере (регистрировать загрузку и т. Д.) Перед возвратом соответствующего файла для загрузки.

Клиент требует, чтобы файл всегда возвращался как вложение к браузеру (т. Е. Заголовок вложения с размещением содержимого). Мне любопытно, какие варианты у меня здесь есть.

Я хотел бы, чтобы URL-адрес CDN был абстрактным, а мой настраиваемый URL-адрес был общедоступным URL-адресом для файла. Это позволило бы мне установить соответствующие заголовки ответов и т. Д. Однако я предполагаю, что единственное решение здесь - это загрузить файл из CDN и кэшировать его на моем веб-сервере, что запутает назначение CDN. Итак, по-видимому, я должен перенаправить клиента на общедоступный URL-адрес CDN после того, как я выполнил обработку на сервере. Но есть ли способ гарантировать, что файл будет возвращен Azure с правильными заголовками ответа, чтобы гарантировать делегирование поведения загрузки по умолчанию для браузера?

* Обновить *

Увидев ответы на этот вопрос, я понял, что, возможно, задаю неправильный вопрос. Спасибо тем из вас, кто ответил здесь. Дополнительный вопрос находится здесь.


person Tom Troughton    schedule 01.03.2016    source источник
comment
Эти файлы должны быть на CDN? Могут ли они быть обслужены / загружены непосредственно из хранилища BLOB-объектов?   -  person Gaurav Mantri    schedule 01.03.2016
comment
Да, это статические ресурсы, которые в конечном итоге обслуживаются глобальной веб-платформой.   -  person Tom Troughton    schedule 02.03.2016


Ответы (1)


TL;DR

Вам необходимо настроить версию по умолчанию в хранилище BLOB-объектов, чтобы он отображал требуемый заголовок для клиентов, не прошедших проверку подлинности. вопрос в этом вопросе имеет код, чтобы заставить его работать.

Как только это будет установлено и будет работать для анонимных клиентов, CDN скопирует все заголовки, и все должно работать должным образом.

Настройка ContentDisposition

Функциональность присутствует, вы можете установить ContentDisposition в свойстве blob Однако, хотя это установит свойство для большого двоичного объекта, оно не передается в заголовок.

Я тестировал это с помощью Powershell, используя следующее (просто потому, что он быстрее, чем С #)

$context = New-AzureStorageContext -StorageAccountName $StorageAccountName -StorageAccountKey $StorageAccountKey 

$container = Get-AzureStorageContainer -Name $ContainerName -Context $context 

$blobref = ($script:container.CloudBlobContainer.GetBlobReferenceFromServer("images/pier.jpg"))
$blobref.Properties
$blobref.Properties.ContentDisposition = 'attachment; filename="fname.ext"'  
$blobref.SetProperties()  

$blobref = ($script:container.CloudBlobContainer.GetBlobReferenceFromServer("images/pier.jpg"))
$blobref.Properties

Что производит (среди прочего)

ContentDisposition: вложение; имя файла = fname.ext

Однако при запросе заголовков ничего не устанавливается.

([system.Net.HttpWebRequest]::Create($blobref.Uri.AbsoluteUri)).getresponse() 

(чтобы ответить на комментарий, это возвращенные заголовки - во время экспериментов я также пробовал с типом содержимого и без него - поэтому здесь он пуст)

IsMutuallyAuthenticated : False
Cookies                 : {}
Headers                 : {x-ms-request-id, x-ms-version, x-ms-lease-status, x-ms-blob-type...}
SupportsHeaders         : True
ContentLength           : 142224
ContentEncoding         : 
ContentType             : 
CharacterSet            : 
Server                  : Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
LastModified            : 01/03/2016 11:29:04
StatusCode              : OK
StatusDescription       : OK
ProtocolVersion         : 1.1
ResponseUri             : https://xxxx.blob.core.windows.net/cdn/images/pier.jpg
Method                  : GET
IsFromCache             : False

А поскольку CDN копирует информацию только из самих HTTP-заголовков, эти данные не попадают в CDN.

отредактировано (после продолжительной болтовни в комментариях!)

По причинам, наиболее известным ему самим, Powershell не отправлял x-ms-версию, поэтому я вернулся к telnet, который действительно создал заголовок -

HEAD  /cdn/images/pier.jpg HTTP/1.1
HOST: xxxx.blob.core.windows.net
x-ms-version: 2015-04-05

HTTP/1.1 200 OK
Content-Length: 142224
Last-Modified: Tue, 01 Mar 2016 11:29:04 GMT
Accept-Ranges: bytes
ETag: "0x8D341C4B1C4F34F"
Server: Windows-Azure-Blob/1.0 Microsoft-HTTPAPI/2.0
x-ms-request-id: b4f41b01-0001-00d7-7cc9-7384c9000000
x-ms-version: 2015-04-05
x-ms-lease-status: unlocked
x-ms-lease-state: available
x-ms-blob-type: BlockBlob
Content-Disposition: attachment; filename="fname.ext"
Date: Tue, 01 Mar 2016 14:49:17 GMT
person Michael B    schedule 01.03.2016
comment
Я не думаю, что в службе хранилища Azure есть какие-либо проблемы. Я считаю, что то, как вы тестируете эту функциональность, неверно. Я не думаю, что HttpWebRequest действительно инициирует загрузку файла. Он просто прочитал бы содержимое большого двоичного объекта как поток байтов и представил его клиенту. Когда вы устанавливаете заголовок content-disposition, именно браузер инициирует загрузку. Что происходит, когда вы вводите URL-адрес большого двоичного объекта в браузере (конечно же, большой двоичный объект должен быть общедоступным)? Он скачивается? - person Gaurav Mantri; 01.03.2016
comment
@GauravMantri Я добавил заголовки, которые возвращаются с HttpWebRequest к вопросу - я на самом деле попробовал еще несколько способов, данные просто не представлены - очевидно, нам все равно, загружается ли он на этом этапе, просто ли присутствуют правильные заголовки. в этом случае заголовок ContentDisposition отсутствует, как ожидалось (в rfc2183) при просмотре в браузере изображение отображается как обычно. Код есть, не стесняйтесь вносить поправки, если чувствуете, что я что-то упустил. - person Michael B; 01.03.2016
comment
Причина, по которой вы не видите этот заголовок, заключается в том, что вы не указали версию службы хранилища в своем HTTP-запросе. Поскольку вы не указали версию службы хранилища, служба хранилища выбирает версию по умолчанию (2009-09-19 или что-то в этом роде). Заголовок Content-Disposition был добавлен в более поздний выпуск REST API службы хранилища. Попробуйте выполнить что-то вроде следующего, и вы увидите, что возвращается этот заголовок: $ req = ([system.Net.HttpWebRequest] :: Create ($ blobref.Uri.AbsoluteUri)) $ req.Headers.Add ('x-ms-version ',' 2015-04-05 ') $ response = $ req.getresponse () - person Gaurav Mantri; 01.03.2016
comment
@GauravMantri Как Chrome et al. указать в запросе версию хранилища? Они не знают, что и где хранится, они просто выполняют запрос HTTP 1.1. - Выполнение отладочного запроса для командлета Powershell показывает api-version=2015-06-15 Получить свойства Blob требует 2013-08-15 - насколько я вижу, ContentDisposition не отражается в заголовках. Как бы их ни называли. Ваш код также приводит к тому, что сообщаются те же заголовки. - person Michael B; 01.03.2016
comment
Они этого не делают. Из msdn.microsoft.com/en-us/library/azure/dd894041 .aspx: If a request to the Blob service does not specify the x-ms-version header, and the default version for the service has not been set using Set Blob Service Properties, then the earliest version of the Blob service is used to process the request. However, if the container was made public with a Set Container ACL operation performed using version 2009-09-19 or newer, then the request is processed using version 2009-09-19. - person Gaurav Mantri; 01.03.2016
comment
Хорошим примером для проверки этого может быть создание URL-адреса SAS в большом двоичном объекте с последней версией службы хранилища. Затем вы должны увидеть этот заголовок, потому что теперь вы явно указываете службе хранения использовать определенную версию. - person Gaurav Mantri; 01.03.2016
comment
Как бы то ни было, тогда почему я не получил этот заголовок, когда я поместил правильную версию в запрос, и как это помогает OP, поскольку их клиенты будут использовать браузер для взаимодействия с этим. Если хранилище Azure вернется к api-version=2009-09-19, тогда мой первоначальный комментарий о том, что это ошибка в хранилище, будет точным, потому что веб-клиенты не смогут получить доступ к этому заголовку HTTP, потому что они не знают api-версий - Вы пробовали это с SAS URL? или вы думаете, что это сработает? - Наконец, Azure Powershell использует api-version=2015-06-15, так почему это не работает? - person Michael B; 01.03.2016
comment
См. Использованный мной код: pastebin.com/n9s2fY4W. Подскажите, какую версию вы ставили в свой запрос? 2015-06-15 - неправильная версия. Самая последняя версия - 2015-04-15, и я ее использовал. Что касается SAS, я не использовал его в этом конкретном примере, но весь мой продукт построен на SAS, и там мы используем Content-Disposition вместе с SAS, чтобы пользователи могли загружать большой двоичный объект, и он работает в моем продукте, поэтому я знаю, что создание SAS с правильной версией службы хранилища работает. Я бы не стал называть это ошибкой в ​​Storage REST API. - person Gaurav Mantri; 01.03.2016
comment
Чтобы ответить на ваш комментарий о OP, они могут изменить версию службы хранилища по умолчанию со стандартной на последнюю, и тогда им не нужно будет ничего делать, потому что тогда, когда браузер запрашивает большой двоичный объект из хранилища Azure, служба хранилища будет использовать последнюю версию, даже если пользователь ничего не указал. - person Gaurav Mantri; 01.03.2016
comment
@GauravMantri Спасибо за интересное отвлечение от выполнения чего-нибудь полезного! похоже, что Powershell отправляет неизвестную версию. (или я использую это неправильно - что часто бывает!) - в любом случае, я всегда ценю изучение того, о чем я раньше не знал. - person Michael B; 01.03.2016
comment
For reasons best known to itself Powershell wasn't sending the x-ms-version - Если вы отслеживаете HTTP-трафик для вызовов хранилища, сделанных клиентской библиотекой хранилища, вы увидите этот заголовок с правильным значением. Теперь, поскольку вы заставляете HttpWebRequest читать большой двоичный объект вместо использования клиентской библиотеки хранилища, вам нужно будет передать этот заголовок, что я и сделал. - person Gaurav Mantri; 01.03.2016
comment
Спасибо за интересное обсуждение, ребята. Очень полезно. Однако это заставило меня задать новый вопрос. Смотрите обновление в OP. - person Tom Troughton; 02.03.2016