Загрузить на s3 прямо из выпуска Flash 403 - PullRequest
5 голосов
/ 08 августа 2011

Существует довольно много способов загрузки на S3 с флэш-памяти.Я пытаюсь реализовать код из следующего примера на сайте Amazon http://aws.amazon.com/code/1092?_encoding=UTF8&jiveRedirect=1

В некоторых сообщениях, на которые я натолкнулся, указано, что многие поля из Amazon теперь обязательны для заполнения, и если вы не заполните их, вы получите этострашная ошибка 403.

Я перепробовал несколько вещей и надеюсь, что скоро будет решение.Я использовал следующие библиотеки здесь http://code.google.com/p/as3awss3lib/.

Вот мой класс, который обрабатывает все загрузки

package com.myemma.s3uploader.main.controllers
{
    import jp.classmethod.aws.core.AWSEvent;

    import s3.flash.S3PostOptions;
    import s3.flash.S3PostRequest;

    import utils.PolicyGenerator;

    import com.myemma.s3uploader.main.model.MainDM;
    import com.myemma.s3uploader.settings.Settings;

    import flash.events.DataEvent;
    import flash.events.Event;
    import flash.events.EventDispatcher;
    import flash.events.IOErrorEvent;
    import flash.events.ProgressEvent;
    import flash.events.SecurityErrorEvent;
    import flash.external.ExternalInterface;
    import flash.net.FileReference;

    /**
     * @author Matthew Sloan Wallace - http://mattwallace.me
     */
    public class UploadFilesAction extends EventDispatcher
    {
        [Inject]
        public var dm : MainDM;
        private var service : S3PostRequest;

        [Init]
        public function onInit() : void
        {
            if (ExternalInterface.available)
                ExternalInterface.addCallback( "uploadFiles", uploadFiles );
        }

        private function uploadFiles() : void
        {
            if (dm.selectedFiles)
                upload();
        }

        private function upload() : void
        {
            if (dm.selectedFiles.length > 0)
            {
                var fileReference : FileReference = dm.selectedFiles[0];
                // var s3:AWSS3 = new AWSS3(Settings.accessKey, Settings.secret_key);
                // s3.saveObject("mattwallace", fileReference.name, "image/png", fileReference);
                // s3.addEventListener("objectSaved", onObjectSaved);

                var policy : PolicyGenerator = PolicyGenerator.getInstance( Settings.accessKey, Settings.secret_key );
                var s3Options : S3PostOptions = new S3PostOptions();
                s3Options.secure = false;
                s3Options.acl = "private";
                s3Options.contentType = "image/png";
                s3Options.filename = fileReference.name;
                s3Options.success_action_status = "201";
                s3Options.policy = policy.policy;
                s3Options.signature = policy.signature;

                service = new S3PostRequest( Settings.accessKey, Settings.bucket, Settings.secret_key, s3Options );

                service.addEventListener( Event.OPEN, function( event : Event ) : void
                {
                    trace( "Uploading..." );
                    trace( "Upload started: " + fileReference.name );
                } );
                service.addEventListener( ProgressEvent.PROGRESS, function( event : ProgressEvent ) : void
                {
                    trace( Math.floor( event.bytesLoaded / event.bytesTotal * 100 ) );
                } );
                service.addEventListener( IOErrorEvent.IO_ERROR, function( event : IOErrorEvent ) : void
                {
                    trace( "Upload error!" );
                    trace( "An IO error occurred: " + event );
                } );
                service.addEventListener( SecurityErrorEvent.SECURITY_ERROR, function( event : SecurityErrorEvent ) : void
                {
                    trace( "Upload error!" );
                    trace( "A security error occurred: " + event );
                } );
                service.addEventListener( DataEvent.UPLOAD_COMPLETE_DATA, function( event : Event ) : void
                {
                    trace( "Upload complete!" );
                    trace( "Upload completed: " + event );
                    dm.selectedFiles.splice( 0, 1 );
                } );

                try
                {
                    service.upload( fileReference );
                }
                catch(e : Error)
                {
                    trace( "Upload error!" );
                    trace( "An error occurred: " + e );
                }
            }
        }
    }
}

Ответы [ 2 ]

0 голосов
/ 19 августа 2011

Мне удалось заставить мой код работать, сложность в том, чтобы получить правильную политику .Я использую библиотеку elctech для генерации вызова загрузки s3.

import com.elctech.*;

public class Uploader{
  private var _options : S3UploadOptions = new S3UploadOptions();

  // ...

  public function uploadPDF(tempFile:File):void{
     _options.FileSize          = tempFile.size.toString();
     _options.FileName          = getFileName(tempFile);
     _options.ContentType       = 'application/pdf';
     _options.key               = certificate['key'] + _options.FileName;

     _options.policy         = certificate['policy'];
     _options.signature      = certificate['signature'];
     _options.bucket         = certificate['bucket'];
     _options.AWSAccessKeyId = certificate['accessKey'];
     _options.acl            = certificate['acl'];
     _options.Expires        = certificate['expiration'];
     _options.Secure         = 'false';
     _options.successactionstatus = certificate['sas'];

     var request:S3UploadRequest = new S3UploadRequest(_options);
     configureUploadListeners(request);

     try {
        request.upload(tempFile);
     } catch(e:Error) {
        trace("An error occurred: " + e);
     }
  }

  private function getFileName(file:FileReference):String {
        var fileName:String = file.name.replace(/^.*(\\|\/)/gi, '').replace(/[^A-Za-z0-9\.\-]/gi, '_');
        return fileName;
  }
}

Я получаю сертификат amazon s3 из нашего основного приложения Rails через наш API, вот как выглядит генерация политики:

def certificate
  bucket = ENV['S3_BUCKET']
  access_key = ENV['S3_KEY']
  secret = ENV['S3_SECRET']
  key = "temp/"
  expiration = 10.hours.from_now.utc.strftime('%Y-%m-%dT%H:%M:%S.000Z')
  max_filesize = 500.megabytes
  acl = 'public-read'
  sas = '201'
  policy = Base64.encode64(
    "{'expiration': '#{expiration}',
      'conditions': [
          {'bucket': '#{bucket}'},
          ['starts-with', '$key', '#{key}'],
          {'acl': '#{acl}'},
          {'Content-Type': 'application/pdf'},
          {'Content-Disposition': 'attachment'},
          ['starts-with', '$Filename', ''],
          ['eq', '$success_action_status', '201']
      ]}
    ").gsub(/\n|\r/, '')
  signature = Base64.encode64(OpenSSL::HMAC.digest(OpenSSL::Digest::Digest.new('sha1'), secret, policy)).gsub(/\n| |\r/, '')
  { :access_key => access_key, :key => key, :policy => policy, :signature => signature, :sas => sas, :bucket => bucket, :acl => acl, :expiration => expiration }
end
0 голосов
/ 17 августа 2011

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

var policyURL = "..."; //something like "http://domain.s3.amazonaws.com/crossdomain.xml"
flash.security.Security.loadPolicyFile(policyURL);
fileReference.addEventListener(Event.SELECT, selectHandler);
fileReference.browse();

function selectHandler(e: Event) {
    fileReference = event.target;

    s3options = new flash.net.URLVariables();
    s3Options.secure = false;
    s3Options.acl = "private";
    s3Options.contentType = "image/png";
    s3Options.filename = fileReference.name;
    s3Options.success_action_status = "201";
    s3Options.policy = policy;
    s3Options.signature = signature;

    uploadURL = new flash.net.URLRequest();
    uploadURL.data = s3Options;
    fileReference.upload(uploadURL, "file", false);
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...