Отправка файла из моего приложения (Indy / Delphi) на страницу ASP, а затем на другой сервер (Amazon S3) - PullRequest
3 голосов
/ 21 марта 2010

Мне нужно хранить файлы на Amazon AWS S3, но для того, чтобы изолировать пользователя от аутентификации AWS, я хочу перейти на страницу ASP на моем сайте, на которую пользователь войдет. Итак:

Приложение отправляет файл с помощью подпрограммы Delphi Indy TidHTTP.Put (FileStream) на страницу ASP вместе с некоторыми средствами аутентификации (мой, а не AWS) в строке запроса.

Страница ASP проверяет данные аутентификации, а затем, если OK, сохраняет файл на S3, используя мою учетную запись Amazon.

Проблема у меня заключается в следующем: как получить доступ к данным, поступающим из Indy PUT, используя JScript на странице ASP, и передать их на S3. Я в порядке с подписью AWS и т. Д., Это просто гайки и болты соединения двух битов (входящий запрос и исходящий запрос AWS) ...

ТИА R

Ответы [ 2 ]

2 голосов
/ 21 марта 2010

A HTTP PUT сохранит файл в указанном месте в заголовке HTTP - он «запрашивает, чтобы вложенный объект был сохранен под предоставленным Request-URI».

Недостатком метода PUT является то, что если вы находитесь в среде общего хостинга, он может быть вам недоступен.

Таким образом, если веб-сервер поддерживает PUT, файл должен быть доступен в указанном месте в (виртуальной) файловой системе. Запрос PUT будет обрабатываться сервером, а не ASP:

В случае PUT, веб-сервер обрабатывает сам запрос: есть нет места для приложения CGI или ASP вмешаться. Единственный способ для вашего приложения захватить PUT, чтобы работать на низкоуровневый, уровень фильтра ISAPI

http://www.15seconds.com/issue/981120.htm

Вы уверены, что вам нужен PUT и вы не можете использовать POST, который отправит файл по URL-адресу, где ваш сценарий ASP сможет прочитать его из потока запросов?

0 голосов
/ 21 марта 2010

ОК, у меня получилось немного дальше. Код в конце ASP:

    var PostedDataSize   = Request.TotalBytes ;
    var PostedData       = Request.BinaryRead (PostedDataSize) ;

    var PostedDataStream = Server.CreateObject ("ADODB.Stream") ; 
    PostedDataStream.Open ;
    PostedDataStream.Type = 1 ;                    // binary
    PostedDataStream.Write (PostedData) ;

    Response.Write ("PostedDataStream.Size = " + PostedDataStream.Size + "<br>") ;

    var XML = AmazonAWSPUTRequest (BucketName, AWSDestinationFileID, PostedDataStream) ;
    .....

    function AmazonAWSPUTRequest (Bucket, Filename, InputStream) 

    {
    ....
    XMLHttp.open ("PUT", URL + FRequest, false) ;

    XMLHttp.setRequestHeader (....
    XMLHttp.setRequestHeader (....
    ...
    Response.Write ("InputStream.Size = " + InputStream.Size + "<br>") ;
    XMLHttp.send (InputStream)  ;     

Так что я использую BinaryRead, записываю его в двоичный поток. Если я выписываю размер потока, я получаю размер файла, который я POST'ed из моего приложения, поэтому я считаю, что данные где-то там. Затем я вызываю подпрограмму (с потоком в качестве параметра), которая устанавливает аутентификацию / подпись AWS и выполняет PUT.

Вызов AWS не возвращает ошибок, и файл с правильным именем создается в нужном месте, но его размер равен нулю! InputStream.Size имеет значение, совпадающее с параметром потока, переданным подпрограмме, т.е. размером исходного файла.

Есть идеи?

Постскриптум. Нашел проблему. Это поймало меня несколько раз с потоками, этот. Когда вы записываете данные в поток, не забудьте сбросить позицию потока обратно в ноль, прежде чем пытаться снова читать из потока. То есть прямо перед строкой:

    XMLHttp.send (InputStream)  ; 

Мне нужно было добавить:

   InputStream.Position = 0 ;

Спасибо за интерес и предложения.

...