vertical-s3_swf_upload 0.3.2.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. data/.gitignore +6 -0
  2. data/CHANGELOG +26 -0
  3. data/Gemfile +4 -0
  4. data/MIT-LICENSE +20 -0
  5. data/Manifest +34 -0
  6. data/README.textile +227 -0
  7. data/Rakefile +14 -0
  8. data/flex_src/bin-release/flex-config.xml +361 -0
  9. data/flex_src/compile +2 -0
  10. data/flex_src/src/Globals.as +15 -0
  11. data/flex_src/src/S3Uploader.as +204 -0
  12. data/flex_src/src/com/adobe/net/MimeTypeMap.as +196 -0
  13. data/flex_src/src/com/elctech/S3UploadOptions.as +32 -0
  14. data/flex_src/src/com/elctech/S3UploadRequest.as +259 -0
  15. data/flex_src/src/com/nathancolgate/s3_swf_upload/BrowseButton.as +55 -0
  16. data/flex_src/src/com/nathancolgate/s3_swf_upload/S3Queue.as +117 -0
  17. data/flex_src/src/com/nathancolgate/s3_swf_upload/S3Signature.as +119 -0
  18. data/flex_src/src/com/nathancolgate/s3_swf_upload/S3Upload.as +111 -0
  19. data/lib/patch/integer.rb +12 -0
  20. data/lib/s3_swf_upload.rb +10 -0
  21. data/lib/s3_swf_upload/railtie.rb +16 -0
  22. data/lib/s3_swf_upload/railties/generators/s3_swf_upload.rb +19 -0
  23. data/lib/s3_swf_upload/railties/generators/uploader/USAGE +10 -0
  24. data/lib/s3_swf_upload/railties/generators/uploader/templates/amazon_s3.yml +20 -0
  25. data/lib/s3_swf_upload/railties/generators/uploader/templates/s3_down_button.gif +0 -0
  26. data/lib/s3_swf_upload/railties/generators/uploader/templates/s3_over_button.gif +0 -0
  27. data/lib/s3_swf_upload/railties/generators/uploader/templates/s3_up_button.gif +0 -0
  28. data/lib/s3_swf_upload/railties/generators/uploader/templates/s3_upload.js +118 -0
  29. data/lib/s3_swf_upload/railties/generators/uploader/templates/s3_upload.swf +0 -0
  30. data/lib/s3_swf_upload/railties/generators/uploader/templates/s3_uploads_controller.rb +57 -0
  31. data/lib/s3_swf_upload/railties/generators/uploader/uploader_generator.rb +20 -0
  32. data/lib/s3_swf_upload/railties/tasks/crossdomain.xml +5 -0
  33. data/lib/s3_swf_upload/s3_config.rb +43 -0
  34. data/lib/s3_swf_upload/signature.rb +203 -0
  35. data/lib/s3_swf_upload/view_helpers.rb +173 -0
  36. data/s3_swf_upload.gemspec +29 -0
  37. metadata +90 -0
