vertical-s3_swf_upload 0.3.2.1

Sign up to get free protection for your applications and to get access to all the features.
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
+ }