diff options
Diffstat (limited to 'webcam')
| -rw-r--r-- | webcam/Webcam.as | 2 | ||||
| -rw-r--r-- | webcam/com/marstonstudio/UploadPostHelper.as | 21 | ||||
| -rw-r--r-- | webcam/ru/inspirit/net/MultipartURLLoader.as | 582 | ||||
| -rw-r--r-- | webcam/ru/inspirit/net/events/MultipartURLLoaderEvent.as | 27 |
4 files changed, 13 insertions, 619 deletions
diff --git a/webcam/Webcam.as b/webcam/Webcam.as index c8be6ca..7a55373 100644 --- a/webcam/Webcam.as +++ b/webcam/Webcam.as @@ -1 +1 @@ -package {
/* JPEGCam v1.0.8 */
/* Webcam library for capturing JPEG images and submitting to a server */
/* Copyright (c) 2008 - 2009 Joseph Huckaby <jhuckaby@goldcartridge.com> */
/* Licensed under the GNU Lesser Public License */
/* http://www.gnu.org/licenses/lgpl.html */
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;
import flash.utils.*;
import flash.media.Camera;
import flash.media.Video;
import flash.external.ExternalInterface;
import flash.net.*;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.geom.Matrix;
import com.adobe.images.JPGEncoder;
public class Webcam extends Sprite {
private var video:Video;
private var encoder:JPGEncoder;
private var snd:Sound;
private var channel:SoundChannel = new SoundChannel();
private var jpeg_quality:int;
private var video_width:int;
private var video_height:int;
private var server_width:int;
private var server_height:int;
private var camera:Camera;
private var bmp:Bitmap;
private var bmpdata:BitmapData;
private var url:String;
public function Webcam() {
// class constructor
flash.system.Security.allowDomain("*");
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
video_width = Math.floor( flashvars.width );
video_height = Math.floor( flashvars.height );
server_width = Math.floor( flashvars.server_width );
server_height = Math.floor( flashvars.server_height );
stage.scaleMode = StageScaleMode.NO_SCALE;
// stage.scaleMode = StageScaleMode.EXACT_FIT;
stage.align = StageAlign.TOP_LEFT;
stage.stageWidth = Math.max(video_width, server_width);
stage.stageHeight = Math.max(video_height, server_height);
// Hack to auto-select iSight camera on Mac (JPEGCam Issue #5, submitted by manuel.gonzalez.noriega)
// From: http://www.squidder.com/2009/03/09/trick-auto-select-mac-isight-in-flash/
var cameraIdx:int = -1;
for (var idx = 0, len = Camera.names.length; idx < len; idx++) {
if (Camera.names[idx] == "USB Video Class Video") {
cameraIdx = idx;
idx = len;
}
}
if (cameraIdx > -1) camera = Camera.getCamera( String(cameraIdx) );
else camera = Camera.getCamera();
if (camera != null) {
camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
video = new Video( Math.max(video_width, server_width), Math.max(video_height, server_height) );
video.attachCamera(camera);
addChild(video);
if ((video_width < server_width) && (video_height < server_height)) {
video.scaleX = video_width / server_width;
video.scaleY = video_height / server_height;
}
camera.setQuality(0, 100);
camera.setKeyFrameInterval(10);
camera.setMode( Math.max(video_width, server_width), Math.max(video_height, server_height), 30);
// do not detect motion (may help reduce CPU usage)
camera.setMotionLevel( 100 );
ExternalInterface.addCallback('_snap', snap);
ExternalInterface.addCallback('_configure', configure);
ExternalInterface.addCallback('_upload', upload);
ExternalInterface.addCallback('_reset', reset);
if (flashvars.shutter_enabled == 1) {
snd = new Sound();
snd.load( new URLRequest( flashvars.shutter_url ) );
}
jpeg_quality = 90;
ExternalInterface.call('webcam.flash_notify', 'flashLoadComplete', true);
}
else {
trace("You need a camera.");
ExternalInterface.call('webcam.flash_notify', "error", "No camera was detected.");
}
}
public function set_quality(new_quality:int) {
// set JPEG image quality
if (new_quality < 0) new_quality = 0;
if (new_quality > 100) new_quality = 100;
jpeg_quality = new_quality;
}
public function configure(panel:String = SecurityPanel.CAMERA) {
// show configure dialog inside flash movie
Security.showSettings(panel);
}
private function activityHandler(event:ActivityEvent):void {
trace("activityHandler: " + event);
}
public function snap(url, new_quality, shutter) {
// take snapshot from camera, and upload if URL was provided
if (new_quality) set_quality(new_quality);
trace("in snap(), drawing to bitmap");
if (shutter) {
channel = snd.play();
setTimeout( snap2, 10, url );
}
else snap2(url);
}
public function snap2(url) {
// take snapshot, convert to jpeg, submit to server
bmpdata = new BitmapData( Math.max(video_width, server_width), Math.max(video_height, server_height) );
bmpdata.draw( video );
// draw snapshot on stage
bmp = new Bitmap( bmpdata );
addChild( bmp );
// stop capturing video
video.attachCamera( null );
removeChild( video );
// if URL was provided, upload now
if (url) upload( url );
}
public function upload(url) {
if (bmpdata) {
if ((video_width > server_width) && (video_height > server_height)) {
// resize image downward before submitting
var tmpdata = new BitmapData(server_width, server_height);
var matrix = new Matrix();
matrix.scale( server_width / video_width, server_height / video_height );
tmpdata.draw( bmpdata, matrix, null, null, null, true ); // smoothing
bmpdata = tmpdata;
} // need resize
trace("converting to jpeg");
var ba:ByteArray;
encoder = new JPGEncoder( jpeg_quality );
ba = encoder.encode( bmpdata );
trace("jpeg length: " + ba.length);
var head:URLRequestHeader = new URLRequestHeader("Accept","text/*");
var req:URLRequest = new URLRequest( url );
req.requestHeaders.push(head);
req.data = ba;
req.method = URLRequestMethod.POST;
req.contentType = "image/jpeg";
var loader:URLLoader = new URLLoader();
loader.addEventListener(Event.COMPLETE, onLoaded);
trace("sending post to: " + url);
try {
loader.load(req);
}
catch (error:Error) {
trace("Unable to load requested document.");
ExternalInterface.call('webcam.flash_notify', "error", "Unable to post data: " + error);
}
}
else {
ExternalInterface.call('webcam.flash_notify', "error", "Nothing to upload, must capture an image first.");
}
}
public function onLoaded(evt:Event):void {
// image upload complete
var msg = "unknown";
if (evt && evt.target && evt.target.data) msg = evt.target.data;
ExternalInterface.call('webcam.flash_notify', "success", msg);
}
public function reset() {
// reset video after taking snapshot
if (bmp) {
removeChild( bmp );
bmp = null;
bmpdata = null;
video.attachCamera(camera);
addChild(video);
}
}
}
}
\ No newline at end of file +package {
/* JPEGCam v1.0.8 */
/* Webcam library for capturing JPEG images and submitting to a server */
/* Copyright (c) 2008 - 2009 Joseph Huckaby <jhuckaby@goldcartridge.com> */
/* Licensed under the GNU Lesser Public License */
/* http://www.gnu.org/licenses/lgpl.html */
import flash.display.LoaderInfo;
import flash.display.Sprite;
import flash.display.StageAlign;
import flash.display.StageScaleMode;
import flash.display.Bitmap;
import flash.display.BitmapData;
import flash.events.*;
import flash.utils.*;
import flash.media.Camera;
import flash.media.Video;
import flash.external.ExternalInterface;
import flash.net.*;
import flash.system.Security;
import flash.system.SecurityPanel;
import flash.media.Sound;
import flash.media.SoundChannel;
import flash.geom.Matrix;
import com.adobe.images.JPGEncoder;
import com.marstonstudio.UploadPostHelper;
public class Webcam extends Sprite {
private var video:Video;
private var encoder:JPGEncoder;
private var snd:Sound;
private var channel:SoundChannel = new SoundChannel();
private var jpeg_quality:int;
private var video_width:int;
private var video_height:int;
private var server_width:int;
private var server_height:int;
private var camera:Camera;
private var bmp:Bitmap;
private var bmpdata:BitmapData;
private var url:String;
private var form_data:Object;
public function Webcam() {
// class constructor
flash.system.Security.allowDomain("*");
var flashvars:Object = LoaderInfo(this.root.loaderInfo).parameters;
video_width = Math.floor( flashvars.width );
video_height = Math.floor( flashvars.height );
server_width = Math.floor( flashvars.server_width );
server_height = Math.floor( flashvars.server_height );
form_data = {};
stage.scaleMode = StageScaleMode.NO_SCALE;
// stage.scaleMode = StageScaleMode.EXACT_FIT;
stage.align = StageAlign.TOP_LEFT;
stage.stageWidth = Math.max(video_width, server_width);
stage.stageHeight = Math.max(video_height, server_height);
// Hack to auto-select iSight camera on Mac (JPEGCam Issue #5, submitted by manuel.gonzalez.noriega)
// From: http://www.squidder.com/2009/03/09/trick-auto-select-mac-isight-in-flash/
var cameraIdx:int = -1;
for (var idx = 0, len = Camera.names.length; idx < len; idx++) {
if (Camera.names[idx] == "USB Video Class Video") {
cameraIdx = idx;
idx = len;
}
}
if (cameraIdx > -1) camera = Camera.getCamera( String(cameraIdx) );
else camera = Camera.getCamera();
if (camera != null) {
camera.addEventListener(ActivityEvent.ACTIVITY, activityHandler);
video = new Video( Math.max(video_width, server_width), Math.max(video_height, server_height) );
video.attachCamera(camera);
addChild(video);
if ((video_width < server_width) && (video_height < server_height)) {
video.scaleX = video_width / server_width;
video.scaleY = video_height / server_height;
}
camera.setQuality(0, 100);
camera.setKeyFrameInterval(10);
camera.setMode( Math.max(video_width, server_width), Math.max(video_height, server_height), 30);
// do not detect motion (may help reduce CPU usage)
camera.setMotionLevel( 100 );
ExternalInterface.addCallback('_snap', snap);
ExternalInterface.addCallback('_configure', configure);
ExternalInterface.addCallback('_upload', upload);
ExternalInterface.addCallback('_reset', reset);
ExternalInterface.addCallback('_set_form_data', set_form_data);
if (flashvars.shutter_enabled == 1) {
snd = new Sound();
snd.load( new URLRequest( flashvars.shutter_url ) );
}
jpeg_quality = 90;
ExternalInterface.call('webcam.flash_notify', 'flashLoadComplete', true);
}
else {
trace("You need a camera.");
ExternalInterface.call('webcam.flash_notify', "error", "No camera was detected.");
}
}
public function set_quality(new_quality:int) {
// set JPEG image quality
if (new_quality < 0) new_quality = 0;
if (new_quality > 100) new_quality = 100;
jpeg_quality = new_quality;
}
public function set_form_data(new_form_data:Object) {
form_data = new_form_data;
}
public function configure(panel:String = SecurityPanel.CAMERA) {
// show configure dialog inside flash movie
Security.showSettings(panel);
}
private function activityHandler(event:ActivityEvent):void {
trace("activityHandler: " + event);
}
public function snap(url, new_quality, shutter) {
// take snapshot from camera, and upload if URL was provided
if (new_quality) set_quality(new_quality);
trace("in snap(), drawing to bitmap");
if (shutter) {
channel = snd.play();
setTimeout( snap2, 10, url );
}
else snap2(url);
}
public function snap2(url) {
// take snapshot, convert to jpeg, submit to server
bmpdata = new BitmapData( Math.max(video_width, server_width), Math.max(video_height, server_height) );
bmpdata.draw( video );
// draw snapshot on stage
bmp = new Bitmap( bmpdata );
addChild( bmp );
// stop capturing video
video.attachCamera( null );
removeChild( video );
// if URL was provided, upload now
if (url) upload( url );
}
public function upload(url) {
if (bmpdata) {
if ((video_width > server_width) && (video_height > server_height)) {
// resize image downward before submitting
var tmpdata = new BitmapData(server_width, server_height);
var matrix = new Matrix();
matrix.scale( server_width / video_width, server_height / video_height );
tmpdata.draw( bmpdata, matrix, null, null, null, true ); // smoothing
bmpdata = tmpdata;
} // need resize
trace("converting to jpeg");
var ba:ByteArray;
encoder = new JPGEncoder( jpeg_quality );
ba = encoder.encode( bmpdata );
trace("jpeg length: " + ba.length);
//URLRequest containing the form fields and the attached image
var req : URLRequest = new URLRequest(url);
req.method = URLRequestMethod.POST;
req.data = UploadPostHelper.getPostData( 'dump.fm.webcam.test.jpg', ba, form_data );
req.requestHeaders.push(new URLRequestHeader('Cache-Control', 'no-cache') );
req.requestHeaders.push(new URLRequestHeader('Content-Type', 'multipart/form-data; boundary=' + UploadPostHelper.getBoundary()));
//URLLoader to load the request
var loader : URLLoader = new URLLoader();
loader.dataFormat = URLLoaderDataFormat.BINARY;
loader.addEventListener(Event.COMPLETE, onLoaded);
trace("sending post to: " + url);
try {
loader.load(req);
}
catch (error:Error) {
trace("Unable to load requested document.");
ExternalInterface.call('webcam.flash_notify', "error", "Unable to post data: " + error);
}
}
else {
ExternalInterface.call('webcam.flash_notify', "error", "Nothing to upload, must capture an image first.");
}
}
public function onLoaded(evt:Event):void {
// image upload complete
var msg = "unknown";
if (evt && evt.target && evt.target.data) msg = evt.target.data;
ExternalInterface.call('webcam.flash_notify', "success", msg);
}
public function reset() {
// reset video after taking snapshot
if (bmp) {
removeChild( bmp );
bmp = null;
bmpdata = null;
video.attachCamera(camera);
addChild(video);
}
}
}
}
\ No newline at end of file diff --git a/webcam/com/marstonstudio/UploadPostHelper.as b/webcam/com/marstonstudio/UploadPostHelper.as index 857bc42..43eb429 100644 --- a/webcam/com/marstonstudio/UploadPostHelper.as +++ b/webcam/com/marstonstudio/UploadPostHelper.as @@ -36,7 +36,7 @@ package com.marstonstudio public static function getBoundary():String { if(_boundary.length == 0) { - for (var i:int = 0; i < 0x20; i++ ) { + for (var i:int = 0; i < 0x20; i++ ) { _boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) ); } } @@ -66,7 +66,7 @@ package com.marstonstudio postData = BOUNDARY(postData); postData = LINEBREAK(postData); bytes = 'Content-Disposition: form-data; name="' + name + '"'; - for ( i = 0; i < bytes.length; i++ ) { + for ( i = 0; i < bytes.length; i++ ) { postData.writeByte( bytes.charCodeAt(i) ); } postData = LINEBREAK(postData); @@ -78,15 +78,15 @@ package com.marstonstudio //add Filedata to postData postData = BOUNDARY(postData); postData = LINEBREAK(postData); - bytes = 'Content-Disposition: form-data; name="Filedata"; filename="'; - for ( i = 0; i < bytes.length; i++ ) { + bytes = 'Content-Disposition: form-data; name="image"; filename="'; + for ( i = 0; i < bytes.length; i++ ) { postData.writeByte( bytes.charCodeAt(i) ); } postData.writeUTFBytes(fileName); postData = QUOTATIONMARK(postData); postData = LINEBREAK(postData); - bytes = 'Content-Type: application/octet-stream'; - for ( i = 0; i < bytes.length; i++ ) { + bytes = 'Content-Type: image/jpeg'; + for ( i = 0; i < bytes.length; i++ ) { postData.writeByte( bytes.charCodeAt(i) ); } postData = LINEBREAK(postData); @@ -94,21 +94,24 @@ package com.marstonstudio postData.writeBytes(byteArray, 0, byteArray.length); postData = LINEBREAK(postData); + // timb: i commented this shit out because i don't think it's needed //add upload filed to postData + /* postData = LINEBREAK(postData); postData = BOUNDARY(postData); postData = LINEBREAK(postData); bytes = 'Content-Disposition: form-data; name="Upload"'; - for ( i = 0; i < bytes.length; i++ ) { + for ( i = 0; i < bytes.length; i++ ) { postData.writeByte( bytes.charCodeAt(i) ); } postData = LINEBREAK(postData); postData = LINEBREAK(postData); bytes = 'Submit Query'; - for ( i = 0; i < bytes.length; i++ ) { + for ( i = 0; i < bytes.length; i++ ) { postData.writeByte( bytes.charCodeAt(i) ); } postData = LINEBREAK(postData); + */ //closing boundary postData = BOUNDARY(postData); @@ -124,7 +127,7 @@ package com.marstonstudio var l:int = UploadPostHelper.getBoundary().length; p = DOUBLEDASH(p); - for (var i:int = 0; i < l; i++ ) { + for (var i:int = 0; i < l; i++ ) { p.writeByte( _boundary.charCodeAt( i ) ); } return p; diff --git a/webcam/ru/inspirit/net/MultipartURLLoader.as b/webcam/ru/inspirit/net/MultipartURLLoader.as deleted file mode 100644 index bfd3db2..0000000 --- a/webcam/ru/inspirit/net/MultipartURLLoader.as +++ /dev/null @@ -1,582 +0,0 @@ -package ru.inspirit.net
-{
- import flash.errors.IllegalOperationError;
- import flash.events.Event;
- import flash.events.EventDispatcher;
- import flash.events.HTTPStatusEvent;
- import flash.events.IOErrorEvent;
- import flash.events.ProgressEvent;
- import flash.events.SecurityErrorEvent;
- import flash.net.URLLoader;
- import flash.net.URLLoaderDataFormat;
- import flash.net.URLRequest;
- import flash.net.URLRequestHeader;
- import flash.net.URLRequestMethod;
- import flash.utils.ByteArray;
- import flash.utils.Dictionary;
- import flash.utils.Endian;
- import flash.utils.setTimeout;
- import flash.utils.clearInterval;
- import ru.inspirit.net.events.MultipartURLLoaderEvent;
-
- /**
- * Multipart URL Loader
- *
- * Original idea by Marston Development Studio - http://marstonstudio.com/?p=36
- *
- * History
- * 2009.01.15 version 1.0
- * Initial release
- *
- * 2009.01.19 version 1.1
- * Added options for MIME-types (default is application/octet-stream)
- *
- * 2009.01.20 version 1.2
- * Added clearVariables and clearFiles methods
- * Small code refactoring
- * Public methods documentaion
- *
- * 2009.02.09 version 1.2.1
- * Changed 'useWeakReference' to false (thanx to zlatko)
- * It appears that on some servers setting 'useWeakReference' to true
- * completely disables this event
- *
- * 2009.03.05 version 1.3
- * Added Async property. Now you can prepare data asynchronous before sending it.
- * It will prevent flash player from freezing while constructing request data.
- * You can specify the amount of bytes to write per iteration through BLOCK_SIZE static property.
- * Added events for asynchronous method.
- * Added dataFormat property for returned server data.
- * Removed 'Cache-Control' from headers and added custom requestHeaders array property.
- * Added getter for the URLLoader class used to send data.
- *
- * @author Eugene Zatepyakin
- * @version 1.3
- * @link http://blog.inspirit.ru/
- */
- public class MultipartURLLoader extends EventDispatcher
- {
- public static var BLOCK_SIZE:uint = 64 * 1024;
-
- private var _loader:URLLoader;
- private var _boundary:String;
- private var _variableNames:Array;
- private var _fileNames:Array;
- private var _variables:Dictionary;
- private var _files:Dictionary;
-
- private var _async:Boolean = false;
- private var _path:String;
- private var _data:ByteArray;
-
- private var _prepared:Boolean = false;
- private var asyncWriteTimeoutId:Number;
- private var asyncFilePointer:uint = 0;
- private var totalFilesSize:uint = 0;
- private var writtenBytes:uint = 0;
-
- public var requestHeaders:Array;
-
- public function MultipartURLLoader()
- {
- _fileNames = new Array();
- _files = new Dictionary();
- _variableNames = new Array();
- _variables = new Dictionary();
- _loader = new URLLoader();
- requestHeaders = new Array();
- }
-
- /**
- * Start uploading data to specified path
- *
- * @param path The server script path
- * @param async Set to true if you are uploading huge amount of data
- */
- public function load(path:String, async:Boolean = false):void
- {
- if (path == null || path == '') throw new IllegalOperationError('You cant load without specifing PATH');
-
- _path = path;
- _async = async;
-
- if (_async) {
- if(!_prepared){
- constructPostDataAsync();
- } else {
- doSend();
- }
- } else {
- _data = constructPostData();
- doSend();
- }
- }
-
- /**
- * Start uploading data after async prepare
- */
- public function startLoad():void
- {
- if ( _path == null || _path == '' || _async == false ) throw new IllegalOperationError('You can use this method only if loading asynchronous.');
- if ( !_prepared && _async ) throw new IllegalOperationError('You should prepare data before sending when using asynchronous.');
-
- doSend();
- }
-
- /**
- * Prepare data before sending (only if you use asynchronous)
- */
- public function prepareData():void
- {
- constructPostDataAsync();
- }
-
- /**
- * Stop loader action
- */
- public function close():void
- {
- try {
- _loader.close();
- } catch( e:Error ) { }
- }
-
- /**
- * Add string variable to loader
- * If you have already added variable with the same name it will be overwritten
- *
- * @param name Variable name
- * @param value Variable value
- */
- public function addVariable(name:String, value:Object = ''):void
- {
- if (_variableNames.indexOf(name) == -1) {
- _variableNames.push(name);
- }
- _variables[name] = value;
- _prepared = false;
- }
-
- /**
- * Add file part to loader
- * If you have already added file with the same fileName it will be overwritten
- *
- * @param fileContent File content encoded to ByteArray
- * @param fileName Name of the file
- * @param dataField Name of the field containg file data
- * @param contentType MIME type of the uploading file
- */
- public function addFile(fileContent:ByteArray, fileName:String, dataField:String = 'Filedata', contentType:String = 'application/octet-stream'):void
- {
- if (_fileNames.indexOf(fileName) == -1) {
- _fileNames.push(fileName);
- _files[fileName] = new FilePart(fileContent, fileName, dataField, contentType);
- totalFilesSize += fileContent.length;
- } else {
- var f:FilePart = _files[fileName] as FilePart;
- totalFilesSize -= f.fileContent.length;
- f.fileContent = fileContent;
- f.fileName = fileName;
- f.dataField = dataField;
- f.contentType = contentType;
- totalFilesSize += fileContent.length;
- }
-
- _prepared = false;
- }
-
- /**
- * Remove all variable parts
- */
- public function clearVariables():void
- {
- _variableNames = new Array();
- _variables = new Dictionary();
- _prepared = false;
- }
-
- /**
- * Remove all file parts
- */
- public function clearFiles():void
- {
- for each(var name:String in _fileNames)
- {
- (_files[name] as FilePart).dispose();
- }
- _fileNames = new Array();
- _files = new Dictionary();
- totalFilesSize = 0;
- _prepared = false;
- }
-
- /**
- * Dispose all class instance objects
- */
- public function dispose(): void
- {
- clearInterval(asyncWriteTimeoutId);
- removeListener();
- close();
-
- _loader = null;
- _boundary = null;
- _variableNames = null;
- _variables = null;
- _fileNames = null;
- _files = null;
- requestHeaders = null;
- _data = null;
- }
-
- /**
- * Generate random boundary
- * @return Random boundary
- */
- public function getBoundary():String
- {
- if (_boundary == null) {
- _boundary = '';
- for (var i:int = 0; i < 0x20; i++ ) {
- _boundary += String.fromCharCode( int( 97 + Math.random() * 25 ) );
- }
- }
- return _boundary;
- }
-
- public function get ASYNC():Boolean
- {
- return _async;
- }
-
- public function get PREPARED():Boolean
- {
- return _prepared;
- }
-
- public function get dataFormat():String
- {
- return _loader.dataFormat;
- }
-
- public function set dataFormat(format:String):void
- {
- if (format != URLLoaderDataFormat.BINARY && format != URLLoaderDataFormat.TEXT && format != URLLoaderDataFormat.VARIABLES) {
- throw new IllegalOperationError('Illegal URLLoader Data Format');
- }
- _loader.dataFormat = format;
- }
-
- public function get loader():URLLoader
- {
- return _loader;
- }
-
- private function doSend():void
- {
- var urlRequest:URLRequest = new URLRequest();
- urlRequest.url = _path;
- urlRequest.contentType = 'multipart/form-data; boundary=' + getBoundary();
- urlRequest.method = URLRequestMethod.POST;
- urlRequest.data = _data;
-
- if (requestHeaders.length && requestHeaders != null){
- urlRequest.requestHeaders = requestHeaders.concat();
- }
-
- addListener();
-
- _loader.load(urlRequest);
- }
-
- private function constructPostDataAsync():void
- {
- clearInterval(asyncWriteTimeoutId);
-
- _data = new ByteArray();
- _data.endian = Endian.BIG_ENDIAN;
-
- _data = constructVariablesPart(_data);
-
- asyncFilePointer = 0;
- writtenBytes = 0;
- _prepared = false;
- if (_fileNames.length) {
- nextAsyncLoop();
- } else {
- _data = closeDataObject(_data);
- _prepared = true;
- dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_COMPLETE) );
- }
- }
-
- private function constructPostData():ByteArray
- {
- var postData:ByteArray = new ByteArray();
- postData.endian = Endian.BIG_ENDIAN;
-
- postData = constructVariablesPart(postData);
- postData = constructFilesPart(postData);
-
- postData = closeDataObject(postData);
-
- return postData;
- }
-
- private function closeDataObject(postData:ByteArray):ByteArray
- {
- postData = BOUNDARY(postData);
- postData = DOUBLEDASH(postData);
- return postData;
- }
-
- private function constructVariablesPart(postData:ByteArray):ByteArray
- {
- var i:uint;
- var bytes:String;
-
- for each(var name:String in _variableNames)
- {
- postData = BOUNDARY(postData);
- postData = LINEBREAK(postData);
- bytes = 'Content-Disposition: form-data; name="' + name + '"';
- for ( i = 0; i < bytes.length; i++ ) {
- postData.writeByte( bytes.charCodeAt(i) );
- }
- postData = LINEBREAK(postData);
- postData = LINEBREAK(postData);
- postData.writeUTFBytes(_variables[name]);
- postData = LINEBREAK(postData);
- }
-
- return postData;
- }
-
- private function constructFilesPart(postData:ByteArray):ByteArray
- {
- var i:uint;
- var bytes:String;
-
- if(_fileNames.length){
- for each(var name:String in _fileNames)
- {
- postData = getFilePartHeader(postData, _files[name] as FilePart);
- postData = getFilePartData(postData, _files[name] as FilePart);
- postData = LINEBREAK(postData);
- }
- postData = closeFilePartsData(postData);
- }
-
- return postData;
- }
-
- private function closeFilePartsData(postData:ByteArray):ByteArray
- {
- var i:uint;
- var bytes:String;
-
- postData = LINEBREAK(postData);
- postData = BOUNDARY(postData);
- postData = LINEBREAK(postData);
- bytes = 'Content-Disposition: form-data; name="Upload"';
- for ( i = 0; i < bytes.length; i++ ) {
- postData.writeByte( bytes.charCodeAt(i) );
- }
- postData = LINEBREAK(postData);
- postData = LINEBREAK(postData);
- bytes = 'Submit Query';
- for ( i = 0; i < bytes.length; i++ ) {
- postData.writeByte( bytes.charCodeAt(i) );
- }
- postData = LINEBREAK(postData);
-
- return postData;
- }
-
- private function getFilePartHeader(postData:ByteArray, part:FilePart):ByteArray
- {
- var i:uint;
- var bytes:String;
-
- postData = BOUNDARY(postData);
- postData = LINEBREAK(postData);
- bytes = 'Content-Disposition: form-data; name="Filename"';
- for ( i = 0; i < bytes.length; i++ ) {
- postData.writeByte( bytes.charCodeAt(i) );
- }
- postData = LINEBREAK(postData);
- postData = LINEBREAK(postData);
- postData.writeUTFBytes(part.fileName);
- postData = LINEBREAK(postData);
-
- postData = BOUNDARY(postData);
- postData = LINEBREAK(postData);
- bytes = 'Content-Disposition: form-data; name="' + part.dataField + '"; filename="';
- for ( i = 0; i < bytes.length; i++ ) {
- postData.writeByte( bytes.charCodeAt(i) );
- }
- postData.writeUTFBytes(part.fileName);
- postData = QUOTATIONMARK(postData);
- postData = LINEBREAK(postData);
- bytes = 'Content-Type: ' + part.contentType;
- for ( i = 0; i < bytes.length; i++ ) {
- postData.writeByte( bytes.charCodeAt(i) );
- }
- postData = LINEBREAK(postData);
- postData = LINEBREAK(postData);
-
- return postData;
- }
-
- private function getFilePartData(postData:ByteArray, part:FilePart):ByteArray
- {
- postData.writeBytes(part.fileContent, 0, part.fileContent.length);
-
- return postData;
- }
-
- private function onProgress( event: ProgressEvent ): void
- {
- dispatchEvent( event );
- }
-
- private function onComplete( event: Event ): void
- {
- removeListener();
- dispatchEvent( event );
- }
-
- private function onIOError( event: IOErrorEvent ): void
- {
- removeListener();
- dispatchEvent( event );
- }
-
- private function onSecurityError( event: SecurityErrorEvent ): void
- {
- removeListener();
- dispatchEvent( event );
- }
-
- private function onHTTPStatus( event: HTTPStatusEvent ): void
- {
- dispatchEvent( event );
- }
-
- private function addListener(): void
- {
- _loader.addEventListener( Event.COMPLETE, onComplete, false, 0, false );
- _loader.addEventListener( ProgressEvent.PROGRESS, onProgress, false, 0, false );
- _loader.addEventListener( IOErrorEvent.IO_ERROR, onIOError, false, 0, false );
- _loader.addEventListener( HTTPStatusEvent.HTTP_STATUS, onHTTPStatus, false, 0, false );
- _loader.addEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError, false, 0, false );
- }
-
- private function removeListener(): void
- {
- _loader.removeEventListener( Event.COMPLETE, onComplete );
- _loader.removeEventListener( ProgressEvent.PROGRESS, onProgress );
- _loader.removeEventListener( IOErrorEvent.IO_ERROR, onIOError );
- _loader.removeEventListener( HTTPStatusEvent.HTTP_STATUS, onHTTPStatus );
- _loader.removeEventListener( SecurityErrorEvent.SECURITY_ERROR, onSecurityError );
- }
-
- private function BOUNDARY(p:ByteArray):ByteArray
- {
- var l:int = getBoundary().length;
- p = DOUBLEDASH(p);
- for (var i:int = 0; i < l; i++ ) {
- p.writeByte( _boundary.charCodeAt( i ) );
- }
- return p;
- }
-
- private function LINEBREAK(p:ByteArray):ByteArray
- {
- p.writeShort(0x0d0a);
- return p;
- }
-
- private function QUOTATIONMARK(p:ByteArray):ByteArray
- {
- p.writeByte(0x22);
- return p;
- }
-
- private function DOUBLEDASH(p:ByteArray):ByteArray
- {
- p.writeShort(0x2d2d);
- return p;
- }
-
- private function nextAsyncLoop():void
- {
- var fp:FilePart;
-
- if (asyncFilePointer < _fileNames.length) {
-
- fp = _files[_fileNames[asyncFilePointer]] as FilePart;
- _data = getFilePartHeader(_data, fp);
-
- asyncWriteTimeoutId = setTimeout(writeChunkLoop, 10, _data, fp.fileContent, 0);
-
- asyncFilePointer ++;
- } else {
- _data = closeFilePartsData(_data);
- _data = closeDataObject(_data);
-
- _prepared = true;
-
- dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_PROGRESS, totalFilesSize, totalFilesSize) );
- dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_COMPLETE) );
- }
- }
-
- private function writeChunkLoop(dest:ByteArray, data:ByteArray, p:uint = 0):void
- {
- var len:uint = Math.min(BLOCK_SIZE, data.length - p);
- dest.writeBytes(data, p, len);
-
- if (len < BLOCK_SIZE || p + len >= data.length) {
- // Finished writing file bytearray
- dest = LINEBREAK(dest);
- nextAsyncLoop();
- return;
- }
-
- p += len;
- writtenBytes += len;
- if ( writtenBytes % BLOCK_SIZE * 2 == 0 ) {
- dispatchEvent( new MultipartURLLoaderEvent(MultipartURLLoaderEvent.DATA_PREPARE_PROGRESS, writtenBytes, totalFilesSize) );
- }
-
- asyncWriteTimeoutId = setTimeout(writeChunkLoop, 10, dest, data, p);
- }
-
- }
-}
-
-internal class FilePart
-{
-
- public var fileContent:flash.utils.ByteArray;
- public var fileName:String;
- public var dataField:String;
- public var contentType:String;
-
- public function FilePart(fileContent:flash.utils.ByteArray, fileName:String, dataField:String = 'Filedata', contentType:String = 'application/octet-stream')
- {
- this.fileContent = fileContent;
- this.fileName = fileName;
- this.dataField = dataField;
- this.contentType = contentType;
- }
-
- public function dispose():void
- {
- fileContent = null;
- fileName = null;
- dataField = null;
- contentType = null;
- }
-}
\ No newline at end of file diff --git a/webcam/ru/inspirit/net/events/MultipartURLLoaderEvent.as b/webcam/ru/inspirit/net/events/MultipartURLLoaderEvent.as deleted file mode 100644 index 2b90855..0000000 --- a/webcam/ru/inspirit/net/events/MultipartURLLoaderEvent.as +++ /dev/null @@ -1,27 +0,0 @@ -package ru.inspirit.net.events
-{
- import flash.events.Event;
-
- /**
- * MultipartURLLoader Event for async data prepare tracking
- * @author Eugene Zatepyakin
- */
- public class MultipartURLLoaderEvent extends Event
- {
- public static const DATA_PREPARE_PROGRESS:String = 'dataPrepareProgress';
- public static const DATA_PREPARE_COMPLETE:String = 'dataPrepareComplete';
-
- public var bytesWritten:uint = 0;
- public var bytesTotal:uint = 0;
-
- public function MultipartURLLoaderEvent(type:String, w:uint = 0, t:uint = 0)
- {
- super(type);
-
- bytesTotal = t;
- bytesWritten = w;
- }
-
- }
-
-}
\ No newline at end of file |