@@ -0,0 +1,259 @@
1
+ package com.elctech {
2
+
3
+ // import flash.events.*;
4
+ import flash.events.EventDispatcher;
5
+ import flash.events.ProgressEvent;
6
+ import flash.events.Event;
7
+ import flash.events.IOErrorEvent;
8
+ import flash.events.SecurityErrorEvent;
9
+ import flash.events.HTTPStatusEvent;
10
+ import flash.events.DataEvent;
11
+
12
+ // import flash.net.*;
13
+ import flash.net.FileReference;
14
+ import flash.net.URLVariables;
15
+ import flash.net.URLRequest;
16
+ import flash.net.URLRequestMethod;
17
+
18
+ import flash.system.Security;
19
+ import flash.xml.XMLDocument;
20
+ import flash.xml.XMLNode;
21
+ // import mx.controls.Alert;
22
+
23
+ /**
24
+ * This class encapsulates a POST request to S3.
25
+ *
26
+ * After you create an S3PostRequest, invoke S3PostRequest::upload(fileReference:FileReference).
27
+ *
28
+ */
29
+ public class S3UploadRequest extends EventDispatcher {
30
+
31
+ [Event(name="open", type="flash.events.Event.OPEN")]
32
+ [Event(name="uploadCompleteData", type="flash.events.DataEvent.UPLOAD_COMPLETE_DATA")]
33
+ [Event(name="ioError", type="flash.events.IOErrorEvent.IO_ERROR")]
34
+ [Event(name="securityError", type="flash.events.SecurityErrorEvent.SECURITY_ERROR")]
35
+ [Event(name="progress", type="flash.events.ProgressEvent.PROGRESS")]
36
+
37
+ private var _accessKeyId:String;
38
+ private var _bucket:String;
39
+ private var _key:String;
40
+ private var _options:S3UploadOptions;
41
+ private var _httpStatusErrorReceived:Boolean;
42
+ private var _uploadStarted:Boolean;
43
+ private var fileReference:FileReference;
44
+
45
+ private const ENDPOINT:String = "s3.amazonaws.com";
46
+ private const MIN_BUCKET_LENGTH:int = 3;
47
+ private const MAX_BUCKET_LENGTH:int = 63;
48
+
49
+
50
+ /**
51
+ * Creates and initializes a new S3PostRequest object.
52
+ * @param accessKeyId The AWS access key id to authenticate the request
53
+ * @param bucket The bucket to POST into
54
+ * @param key The key to create
55
+ * @param options Options for this request
56
+ */
57
+ public function S3UploadRequest(options:S3UploadOptions) {
58
+
59
+ _accessKeyId = options.AWSAccessKeyId;
60
+ _bucket = options.bucket;
61
+ _key = options.key;
62
+ _options = options;
63
+
64
+ if (options.newKey) { //NOTE that we stop caring about the specified prefix if we have a newkey.
65
+ _key = options.newKey;
66
+ options.key = options.newKey; //so we output the right value in callbacks, etc.
67
+ }
68
+ }
69
+
70
+ private function buildUrl():String {
71
+
72
+ var canUseVanityStyle:Boolean = canUseVanityStyle(_bucket);
73
+
74
+ if(_options.Secure!="false" && canUseVanityStyle && _bucket.match(/\./)) {
75
+ // We cannot use SSL for bucket names containing "."
76
+ // The certificate won't match "my.bucket.s3.amazonaws.com"
77
+ throw new SecurityError("Cannot use SSL with bucket name containing '.': " + _bucket);
78
+ }
79
+
80
+ var postUrl:String = "http" + ((_options.Secure == 'true') ? "s" : "") + "://";
81
+
82
+ if(canUseVanityStyle) {
83
+ postUrl += _bucket + "." + ENDPOINT;
84
+ } else {
85
+ postUrl += ENDPOINT + "/" + _bucket;
86
+ }
87
+
88
+ return postUrl;
89
+ }
90
+
91
+ private function canUseVanityStyle(bucket:String):Boolean {
92
+ if( bucket.length < MIN_BUCKET_LENGTH ||
93
+ bucket.length > MAX_BUCKET_LENGTH ||
94
+ bucket.match(/^\./) ||
95
+ bucket.match(/\.$/) ) {
96
+ return false;
97
+ }
98
+
99
+ // must be lower case
100
+ if(bucket.toLowerCase() != bucket) {
101
+ return false;
102
+ }
103
+
104
+ // Check not IPv4-like
105
+ if (bucket.match(/^[0-9]|+\.[0-9]|+\.[0-9]|+\.[0-9]|+$/)) {
106
+ return false;
107
+ }
108
+
109
+ // Check each label
110
+ if(bucket.match(/\./)) {
111
+ var labels:Array = bucket.split(/\./);
112
+ for (var i:int = 0;i < labels.length; i++) {
113
+ if(!labels[i].match(/^[a-z0-9]([a-z0-9\-]*[a-z0-9])?$/)) {
114
+ return false;
115
+ }
116
+ }
117
+ }
118
+
119
+ return true;
120
+ }
121
+
122
+ private function loadPolicyFile(postUrl:String):void {
123
+ /*
124
+ * Due to the restrictions imposed by the Adobe Flash security sandbox,
125
+ * the bucket being uploaded to must contain a public-readable crossdomain.xml
126
+ * file that allows access from the domain that served the SWF hosting this code.
127
+ *
128
+ * Read Adobe's documentation on the Flash security sandbox for more information.
129
+ *
130
+ */
131
+
132
+ Security.loadPolicyFile(postUrl + "/crossdomain.xml");
133
+ }
134
+
135
+
136
+ public function removeListeners():void {
137
+ trace('removeListeners');
138
+ fileReference.removeEventListener(Event.OPEN, onOpen);
139
+ fileReference.removeEventListener(ProgressEvent.PROGRESS, onProgress);
140
+ fileReference.removeEventListener(IOErrorEvent.IO_ERROR, onIOError);
141
+ fileReference.removeEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
142
+ fileReference.removeEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData);
143
+ fileReference.removeEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpStatus);
144
+ }
145
+ /**
146
+ * Initiates a POST upload request to S3
147
+ * @param fileReference A FileReference object referencing the file to upload to S3.
148
+ */
149
+ public function upload(_fileReference:FileReference):void {
150
+
151
+ if(_uploadStarted) {
152
+ throw new Error("S3PostRequest object cannot be reused. Create another S3PostRequest object to send another request to Amazon S3.");
153
+ }
154
+ _uploadStarted = true;
155
+
156
+ // Save the FileReference object so that it doesn't get GCed.
157
+ // If this happens, we can lose events that should be dispatched.
158
+ fileReference = _fileReference;
159
+
160
+ var postUrl:String = buildUrl();
161
+ loadPolicyFile(postUrl);
162
+ var urlRequest:URLRequest = new URLRequest(postUrl);
163
+ urlRequest.method = URLRequestMethod.POST;
164
+ urlRequest.data = buildPostVariables();
165
+
166
+ // set up event handlers *****************************************************
167
+ fileReference.addEventListener(Event.OPEN, onOpen);
168
+ fileReference.addEventListener(ProgressEvent.PROGRESS, onProgress);
169
+ fileReference.addEventListener(IOErrorEvent.IO_ERROR, onIOError);
170
+ fileReference.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSecurityError);
171
+ fileReference.addEventListener(DataEvent.UPLOAD_COMPLETE_DATA, onUploadCompleteData);
172
+ fileReference.addEventListener(HTTPStatusEvent.HTTP_STATUS, onHttpStatus);
173
+ // *****************************************************************************
174
+
175
+ // send the request
176
+ fileReference.upload(urlRequest, "file", false);
177
+ }
178
+
179
+ private function buildPostVariables():URLVariables {
180
+
181
+ var postVariables:URLVariables = new URLVariables();
182
+
183
+ postVariables.key = _key;
184
+ postVariables.acl = _options.acl;
185
+ postVariables.AWSAccessKeyId = _accessKeyId;
186
+ postVariables.signature = _options.signature;
187
+ postVariables["Content-Type"] = _options.ContentType;
188
+ postVariables["Content-Disposition"] = _options.ContentDisposition;
189
+ postVariables.policy = _options.policy;
190
+
191
+ /**
192
+ * Certain combinations of Flash player version and platform don't handle
193
+ * HTTP responses with the header 'Content-Length: 0'. These clients do not
194
+ * dispatch completion or error events when such a response is received.
195
+ * Therefore it is impossible to tell when the upload has completed or failed.
196
+ *
197
+ * Flash clients should always set the success_action_status parameter to 201
198
+ * so that Amazon S3 returns a response with Content-Length being non-zero.
199
+ *
200
+ */
201
+ postVariables.success_action_status = "201";
202
+
203
+ return postVariables;
204
+ }
205
+
206
+ private function onOpen(event:Event):void {
207
+ trace('onOpen: '+this._key);
208
+ this.dispatchEvent(event);
209
+ }
210
+ private function onIOError(event:IOErrorEvent):void {
211
+ /*
212
+ * FileReference.upload likes to send cryptic IOErrors when it doesn't get a status code that it likes.
213
+ * If we already got an error HTTP status code, don't propagate this event since the HTTPStatusEvent
214
+ * event handler dispatches an IOErrorEvent.
215
+ */
216
+ if(!_httpStatusErrorReceived) {
217
+ this.dispatchEvent(event);
218
+ }
219
+ }
220
+ private function onSecurityError(event:SecurityErrorEvent):void {
221
+ this.dispatchEvent(event);
222
+ }
223
+ private function onProgress(event:ProgressEvent):void {
224
+ this.dispatchEvent(event);
225
+ }
226
+ private function onUploadCompleteData(event:DataEvent):void {
227
+ var data:String = event.data;
228
+ if(isError(data)) {
229
+ this.dispatchEvent(
230
+ new IOErrorEvent(IOErrorEvent.IO_ERROR, event.bubbles, event.cancelable, "Amazon S3 returned an error: " + data + ".")
231
+ );
232
+ } else {
233
+ this.dispatchEvent(new DataEvent(DataEvent.UPLOAD_COMPLETE_DATA, event.bubbles, event.cancelable, data));
234
+ }
235
+ }
236
+ private function onHttpStatus(event:HTTPStatusEvent):void {
237
+ _httpStatusErrorReceived = true;
238
+ if(Math.floor(event.status/100) == 2) {
239
+ this.dispatchEvent(new DataEvent(DataEvent.UPLOAD_COMPLETE_DATA, event.bubbles, event.cancelable, "Amazon S3 returned HTTP status " + event.status.toString() + "."));
240
+ } else {
241
+ this.dispatchEvent(new IOErrorEvent(IOErrorEvent.IO_ERROR, event.bubbles, event.cancelable, "Amazon S3 returned an error: HTTP status " + event.status.toString() + "."));
242
+ }
243
+ }
244
+
245
+ private function isError(responseText:String):Boolean {
246
+ var xml:XMLDocument = new XMLDocument();
247
+ xml.ignoreWhite = true;
248
+ xml.parseXML(responseText);
249
+ var root:XMLNode = xml.firstChild;
250
+ if( root == null || root.nodeName != "Error" )
251
+ {
252
+ return false;
253
+ }
254
+ return true;
255
+ }
256
+
257
+ }
258
+
259
+ }
@@ -0,0 +1,55 @@
1
+ package com.nathancolgate.s3_swf_upload {
2
+
3
+ import flash.display.*;
4
+ import flash.events.MouseEvent;
5
+ import flash.events.Event;
6
+ import flash.net.*;
7
+
8
+ public dynamic class BrowseButton extends Sprite {
9
+
10
+ private var _playButton:flash.display.SimpleButton;
11
+
12
+ public function BrowseButton(width:Number,
13
+ height:Number,
14
+ buttonUpUrl:String,
15
+ buttonDownUrl:String,
16
+ buttonOverUrl:String)
17
+ {
18
+ super();
19
+
20
+ _playButton = new flash.display.SimpleButton();
21
+ _playButton.useHandCursor = true;
22
+ addChild(_playButton);
23
+
24
+ // Hit Test
25
+ var hit_test:Shape = new flash.display.Shape();
26
+ hit_test.graphics.beginFill(0xFFCC00);
27
+ hit_test.graphics.drawRect(0, 0, width, height);
28
+ hit_test.graphics.endFill();
29
+ _playButton.hitTestState = hit_test;
30
+
31
+ // Up
32
+ var upLoader:Loader = new Loader();
33
+ upLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
34
+ _playButton.upState = new Bitmap(e.target.content.bitmapData);
35
+ });
36
+ upLoader.load(new URLRequest(buttonUpUrl));
37
+
38
+ // Down
39
+ var downLoader:Loader = new Loader();
40
+ downLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
41
+ _playButton.downState = new Bitmap(e.target.content.bitmapData);
42
+ });
43
+ downLoader.load(new URLRequest(buttonDownUrl));
44
+
45
+ // Over
46
+ var overLoader:Loader = new Loader();
47
+ overLoader.contentLoaderInfo.addEventListener(Event.COMPLETE,function(e:Event):void{
48
+ _playButton.overState = new Bitmap(e.target.content.bitmapData);
49
+ });
50
+ overLoader.load(new URLRequest(buttonOverUrl));
51
+ }
52
+
53
+
54
+ }
55
+ }
@@ -0,0 +1,117 @@
1
+ package com.nathancolgate.s3_swf_upload {
2
+
3
+ import mx.collections.ArrayCollection;
4
+ import mx.events.CollectionEvent;
5
+ import flash.external.ExternalInterface;
6
+ import flash.net.FileReference;
7
+ import com.nathancolgate.s3_swf_upload.*;
8
+
9
+ public class S3Queue extends ArrayCollection {
10
+
11
+ // S3 Interaction Vars
12
+ private var _signatureUrl:String;
13
+ private var _prefixPath:String;
14
+
15
+ public var currentSignature:S3Signature;
16
+
17
+ public function S3Queue(signatureUrl:String,
18
+ prefixPath:String,
19
+ source:Array = null) {
20
+
21
+ _signatureUrl = signatureUrl;
22
+ _prefixPath = prefixPath;
23
+ super(source);
24
+
25
+ // Outgoing calls
26
+ this.addEventListener(CollectionEvent.COLLECTION_CHANGE, changeHandler);
27
+ // Incoming calls
28
+ ExternalInterface.addCallback("startUploading", startUploadingHandler);
29
+ ExternalInterface.addCallback("clearQueue", clearHandler);
30
+ ExternalInterface.addCallback("stopUploading", stopUploadingHandler);
31
+ }
32
+
33
+ public function uploadNextFile():void{
34
+ // ExternalInterface.call('s3_swf.jsLog','uploadNextFile');
35
+ // ExternalInterface.call('s3_swf.jsLog','Start uploadNextFile...');
36
+ var next_file:FileReference = FileReference(this.getItemAt(0));
37
+ currentSignature = new S3Signature(next_file,_signatureUrl,_prefixPath);
38
+ // ExternalInterface.call('s3_swf.jsLog','End uploadNextFile');
39
+ }
40
+
41
+ // whenever the queue changes this function is called
42
+ private function changeHandler(event:CollectionEvent):void{
43
+ // ExternalInterface.call('s3_swf.jsLog','changeHandler');
44
+ // ExternalInterface.call('s3_swf.jsLog','Calling onQueueChange...');
45
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onQueueChange',this.toJavascript());
46
+ // ExternalInterface.call('s3_swf.jsLog','onQueueChange called');
47
+ }
48
+
49
+ // Remove all files from the upload queue;
50
+ private function clearHandler():void{
51
+ // ExternalInterface.call('s3_swf.jsLog','clearHandler');
52
+ // ExternalInterface.call('s3_swf.jsLog','Removing All...');
53
+ this.removeAll();
54
+ // ExternalInterface.call('s3_swf.jsLog','All removed');
55
+ // ExternalInterface.call('s3_swf.jsLog','Calling onQueueClear...');
56
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onQueueClear',this.toJavascript());
57
+ // ExternalInterface.call('s3_swf.jsLog','onQueueClear called');
58
+ }
59
+
60
+ // Start uploading the files from the queue
61
+ private function startUploadingHandler():void{
62
+ // ExternalInterface.call('s3_swf.jsLog','startUploadingHandler');
63
+ if (this.length > 0){
64
+ // ExternalInterface.call('s3_swf.jsLog','Calling onUploadingStart...');
65
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onUploadingStart');
66
+ // ExternalInterface.call('s3_swf.jsLog','onUploadingStart called');
67
+ // ExternalInterface.call('s3_swf.jsLog','Uploading next file...');
68
+ uploadNextFile();
69
+ // ExternalInterface.call('s3_swf.jsLog','Next file uploaded');
70
+ } else {
71
+ // ExternalInterface.call('s3_swf.jsLog','Calling onQueueEmpty...');
72
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onQueueEmpty',this);
73
+ // ExternalInterface.call('s3_swf.jsLog','onQueueEmpty called');
74
+ }
75
+ }
76
+
77
+ // Cancel Current File Upload
78
+ // Which stops all future uploads as well
79
+ private function stopUploadingHandler():void{
80
+ // ExternalInterface.call('s3_swf.jsLog','stopUploadingHandler');
81
+ if (this.length > 0){
82
+ var current_file:FileReference = FileReference(this.getItemAt(0));
83
+ // ExternalInterface.call('s3_swf.jsLog','Cancelling current file...');
84
+ current_file.cancel();
85
+
86
+ currentSignature.s3upload.removeListeners();
87
+
88
+ // ExternalInterface.call('s3_swf.jsLog','Current file cancelled');
89
+ // ExternalInterface.call('s3_swf.jsLog','Calling onUploadingStop...');
90
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onUploadingStop');
91
+ // ExternalInterface.call('s3_swf.jsLog','onUploadingStop called');
92
+ } else {
93
+ // ExternalInterface.call('s3_swf.jsLog','Calling onQueueEmpty...');
94
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onQueueEmpty',this.toJavascript());
95
+ // ExternalInterface.call('s3_swf.jsLog','onQueueEmpty called');
96
+ }
97
+ }
98
+
99
+ // This is a rather silly function to need, especially since it worked at one point
100
+ // In flash player 10.1, you could no longer send files over external reference
101
+ // This is the hack to get around the problem. Essentially: turn all those
102
+ // Files into objects
103
+ // August 27, 2010 - NCC@BNB
104
+ public function toJavascript():Object {
105
+ var faux_queue:Object = new Object();
106
+ faux_queue.files = new Array();
107
+ for (var i:int = 0;i < source.length; i++) {
108
+ faux_queue.files[i] = new Object();
109
+ faux_queue.files[i].name = source[i].name;
110
+ faux_queue.files[i].size = source[i].size;
111
+ faux_queue.files[i].type = source[i].type;
112
+ }
113
+ return faux_queue;
114
+ }
115
+
116
+ }
117
+ }
@@ -0,0 +1,119 @@
1
+ package com.nathancolgate.s3_swf_upload {
2
+
3
+ import com.elctech.S3UploadOptions;
4
+ import com.nathancolgate.s3_swf_upload.*;
5
+ import flash.external.ExternalInterface;
6
+ import com.adobe.net.MimeTypeMap;
7
+
8
+ import flash.net.*
9
+ import flash.events.*
10
+
11
+ public class S3Signature {
12
+
13
+ private var upload_options:S3UploadOptions;
14
+ private var _file:FileReference;
15
+ //private var _prefixPath:String
16
+
17
+ public var s3upload:S3Upload;
18
+
19
+ public function S3Signature(file:FileReference,
20
+ signatureUrl:String,
21
+ prefixPath:String) {
22
+ _file = file;
23
+ // _prefixPath = prefixPath
24
+ // Create options list for file s3 upload metadata
25
+ upload_options = new S3UploadOptions;
26
+ upload_options.FileSize = _file.size.toString();
27
+ upload_options.FileName = getFileName(_file);
28
+ upload_options.ContentType = getContentType(upload_options.FileName);
29
+ upload_options.key = prefixPath + upload_options.FileName;
30
+
31
+ var variables:URLVariables = new URLVariables();
32
+ variables.key = upload_options.key
33
+ variables.content_type = upload_options.ContentType;
34
+
35
+ var request:URLRequest = new URLRequest(signatureUrl);
36
+ request.method = URLRequestMethod.GET;
37
+ request.data = variables;
38
+
39
+ var signature:URLLoader = new URLLoader();
40
+ signature.dataFormat = URLLoaderDataFormat.TEXT;
41
+ signature.addEventListener(Event.OPEN, openHandler);
42
+ signature.addEventListener(ProgressEvent.PROGRESS, progressHandler);
43
+ signature.addEventListener(SecurityErrorEvent.SECURITY_ERROR, securityErrorHandler);
44
+ signature.addEventListener(HTTPStatusEvent.HTTP_STATUS, httpStatusHandler);
45
+ signature.addEventListener(IOErrorEvent.IO_ERROR, ioErrorHandler);
46
+ signature.addEventListener(Event.COMPLETE, completeHandler);
47
+ signature.load(request);
48
+ }
49
+
50
+ private function openHandler(event:Event):void {
51
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureOpen',toJavascript(_file),event);
52
+ }
53
+
54
+ private function progressHandler(progress_event:ProgressEvent):void {
55
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureProgress',toJavascript(_file),progress_event);
56
+ }
57
+
58
+ private function securityErrorHandler(security_error_event:SecurityErrorEvent):void {
59
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureSecurityError',toJavascript(_file),security_error_event);
60
+ }
61
+
62
+ private function httpStatusHandler(http_status_event:HTTPStatusEvent):void {
63
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureHttpStatus',toJavascript(_file),http_status_event);
64
+ }
65
+
66
+ private function ioErrorHandler(io_error_event:IOErrorEvent):void {
67
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureIOError',toJavascript(_file),io_error_event);
68
+ }
69
+
70
+ private function completeHandler(event:Event):void {
71
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureComplete',toJavascript(_file),event);
72
+ var loader:URLLoader = URLLoader(event.target);
73
+ var xml:XML = new XML(loader.data);
74
+
75
+ // create the s3 options object
76
+ upload_options.policy = xml.policy;
77
+ upload_options.signature = xml.signature;
78
+ upload_options.bucket = xml.bucket;
79
+ upload_options.AWSAccessKeyId = xml.accesskeyid;
80
+ upload_options.acl = xml.acl;
81
+ upload_options.Expires = xml.expirationdate;
82
+ upload_options.Secure = xml.https;
83
+ upload_options.ContentDisposition = xml.contentDisposition;
84
+ upload_options.newKey = xml.newKey; //NOTE that we stop caring about the specified prefix if we have a newkey.
85
+
86
+ if (xml.errorMessage != "") {
87
+ ExternalInterface.call(S3Uploader.s3_swf_obj+'.onSignatureXMLError',toJavascript(_file),xml.errorMessage);
88
+ return;
89
+ }
90
+
91
+ s3upload = new S3Upload(upload_options);
92
+ }
93
+
94
+ /* MISC */
95
+
96
+ private function getContentType(fileName:String):String {
97
+ var fileNameArray:Array = fileName.split(/\./);
98
+ var fileExtension:String = fileNameArray[fileNameArray.length - 1];
99
+ var mimeMap:MimeTypeMap = new MimeTypeMap;
100
+ var contentType:String = mimeMap.getMimeType(fileExtension);
101
+ return contentType;
102
+ }
103
+
104
+ private function getFileName(file:FileReference):String {
105
+ var fileName:String = file.name.replace(/^.*(\\|\/)/gi, '').replace(/[^A-Za-z0-9\.\-]/gi, '_');
106
+ return fileName;
107
+ }
108
+
109
+ // Turns a FileReference into an Object so that ExternalInterface doesn't choke
110
+ private function toJavascript(file:FileReference):Object{
111
+ var javascriptable_file:Object = new Object();
112
+ javascriptable_file.name = file.name;
113
+ javascriptable_file.size = file.size;
114
+ javascriptable_file.type = file.type;
115
+ return javascriptable_file;
116
+ }
117
+
118
+ }
119
+ }