>p)!=(s&DM)>>p) {
- r[k++] = d|(s<<(DB-p));
- }
- while (i>=0) {
- if(p<8) {
- d = (a[i]&((1<>(p+=DB-8);
- } else {
- d = (a[i]>>(p-=8))&0xff;
- if (p<=0) {
- p += DB;
- --i;
- }
- }
- if ((d&0x80)!=0) d|=-256;
- if (k==0 && (s&0x80)!=(d&0x80)) ++k;
- if (k>0 || d!=s) r[k++] = d;
- }
- }
- return r;
- }
-
- public function equals(a:BigInteger):Boolean {
- return compareTo(a)==0;
- }
- public function min(a:BigInteger):BigInteger {
- return (compareTo(a)<0)?this:a;
- }
- public function max(a:BigInteger):BigInteger {
- return (compareTo(a)>0)?this:a;
- }
-
- /**
- *
- * @param a a BigInteger to perform the operation with
- * @param op a Function implementing the operation
- * @param r a BigInteger to store the result of the operation
- *
- */
- protected function bitwiseTo(a:BigInteger, op:Function, r:BigInteger):void {
- var i:int;
- var f:int;
- var m:int = Math.min(a.t, t);
- for (i=0; i>= 16; r += 16; }
- if ((x&0xff) == 0) { x>>= 8; r += 8; }
- if ((x&0xf) == 0) { x>>= 4; r += 4; }
- if ((x&0x3) == 0) { x>>= 2; r += 2; }
- if ((x&0x1) == 0) ++r;
- return r;
- }
-
- /**
- *
- * @return index of lowest 1-bit (or -1 if none)
- *
- */
- public function getLowestSetBit():int {
- for (var i:int=0;i=t) {
- return s!=0;
- }
- return ((a[j]&(1<<(n%DB)))!=0);
- }
-
- /**
- *
- * @param n
- * @param op
- * @return this op (1<>=DB;
- }
- if (a.t < t) {
- c += a.s;
- while (i>= DB;
- }
- c += s;
- } else {
- c += s;
- while (i>= DB;
- }
- c += a.s;
- }
- r.s = (c<0)?-1:0;
- if (c>0) {
- r.a[i++] = c;
- } else if (c<-1) {
- r.a[i++] = DV+c;
- }
- r.t = i;
- r.clamp();
- }
-
- /**
- *
- * @param a
- * @return this + a
- *
- */
- public function add(a:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- addTo(a,r);
- return r;
- }
-
- /**
- *
- * @param a
- * @return this - a
- *
- */
- public function subtract(a:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- subTo(a,r);
- return r;
- }
-
- /**
- *
- * @param a
- * @return this * a
- *
- */
- public function multiply(a:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- multiplyTo(a,r);
- return r;
- }
-
- /**
- *
- * @param a
- * @return this / a
- *
- */
- public function divide(a:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- divRemTo(a, r, null);
- return r;
- }
-
- public function remainder(a:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- divRemTo(a, null, r);
- return r;
- }
-
- /**
- *
- * @param a
- * @return [this/a, this%a]
- *
- */
- public function divideAndRemainder(a:BigInteger):Array {
- var q:BigInteger = new BigInteger;
- var r:BigInteger = new BigInteger;
- divRemTo(a, q, r);
- return [q,r];
- }
-
- /**
- *
- * this *= n, this >=0, 1 < n < DV
- *
- * @param n
- *
- */
- bi_internal function dMultiply(n:int):void {
- a[t] = am(0, n-1, this, 0, 0, t);
- ++t;
- clamp();
- }
-
- /**
- *
- * this += n << w words, this >= 0
- *
- * @param n
- * @param w
- *
- */
- bi_internal function dAddOffset(n:int, w:int):void {
- while (t<=w) {
- a[t++] = 0;
- }
- a[w] += n;
- while (a[w] >= DV) {
- a[w] -= DV;
- if (++w >= t) {
- a[t++] = 0;
- }
- ++a[w];
- }
- }
-
- /**
- *
- * @param e
- * @return this^e
- *
- */
- public function pow(e:int):BigInteger {
- return exp(e, new NullReduction);
- }
-
- /**
- *
- * @param a
- * @param n
- * @param r = lower n words of "this * a", a.t <= n
- *
- */
- bi_internal function multiplyLowerTo(a:BigInteger, n:int, r:BigInteger):void {
- var i:int = Math.min(t+a.t, n);
- r.s = 0; // assumes a, this >= 0
- r.t = i;
- while (i>0) {
- r.a[--i]=0;
- }
- var j:int;
- for (j=r.t-t;i 0
- *
- */
- bi_internal function multiplyUpperTo(a:BigInteger, n:int, r:BigInteger):void {
- --n;
- var i:int = r.t = t+a.t-n;
- r.s = 0; // assumes a,this >= 0
- while (--i>=0) {
- r.a[i] = 0;
- }
- for (i=Math.max(n-t,0);i 1) {
- var g2:BigInteger = new BigInteger;
- z.sqrTo(g[1], g2);
- while (n<=km) {
- g[n] = new BigInteger;
- z.mulTo(g2, g[n-2], g[n]);
- n += 2;
- }
- }
-
- var j:int = e.t-1;
- var w:int;
- var is1:Boolean = true;
- var r2:BigInteger = new BigInteger;
- var t:BigInteger;
- i = nbits(e.a[j])-1;
- while (j>=0) {
- if (i>=k1) {
- w = (e.a[j]>>(i-k1))&km;
- } else {
- w = (e.a[j]&((1<<(i+1))-1))<<(k1-i);
- if (j>0) {
- w |= e.a[j-1]>>(DB+i-k1);
- }
- }
- n = k;
- while ((w&1)==0) {
- w >>= 1;
- --n;
- }
- if ((i -= n) <0) {
- i += DB;
- --j;
- }
- if (is1) { // ret == 1, don't bother squaring or multiplying it
- g[w].copyTo(r);
- is1 = false;
- } else {
- while (n>1) {
- z.sqrTo(r, r2);
- z.sqrTo(r2, r);
- n -= 2;
- }
- if (n>0) {
- z.sqrTo(r, r2);
- } else {
- t = r;
- r = r2;
- r2 = t;
- }
- z.mulTo(r2, g[w], r);
- }
- while (j>=0 && (e.a[j]&(1<0) {
- x.rShiftTo(g, x);
- y.rShiftTo(g, y);
- }
- while (x.sigNum()>0) {
- if ((i = x.getLowestSetBit()) >0) {
- x.rShiftTo(i, x);
- }
- if ((i = y.getLowestSetBit()) >0) {
- y.rShiftTo(i, y);
- }
- if (x.compareTo(y) >= 0) {
- x.subTo(y, x);
- x.rShiftTo(1, x);
- } else {
- y.subTo(x, y);
- y.rShiftTo(1, y);
- }
- }
- if (g>0) {
- y.lShiftTo(g, y);
- }
- return y;
- }
-
- /**
- *
- * @param n
- * @return this % n, n < 2^DB
- *
- */
- protected function modInt(n:int):int {
- if (n<=0) return 0;
- var d:int = DV%n;
- var r:int = (s<0)?n-1:0;
- if (t>0) {
- if (d==0) {
- r = a[0]%n;
- } else {
- for (var i:int=t-1;i>=0;--i) {
- r = (d*r+a[i])%n;
- }
- }
- }
- return r;
- }
-
- /**
- *
- * @param m
- * @return 1/this %m (HAC 14.61)
- *
- */
- public function modInverse(m:BigInteger):BigInteger {
- var ac:Boolean = m.isEven();
- if ((isEven()&&ac) || m.sigNum()==0) {
- return BigInteger.ZERO;
- }
- var u:BigInteger = m.clone();
- var v:BigInteger = clone();
- var a:BigInteger = nbv(1);
- var b:BigInteger = nbv(0);
- var c:BigInteger = nbv(0);
- var d:BigInteger = nbv(1);
- while (u.sigNum()!=0) {
- while (u.isEven()) {
- u.rShiftTo(1,u);
- if (ac) {
- if (!a.isEven() || !b.isEven()) {
- a.addTo(this,a);
- b.subTo(m,b);
- }
- a.rShiftTo(1,a);
- } else if (!b.isEven()) {
- b.subTo(m,b);
- }
- b.rShiftTo(1,b);
- }
- while (v.isEven()) {
- v.rShiftTo(1,v);
- if (ac) {
- if (!c.isEven() || !d.isEven()) {
- c.addTo(this,c);
- d.subTo(m,d);
- }
- c.rShiftTo(1,c);
- } else if (!d.isEven()) {
- d.subTo(m,d);
- }
- d.rShiftTo(1,d);
- }
- if (u.compareTo(v)>=0) {
- u.subTo(v,u);
- if (ac) {
- a.subTo(c,a);
- }
- b.subTo(d,b);
- } else {
- v.subTo(u,v);
- if (ac) {
- c.subTo(a,c);
- }
- d.subTo(b,d);
- }
- }
- if (v.compareTo(BigInteger.ONE) != 0) {
- return BigInteger.ZERO;
- }
- if (d.compareTo(m) >= 0) {
- return d.subtract(m);
- }
- if (d.sigNum()<0) {
- d.addTo(m,d);
- } else {
- return d;
- }
- if (d.sigNum()<0) {
- return d.add(m);
- } else {
- return d;
- }
- }
-
- /**
- *
- * @param t
- * @return primality with certainty >= 1-.5^t
- *
- */
- public function isProbablePrime(t:int):Boolean {
- var i:int;
- var x:BigInteger = abs();
- if (x.t == 1 && x.a[0]<=lowprimes[lowprimes.length-1]) {
- for (i=0;i>1;
- if (t>lowprimes.length) {
- t = lowprimes.length;
- }
- var a:BigInteger = new BigInteger;
- for (var i:int=0;ibits) subTo(BigInteger.ONE.shiftLeft(bits-1),this);
- }
- }
-
- }
-}
diff --git a/include/as3crypto_patched/src/com/hurlant/math/ClassicReduction.as b/include/as3crypto_patched/src/com/hurlant/math/ClassicReduction.as
deleted file mode 100755
index ea9f17cf..00000000
--- a/include/as3crypto_patched/src/com/hurlant/math/ClassicReduction.as
+++ /dev/null
@@ -1,35 +0,0 @@
-package com.hurlant.math
-{
- use namespace bi_internal;
-
- /**
- * Modular reduction using "classic" algorithm
- */
- internal class ClassicReduction implements IReduction
- {
- private var m:BigInteger;
- public function ClassicReduction(m:BigInteger) {
- this.m = m;
- }
- public function convert(x:BigInteger):BigInteger {
- if (x.s<0 || x.compareTo(m)>=0) {
- return x.mod(m);
- }
- return x;
- }
- public function revert(x:BigInteger):BigInteger {
- return x;
- }
- public function reduce(x:BigInteger):void {
- x.divRemTo(m, null,x);
- }
- public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
- x.multiplyTo(y,r);
- reduce(r);
- }
- public function sqrTo(x:BigInteger, r:BigInteger):void {
- x.squareTo(r);
- reduce(r);
- }
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/IReduction.as b/include/as3crypto_patched/src/com/hurlant/math/IReduction.as
deleted file mode 100755
index 210a0543..00000000
--- a/include/as3crypto_patched/src/com/hurlant/math/IReduction.as
+++ /dev/null
@@ -1,11 +0,0 @@
-package com.hurlant.math
-{
- internal interface IReduction
- {
- function convert(x:BigInteger):BigInteger;
- function revert(x:BigInteger):BigInteger;
- function reduce(x:BigInteger):void;
- function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void;
- function sqrTo(x:BigInteger, r:BigInteger):void;
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/MontgomeryReduction.as b/include/as3crypto_patched/src/com/hurlant/math/MontgomeryReduction.as
deleted file mode 100755
index 47a16d6f..00000000
--- a/include/as3crypto_patched/src/com/hurlant/math/MontgomeryReduction.as
+++ /dev/null
@@ -1,85 +0,0 @@
-package com.hurlant.math
-{
- use namespace bi_internal;
- /**
- * Montgomery reduction
- */
- internal class MontgomeryReduction implements IReduction
- {
- private var m:BigInteger;
- private var mp:int;
- private var mpl:int;
- private var mph:int;
- private var um:int;
- private var mt2:int;
- public function MontgomeryReduction(m:BigInteger) {
- this.m = m;
- mp = m.invDigit();
- mpl = mp & 0x7fff;
- mph = mp>>15;
- um = (1<<(BigInteger.DB-15))-1;
- mt2 = 2*m.t;
- }
- /**
- * xR mod m
- */
- public function convert(x:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- x.abs().dlShiftTo(m.t, r);
- r.divRemTo(m, null, r);
- if (x.s<0 && r.compareTo(BigInteger.ZERO)>0) {
- m.subTo(r,r);
- }
- return r;
- }
- /**
- * x/R mod m
- */
- public function revert(x:BigInteger):BigInteger {
- var r:BigInteger = new BigInteger;
- x.copyTo(r);
- reduce(r);
- return r;
- }
- /**
- * x = x/R mod m (HAC 14.32)
- */
- public function reduce(x:BigInteger):void {
- while (x.t<=mt2) { // pad x so am has enough room later
- x.a[x.t++] = 0;
- }
- for (var i:int=0; i>15)*mpl)&um)<<15))&BigInteger.DM;
- // use am to combine the multiply-shift-add into one call
- j = i+m.t;
- x.a[j] += m.am(0, u0, x, i, 0, m.t);
- // propagate carry
- while (x.a[j]>=BigInteger.DV) {
- x.a[j] -= BigInteger.DV;
- x.a[++j]++;
- }
- }
- x.clamp();
- x.drShiftTo(m.t, x);
- if (x.compareTo(m)>=0) {
- x.subTo(m,x);
- }
- }
- /**
- * r = "x^2/R mod m"; x != r
- */
- public function sqrTo(x:BigInteger, r:BigInteger):void {
- x.squareTo(r);
- reduce(r);
- }
- /**
- * r = "xy/R mod m"; x,y != r
- */
- public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void {
- x.multiplyTo(y,r);
- reduce(r);
- }
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/NullReduction.as b/include/as3crypto_patched/src/com/hurlant/math/NullReduction.as
deleted file mode 100755
index 5b55832e..00000000
--- a/include/as3crypto_patched/src/com/hurlant/math/NullReduction.as
+++ /dev/null
@@ -1,34 +0,0 @@
-package com.hurlant.math
-{
- use namespace bi_internal;
- /**
- * A "null" reducer
- */
- public class NullReduction implements IReduction
- {
- public function revert(x:BigInteger):BigInteger
- {
- return x;
- }
-
- public function mulTo(x:BigInteger, y:BigInteger, r:BigInteger):void
- {
- x.multiplyTo(y,r);
- }
-
- public function sqrTo(x:BigInteger, r:BigInteger):void
- {
- x.squareTo(r);
- }
-
- public function convert(x:BigInteger):BigInteger
- {
- return x;
- }
-
- public function reduce(x:BigInteger):void
- {
- }
-
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/math/bi_internal.as b/include/as3crypto_patched/src/com/hurlant/math/bi_internal.as
deleted file mode 100755
index dc86aad7..00000000
--- a/include/as3crypto_patched/src/com/hurlant/math/bi_internal.as
+++ /dev/null
@@ -1,11 +0,0 @@
-/**
- * bi_internal
- *
- * A namespace. w00t.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.math {
- public namespace bi_internal = "http://crypto.hurlant.com/BigInteger";
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/ArrayUtil.as b/include/as3crypto_patched/src/com/hurlant/util/ArrayUtil.as
deleted file mode 100755
index b02b8d52..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/ArrayUtil.as
+++ /dev/null
@@ -1,25 +0,0 @@
-/**
- * ArrayUtil
- *
- * A class that allows to compare two ByteArrays.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util {
- import flash.utils.ByteArray;
-
-
- public class ArrayUtil {
-
- public static function equals(a1:ByteArray, a2:ByteArray):Boolean {
- if (a1.length != a2.length) return false;
- var l:int = a1.length;
- for (var i:int=0;i
- * LastModified: Oct 26, 2009
- * This library is free. You can redistribute it and/or modify it.
- */
-package com.hurlant.util{
- import flash.utils.ByteArray;
-
- public class Base64
- {
- private static const _encodeChars : Vector. = InitEncoreChar();
- private static const _decodeChars : Vector. = InitDecodeChar();
-
- public static function encodeByteArray(data : ByteArray) : String
- {
- var out : ByteArray = new ByteArray();
- //Presetting the length keep the memory smaller and optimize speed since there is no "grow" needed
- out.length = (2 + data.length - ((data.length + 2) % 3)) * 4 / 3; //Preset length //1.6 to 1.5 ms
- var i : int = 0;
- var r : int = data.length % 3;
- var len : int = data.length - r;
- var c : int; //read (3) character AND write (4) characters
-
- while (i < len)
- {
- //Read 3 Characters (8bit * 3 = 24 bits)
- c = data[i++] << 16 | data[i++] << 8 | data[i++];
-
- //Cannot optimize this to read int because of the positioning overhead. (as3 bytearray seek is slow)
- //Convert to 4 Characters (6 bit * 4 = 24 bits)
- c = (_encodeChars[c >>> 18] << 24) | (_encodeChars[c >>> 12 & 0x3f] << 16) | (_encodeChars[c >>> 6 & 0x3f] << 8) | _encodeChars[c & 0x3f];
-
- //Optimization: On older and slower computer, do one write Int instead of 4 write byte: 1.5 to 0.71 ms
- out.writeInt(c);
- /*
- out.writeByte(_encodeChars[c >> 18] );
- out.writeByte(_encodeChars[c >> 12 & 0x3f]);
- out.writeByte(_encodeChars[c >> 6 & 0x3f]);
- out.writeByte(_encodeChars[c & 0x3f]);
- */
- }
-
- if (r == 1) //Need two "=" padding
- {
- //Read one char, write two chars, write padding
- c = data[i];
- c = (_encodeChars[c >>> 2] << 24) | (_encodeChars[(c & 0x03) << 4] << 16) | 61 << 8 | 61;
- out.writeInt(c);
- }
- else if (r == 2) //Need one "=" padding
- {
- c = data[i++] << 8 | data[i];
- c = (_encodeChars[c >>> 10] << 24) | (_encodeChars[c >>> 4 & 0x3f] << 16) | (_encodeChars[(c & 0x0f) << 2] << 8) | 61;
- out.writeInt(c);
- }
-
- out.position = 0;
- return out.readUTFBytes(out.length);
- }
-
-
- public static function decodeToByteArray(str : String) : ByteArray
- {
- var c1 : int;
- var c2 : int;
- var c3 : int;
- var c4 : int;
- var i : int;
- var len : int;
- var out : ByteArray;
- len = str.length;
- i = 0;
- out = new ByteArray();
- var byteString : ByteArray = new ByteArray();
- byteString.writeUTFBytes(str);
- while (i < len)
- {
- //c1
- do
- {
- c1 = _decodeChars[byteString[i++]];
- } while (i < len && c1 == -1);
- if (c1 == -1) break;
-
- //c2
- do
- {
- c2 = _decodeChars[byteString[i++]];
- } while (i < len && c2 == -1);
- if (c2 == -1) break;
-
- out.writeByte((c1 << 2) | ((c2 & 0x30) >> 4));
-
- //c3
- do
- {
- c3 = byteString[i++];
- if (c3 == 61) return out;
-
- c3 = _decodeChars[c3];
- } while (i < len && c3 == -1);
- if (c3 == -1) break;
-
- out.writeByte(((c2 & 0x0f) << 4) | ((c3 & 0x3c) >> 2));
-
- //c4
- do {
- c4 = byteString[i++];
- if (c4 == 61) return out;
-
- c4 = _decodeChars[c4];
- } while (i < len && c4 == -1);
- if (c4 == -1) break;
-
- out.writeByte(((c3 & 0x03) << 6) | c4);
-
- }
-
- out.position = 0;
-
- return out;
- }
-
- public static function encode(data : String) : String {
- // Convert string to ByteArray
- var bytes : ByteArray = new ByteArray();
- bytes.writeUTFBytes(data);
-
- // Return encoded ByteArray
- return encodeByteArray(bytes);
- }
-
- public static function decode(data : String) : String {
- // Decode data to ByteArray
- var bytes : ByteArray = decodeToByteArray(data);
-
- // Convert to string and return
- return bytes.readUTFBytes(bytes.length);
- }
-
- public static function InitEncoreChar() : Vector.
- {
- var encodeChars : Vector. = new Vector.();
- // We could push the number directly, but i think it's nice to see the characters (with no overhead on encode/decode)
- var chars : String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- for (var i : int = 0; i < 64; i++)
- {
- encodeChars.push(chars.charCodeAt(i));
- }
- /*
- encodeChars.push(
- 65, 66, 67, 68, 69, 70, 71, 72,
- 73, 74, 75, 76, 77, 78, 79, 80,
- 81, 82, 83, 84, 85, 86, 87, 88,
- 89, 90, 97, 98, 99, 100, 101, 102,
- 103, 104, 105, 106, 107, 108, 109, 110,
- 111, 112, 113, 114, 115, 116, 117, 118,
- 119, 120, 121, 122, 48, 49, 50, 51,
- 52, 53, 54, 55, 56, 57, 43, 47);
- */
- return encodeChars;
- }
-
- public static function InitDecodeChar() : Vector.
- {
- var decodeChars : Vector. = new Vector.();
-
- decodeChars.push(-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 62, -1, -1, -1, 63,
- 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, -1, -1, -1, -1, -1, -1,
- -1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14,
- 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, -1, -1, -1, -1, -1,
- -1, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40,
- 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, -1, -1, -1, -1, -1
- - 1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
- -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1);
- return decodeChars;
- }
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/Hex.as b/include/as3crypto_patched/src/com/hurlant/util/Hex.as
deleted file mode 100755
index 98d887b9..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/Hex.as
+++ /dev/null
@@ -1,66 +0,0 @@
-/**
- * Hex
- *
- * Utility class to convert Hex strings to ByteArray or String types.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util
-{
- import flash.utils.ByteArray;
-
- public class Hex
- {
- /**
- * Support straight hex, or colon-laced hex.
- * (that means 23:03:0e:f0, but *NOT* 23:3:e:f0)
- * Whitespace characters are ignored.
- */
- public static function toArray(hex:String):ByteArray {
- hex = hex.replace(/\s|:/gm,'');
- var a:ByteArray = new ByteArray;
- if (hex.length&1==1) hex="0"+hex;
- for (var i:uint=0;i=0x80) {
- // long form of length
- var count:int = len & 0x7f;
- len = 0;
- while (count>0) {
- len = (len<<8) | der.readUnsignedByte();
- count--;
- }
- }
- // data
- var b:ByteArray
- switch (type) {
- case 0x00: // WHAT IS THIS THINGY? (seen as 0xa0)
- // (note to self: read a spec someday.)
- // for now, treat as a sequence.
- case 0x10: // SEQUENCE/SEQUENCE OF. whatever
- // treat as an array
- var p:int = der.position;
- var o:Sequence = new Sequence(type, len);
- var arrayStruct:Array = structure as Array;
- if (arrayStruct!=null) {
- // copy the array, as we destroy it later.
- arrayStruct = arrayStruct.concat();
- }
- while (der.position < p+len) {
- var tmpStruct:Object = null
- if (arrayStruct!=null) {
- tmpStruct = arrayStruct.shift();
- }
- if (tmpStruct!=null) {
- while (tmpStruct && tmpStruct.optional) {
- // make sure we have something that looks reasonable. XXX I'm winging it here..
- var wantConstructed:Boolean = (tmpStruct.value is Array);
- var isConstructed:Boolean = isConstructedType(der);
- if (wantConstructed!=isConstructed) {
- // not found. put default stuff, or null
- o.push(tmpStruct.defaultValue);
- o[tmpStruct.name] = tmpStruct.defaultValue;
- // try the next thing
- tmpStruct = arrayStruct.shift();
- } else {
- break;
- }
- }
- }
- if (tmpStruct!=null) {
- var name:String = tmpStruct.name;
- var value:* = tmpStruct.value;
- if (tmpStruct.extract) {
- // we need to keep a binary copy of this element
- var size:int = getLengthOfNextElement(der);
- var ba:ByteArray = new ByteArray;
- ba.writeBytes(der, der.position, size);
- o[name+"_bin"] = ba;
- }
- var obj:IAsn1Type = DER.parse(der, value);
- o.push(obj);
- o[name] = obj;
- } else {
- o.push(DER.parse(der));
- }
- }
- return o;
- case 0x11: // SET/SET OF
- p = der.position;
- var s:Set = new Set(type, len);
- while (der.position < p+len) {
- s.push(DER.parse(der));
- }
- return s;
- case 0x02: // INTEGER
- // put in a BigInteger
- b = new ByteArray;
- der.readBytes(b,0,len);
- b.position=0;
- return new Integer(type, len, b);
- case 0x06: // OBJECT IDENTIFIER:
- b = new ByteArray;
- der.readBytes(b,0,len);
- b.position=0;
- return new ObjectIdentifier(type, len, b);
- default:
- trace("I DONT KNOW HOW TO HANDLE DER stuff of TYPE "+type);
- // fall through
- case 0x03: // BIT STRING
- if (der[der.position]==0) {
- //trace("Horrible Bit String pre-padding removal hack."); // I wish I had the patience to find a spec for this.
- der.position++;
- len--;
- }
- case 0x04: // OCTET STRING
- // stuff in a ByteArray for now.
- var bs:ByteString = new ByteString(type, len);
- der.readBytes(bs,0,len);
- return bs;
- case 0x05: // NULL
- // if len!=0, something's horribly wrong.
- // should I check?
- return null;
- case 0x13: // PrintableString
- var ps:PrintableString = new PrintableString(type, len);
- ps.setString(der.readMultiByte(len, "US-ASCII"));
- return ps;
- case 0x22: // XXX look up what this is. openssl uses this to store my email.
- case 0x14: // T61String - an horrible format we don't even pretend to support correctly
- ps = new PrintableString(type, len);
- ps.setString(der.readMultiByte(len, "latin1"));
- return ps;
- case 0x17: // UTCTime
- var ut:UTCTime = new UTCTime(type, len);
- ut.setUTCTime(der.readMultiByte(len, "US-ASCII"));
- return ut;
- }
- }
-
- private static function getLengthOfNextElement(b:ByteArray):int {
- var p:uint = b.position;
- // length
- b.position++;
- var len:int = b.readUnsignedByte();
- if (len>=0x80) {
- // long form of length
- var count:int = len & 0x7f;
- len = 0;
- while (count>0) {
- len = (len<<8) | b.readUnsignedByte();
- count--;
- }
- }
- len += b.position-p; // length of length
- b.position = p;
- return len;
- }
- private static function isConstructedType(b:ByteArray):Boolean {
- var type:int = b[b.position];
- return (type&0x20)!=0;
- }
-
- public static function wrapDER(type:int, data:ByteArray):ByteArray {
- var d:ByteArray = new ByteArray;
- d.writeByte(type);
- var len:int = data.length;
- if (len<128) {
- d.writeByte(len);
- } else if (len<256) {
- d.writeByte(1 | 0x80);
- d.writeByte(len);
- } else if (len<65536) {
- d.writeByte(2 | 0x80);
- d.writeByte(len>>8);
- d.writeByte(len);
- } else if (len<65536*256) {
- d.writeByte(3 | 0x80);
- d.writeByte(len>>16);
- d.writeByte(len>>8);
- d.writeByte(len);
- } else {
- d.writeByte(4 | 0x80);
- d.writeByte(len>>24);
- d.writeByte(len>>16);
- d.writeByte(len>>8);
- d.writeByte(len);
- }
- d.writeBytes(data);
- d.position=0;
- return d;
-
- }
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/IAsn1Type.as b/include/as3crypto_patched/src/com/hurlant/util/der/IAsn1Type.as
deleted file mode 100755
index f4f2112a..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/der/IAsn1Type.as
+++ /dev/null
@@ -1,21 +0,0 @@
-/**
- * IAsn1Type
- *
- * An interface for Asn-1 types.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util.der
-{
- import flash.utils.ByteArray;
-
- public interface IAsn1Type
- {
- function getType():uint;
- function getLength():uint;
-
- function toDER():ByteArray;
-
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/Integer.as b/include/as3crypto_patched/src/com/hurlant/util/der/Integer.as
deleted file mode 100755
index e2f045c9..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/der/Integer.as
+++ /dev/null
@@ -1,44 +0,0 @@
-/**
- * Integer
- *
- * An ASN1 type for an Integer, represented with a BigInteger
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util.der
-{
- import com.hurlant.math.BigInteger;
- import flash.utils.ByteArray;
-
- public class Integer extends BigInteger implements IAsn1Type
- {
- private var type:uint;
- private var len:uint;
-
- public function Integer(type:uint, length:uint, b:ByteArray) {
- this.type = type;
- this.len = length;
- super(b);
- }
-
- public function getLength():uint
- {
- return len;
- }
-
- public function getType():uint
- {
- return type;
- }
-
- override public function toString(radix:Number=0):String {
- return DER.indent+"Integer["+type+"]["+len+"]["+super.toString(16)+"]";
- }
-
- public function toDER():ByteArray {
- return null;
- }
-
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/OID.as b/include/as3crypto_patched/src/com/hurlant/util/der/OID.as
deleted file mode 100755
index 4d43d955..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/der/OID.as
+++ /dev/null
@@ -1,35 +0,0 @@
-/**
- * OID
- *
- * A list of various ObjectIdentifiers.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util.der
-{
- public class OID
- {
-
- public static const RSA_ENCRYPTION:String = "1.2.840.113549.1.1.1";
- public static const MD2_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.2";
- public static const MD5_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.4";
- public static const SHA1_WITH_RSA_ENCRYPTION:String = "1.2.840.113549.1.1.5";
- public static const MD2_ALGORITHM:String = "1.2.840.113549.2.2";
- public static const MD5_ALGORITHM:String = "1.2.840.113549.2.5";
- public static const DSA:String = "1.2.840.10040.4.1";
- public static const DSA_WITH_SHA1:String = "1.2.840.10040.4.3";
- public static const DH_PUBLIC_NUMBER:String = "1.2.840.10046.2.1";
- public static const SHA1_ALGORITHM:String = "1.3.14.3.2.26";
-
- public static const COMMON_NAME:String = "2.5.4.3";
- public static const SURNAME:String = "2.5.4.4";
- public static const COUNTRY_NAME:String = "2.5.4.6";
- public static const LOCALITY_NAME:String = "2.5.4.7";
- public static const STATE_NAME:String = "2.5.4.8";
- public static const ORGANIZATION_NAME:String = "2.5.4.10";
- public static const ORG_UNIT_NAME:String = "2.5.4.11";
- public static const TITLE:String = "2.5.4.12";
-
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/ObjectIdentifier.as b/include/as3crypto_patched/src/com/hurlant/util/der/ObjectIdentifier.as
deleted file mode 100755
index 932acd7b..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/der/ObjectIdentifier.as
+++ /dev/null
@@ -1,112 +0,0 @@
-/**
- * ObjectIdentifier
- *
- * An ASN1 type for an ObjectIdentifier
- * We store the oid in an Array.
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util.der
-{
- import flash.utils.ByteArray;
-
- public class ObjectIdentifier implements IAsn1Type
- {
- private var type:uint;
- private var len:uint;
- private var oid:Array;
-
- public function ObjectIdentifier(type:uint, length:uint, b:*) {
- this.type = type;
- this.len = length;
- if (b is ByteArray) {
- parse(b as ByteArray);
- } else if (b is String) {
- generate(b as String);
- } else {
- throw new Error("Invalid call to new ObjectIdentifier");
- }
- }
-
- private function generate(s:String):void {
- oid = s.split(".");
- }
-
- private function parse(b:ByteArray):void {
- // parse stuff
- // first byte = 40*value1 + value2
- var o:uint = b.readUnsignedByte();
- var a:Array = []
- a.push(uint(o/40));
- a.push(uint(o%40));
- var v:uint = 0;
- while (b.bytesAvailable>0) {
- o = b.readUnsignedByte();
- var last:Boolean = (o&0x80)==0;
- o &= 0x7f;
- v = v*128 + o;
- if (last) {
- a.push(v);
- v = 0;
- }
- }
- oid = a;
- }
-
- public function getLength():uint
- {
- return len;
- }
-
- public function getType():uint
- {
- return type;
- }
-
- public function toDER():ByteArray {
- var tmp:Array = [];
- tmp[0] = oid[0]*40 + oid[1];
- for (var i:int=2;i>7)|0x80 );
- tmp.push( v&0x7f );
- } else if (v<128*128*128) {
- tmp.push( (v>>14)|0x80 );
- tmp.push( (v>>7)&0x7f | 0x80 );
- tmp.push( v&0x7f);
- } else if (v<128*128*128*128) {
- tmp.push( (v>>21)|0x80 );
- tmp.push( (v>>14) & 0x7f | 0x80 );
- tmp.push( (v>>7) & 0x7f | 0x80 );
- tmp.push( v & 0x7f );
- } else {
- throw new Error("OID element bigger than we thought. :(");
- }
- }
- len = tmp.length;
- if (type==0) {
- type = 6;
- }
- tmp.unshift(len); // assume length is small enough to fit here.
- tmp.unshift(type);
- var b:ByteArray = new ByteArray;
- for (i=0;i, null ]; ( apparently, that's an X-509 Algorithm Identifier.
- if (arr[0][0].toString()!=OID.RSA_ENCRYPTION) {
- return null;
- }
- // arr[1] is a ByteArray begging to be parsed as DER
- arr[1].position = 1; // there's a 0x00 byte up front. find out why later. like, read a spec.
- obj = DER.parse(arr[1]);
- if (obj is Array) {
- arr = obj as Array;
- // arr[0] = modulus
- // arr[1] = public expt.
- return new RSAKey(arr[0], arr[1]);
- } else {
- return null;
- }
- } else {
- // dunno
- return null;
- }
- }
-
- public static function readCertIntoArray(str:String):ByteArray {
- var tmp:ByteArray = extractBinary(CERTIFICATE_HEADER, CERTIFICATE_FOOTER, str);
- return tmp;
- }
-
- private static function extractBinary(header:String, footer:String, str:String):ByteArray {
- var i:int = str.indexOf(header);
- if (i==-1) return null;
- i += header.length;
- var j:int = str.indexOf(footer);
- if (j==-1) return null;
- var b64:String = str.substring(i, j);
- // remove whitesapces.
- b64 = b64.replace(/\s/mg, '');
- // decode
- return Base64.decodeToByteArray(b64);
- }
-
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/PrintableString.as b/include/as3crypto_patched/src/com/hurlant/util/der/PrintableString.as
deleted file mode 100755
index ed1775e2..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/der/PrintableString.as
+++ /dev/null
@@ -1,49 +0,0 @@
-/**
- * PrintableString
- *
- * An ASN1 type for a PrintableString, held within a String
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util.der
-{
- import flash.utils.ByteArray;
-
- public class PrintableString implements IAsn1Type
- {
- protected var type:uint;
- protected var len:uint;
- protected var str:String;
-
- public function PrintableString(type:uint, length:uint) {
- this.type = type;
- this.len = length;
- }
-
- public function getLength():uint
- {
- return len;
- }
-
- public function getType():uint
- {
- return type;
- }
-
- public function setString(s:String):void {
- str = s;
- }
- public function getString():String {
- return str;
- }
-
- public function toString():String {
- return DER.indent+str;
- }
-
- public function toDER():ByteArray {
- return null; // XXX not implemented
- }
- }
-}
\ No newline at end of file
diff --git a/include/as3crypto_patched/src/com/hurlant/util/der/Sequence.as b/include/as3crypto_patched/src/com/hurlant/util/der/Sequence.as
deleted file mode 100755
index c3524142..00000000
--- a/include/as3crypto_patched/src/com/hurlant/util/der/Sequence.as
+++ /dev/null
@@ -1,90 +0,0 @@
-/**
- * Sequence
- *
- * An ASN1 type for a Sequence, implemented as an Array
- * Copyright (c) 2007 Henri Torgemane
- *
- * See LICENSE.txt for full license information.
- */
-package com.hurlant.util.der
-{
- import flash.utils.ByteArray;
-
- public dynamic class Sequence extends Array implements IAsn1Type
- {
- protected var type:uint;
- protected var len:uint;
-
- public function Sequence(type:uint = 0x30, length:uint = 0x00) {
- this.type = type;
- this.len = length;
- }
-
- public function getLength():uint
- {
- return len;
- }
-
- public function getType():uint
- {
- return type;
- }
-
- public function toDER():ByteArray {
- var tmp:ByteArray = new ByteArray;
- for (var i:int=0;i
-
-
- com.Test
- Test
- 1.0
- Test
- Test
- (c) 2007
-
- bin/Test.swf
- Test
- standard
- false
- true
- true
- true
- true
- 1024
- 768
- 100
- 50
- 300 300
- 800 800
-
- Test
- Test
-
-
-
- false
- false
-
\ No newline at end of file
diff --git a/include/as3crypto_patched/test/Test.mxml b/include/as3crypto_patched/test/Test.mxml
deleted file mode 100644
index 0121fcee..00000000
--- a/include/as3crypto_patched/test/Test.mxml
+++ /dev/null
@@ -1,35 +0,0 @@
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/include/as3crypto_patched/test/suite/AllTests.as b/include/as3crypto_patched/test/suite/AllTests.as
deleted file mode 100644
index a7ac7d5f..00000000
--- a/include/as3crypto_patched/test/suite/AllTests.as
+++ /dev/null
@@ -1,16 +0,0 @@
-package suite {
-
- import flexunit.framework.TestSuite;
-
- public class AllTests extends TestSuite {
-
- public function AllTests() {
- super();
- // Add tests here
- // For examples, see: http://code.google.com/p/as3flexunitlib/wiki/Resources
- //addTest(SomeTest.suite());
- }
-
- }
-
-}
\ No newline at end of file
diff --git a/include/vnc.js b/include/vnc.js
index c3531c2c..4754f6b0 100644
--- a/include/vnc.js
+++ b/include/vnc.js
@@ -11,7 +11,7 @@
/*global window, document, VNC_uri_prefix */
// Globals defined here
-var VNC_native_ws, WebSocket__swfLocation;
+var VNC_native_ws, WEB_SOCKET_SWF_LOCATION;
/*
* Load supporting scripts
@@ -41,7 +41,7 @@ function get_VNC_uri_prefix() {
VNC_native_ws = true;
} else {
VNC_native_ws = false;
- WebSocket__swfLocation = get_VNC_uri_prefix() +
+ WEB_SOCKET_SWF_LOCATION = get_VNC_uri_prefix() +
"web-socket-js/WebSocketMain.swf";
extra += start + "web-socket-js/swfobject.js" + end;
extra += start + "web-socket-js/FABridge.js" + end;
diff --git a/include/web-socket-js/README.txt b/include/web-socket-js/README.txt
index 98ead65d..2e32ea7f 100644
--- a/include/web-socket-js/README.txt
+++ b/include/web-socket-js/README.txt
@@ -15,23 +15,41 @@ Assuming you have Web server (e.g. Apache) running at http://example.com/ .
#1: First argument of echo_server.rb means that it accepts Web Socket connection from HTML pages in example.com.
-* How to debug
+* Troubleshooting
-If sample.html doesn't work, check these:
+If it doesn't work, try these:
-- It doesn't work when you open sample.html as local file i.e. file:///.../sample.html. Open it via Web server.
-- Make sure port 10081 is not blocked by your server/client's firewall.
-- Use Developer Tools (Chrome/Safari) or Firebug (Firefox) to see if console.log outputs any errors.
-- Install debugger version of Flash Player available here to see Flash errors:
+1. Try Chrome and Firefox 3.x.
+- It doesn't work on Chrome:
+-- It's likely an issue of your code or the server. Debug your code as usual e.g. using console.log.
+- It works on Chrome but it doesn't work on Firefox:
+-- It's likely an issue of web-socket-js specific configuration (e.g. 3 and 4 below).
+- It works on both Chrome and Firefox, but it doesn't work on your browser:
+-- Check "Supported environment" section below. Your browser may not be supported by web-socket-js.
+
+2. Add this line before your code:
+ WEB_SOCKET_DEBUG = true;
+and use Developer Tools (Chrome/Safari) or Firebug (Firefox) to see if console.log outputs any errors.
+
+3. Make sure you do NOT open your HTML page as local file e.g. file:///.../sample.html. web-socket-js doesn't work on local file. Open it via Web server e.g. http:///.../sample.html.
+
+4. If you are NOT using web-socket-ruby as your WebSocket server, you need to place Flash socket policy file on your server. See "Flash socket policy file" section below for details.
+
+5. Check if sample.html bundled with web-socket-js works.
+
+6. Make sure the port used for WebSocket (10081 in example above) is not blocked by your server/client's firewall.
+
+7. Install debugger version of Flash Player available here to see Flash errors:
http://www.adobe.com/support/flashplayer/downloads.html
-* Supported environment
+* Supported environments
-I confirmed it works on Chrome 3, Firefox 3.5 and IE 8. It may not work in other browsers.
-It requires Flash Player 9 or later (probably).
+It should work on:
+- Google Chrome 4 or later (just uses native implementation)
+- Firefox 3.x, Internet Explorer 8 + Flash Player 9 or later
-On Chrome 4 Dev Channel, it just uses native Web Socket implementation.
+It may or may not work on other browsers such as Safari, Opera or IE 6. Patch for these browsers are appreciated, but I will not work on fixing issues specific to these browsers by myself.
* Flash socket policy file
@@ -44,7 +62,8 @@ http://github.com/gimite/web-socket-ruby/tree/master
If you use other Web Socket server implementation, you need to provide socket policy file yourself. See
http://www.lightsphere.com/dev/articles/flash_socket_policy.html
-for details and sample script to run socket policy file server.
+for details and sample script to run socket policy file server. node.js implementation is available here:
+http://github.com/LearnBoost/Socket.IO-node/blob/master/lib/socket.io/transports/flashsocket.js
Actually, it's still better to provide socket policy file at port 843 even if you use web-socket-ruby. Flash always try to connect to port 843 first, so providing the file at port 843 makes startup faster.
@@ -65,6 +84,17 @@ The AS3 Socket class doesn't implement this mechanism, which renders it useless
The class RFC2817Socket (by Christian Cantrell) effectively lets us implement this, as long as the proxy settings are known and provided by the interface that instantiates the WebSocket. As such, if you want to support proxied conncetions, you'll have to supply this information to the WebSocket constructor when Flash is being used. One way to go about it would be to ask the user for proxy settings information if the initial connection fails.
+* How to host HTML file and SWF file in different domains
+
+By default, HTML file and SWF file must be in the same domain. You can follow steps below to allow hosting them in different domain.
+
+WARNING: If you use the method below, HTML files in ANY domains can send arbitrary TCP data to your WebSocket server, regardless of configuration in Flash socket policy file. Arbitrary TCP data means that they can even fake request headers including Origin and Cookie.
+
+- Unzip WebSocketMainInsecure.zip to extract WebSocketMainInsecure.swf.
+- Put WebSocketMainInsecure.swf on your server, instead of WebSocketMain.swf.
+- In JavaScript, set WEB_SOCKET_SWF_LOCATION to URL of your WebSocketMainInsecure.swf.
+
+
* How to build WebSocketMain.swf
Install Flex 4 SDK:
diff --git a/include/web-socket-js/WebSocketMain.swf b/include/web-socket-js/WebSocketMain.swf
deleted file mode 120000
index 4753408d..00000000
--- a/include/web-socket-js/WebSocketMain.swf
+++ /dev/null
@@ -1 +0,0 @@
-flash-src/WebSocketMain.swf
\ No newline at end of file
diff --git a/include/web-socket-js/WebSocketMain.swf b/include/web-socket-js/WebSocketMain.swf
new file mode 100644
index 00000000..d52a0b79
Binary files /dev/null and b/include/web-socket-js/WebSocketMain.swf differ
diff --git a/include/web-socket-js/flash-src/WebSocket.as b/include/web-socket-js/flash-src/WebSocket.as
deleted file mode 100644
index c6dad119..00000000
--- a/include/web-socket-js/flash-src/WebSocket.as
+++ /dev/null
@@ -1,458 +0,0 @@
-// Copyright: Hiroshi Ichikawa
-// License: New BSD License
-// Reference: http://dev.w3.org/html5/websockets/
-// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-76
-
-package {
-
-import flash.display.*;
-import flash.events.*;
-import flash.external.*;
-import flash.net.*;
-import flash.system.*;
-import flash.utils.*;
-import mx.core.*;
-import mx.controls.*;
-import mx.events.*;
-import mx.utils.*;
-import com.adobe.net.proxies.RFC2817Socket;
-import com.hurlant.crypto.tls.TLSSocket;
-import com.hurlant.crypto.tls.TLSConfig;
-import com.hurlant.crypto.tls.TLSEngine;
-import com.hurlant.crypto.tls.TLSSecurityParameters;
-import com.gsolo.encryption.MD5;
-
-[Event(name="message", type="WebSocketMessageEvent")]
-[Event(name="open", type="flash.events.Event")]
-[Event(name="close", type="flash.events.Event")]
-[Event(name="error", type="flash.events.Event")]
-[Event(name="stateChange", type="WebSocketStateEvent")]
-public class WebSocket extends EventDispatcher {
-
- private static var CONNECTING:int = 0;
- private static var OPEN:int = 1;
- private static var CLOSING:int = 2;
- private static var CLOSED:int = 3;
-
- private var rawSocket:Socket;
- private var tlsSocket:TLSSocket;
- private var tlsConfig:TLSConfig;
- private var socket:Socket;
- private var main:WebSocketMain;
- private var url:String;
- private var scheme:String;
- private var host:String;
- private var port:uint;
- private var path:String;
- private var origin:String;
- private var protocol:String;
- private var buffer:ByteArray = new ByteArray();
- private var dataQueue:Array;
- private var headerState:int = 0;
- private var readyState:int = CONNECTING;
- private var bufferedAmount:int = 0;
- private var headers:String;
- private var noiseChars:Array;
- private var expectedDigest:String;
-
- public function WebSocket(
- main:WebSocketMain, url:String, protocol:String,
- proxyHost:String = null, proxyPort:int = 0,
- headers:String = null) {
- this.main = main;
- initNoiseChars();
- this.url = url;
- var m:Array = url.match(/^(\w+):\/\/([^\/:]+)(:(\d+))?(\/.*)?$/);
- if (!m) main.fatal("SYNTAX_ERR: invalid url: " + url);
- this.scheme = m[1];
- this.host = m[2];
- this.port = parseInt(m[4] || "80");
- this.path = m[5] || "/";
- this.origin = main.getOrigin();
- this.protocol = protocol;
- // if present and not the empty string, headers MUST end with \r\n
- // headers should be zero or more complete lines, for example
- // "Header1: xxx\r\nHeader2: yyyy\r\n"
- this.headers = headers;
-
- if (proxyHost != null && proxyPort != 0){
- if (scheme == "wss") {
- main.fatal("wss with proxy is not supported");
- }
- var proxySocket:RFC2817Socket = new RFC2817Socket();
- proxySocket.setProxyInfo(proxyHost, proxyPort);
- proxySocket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
- rawSocket = socket = proxySocket;
- } else {
- rawSocket = new Socket();
- if (scheme == "wss") {
- tlsConfig= new TLSConfig(TLSEngine.CLIENT,
- null, null, null, null, null,
- TLSSecurityParameters.PROTOCOL_VERSION);
- tlsConfig.trustSelfSignedCertificates = true;
- tlsConfig.ignoreCommonNameMismatch = true;
- tlsSocket = new TLSSocket();
- tlsSocket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
- socket = tlsSocket;
- } else {
- rawSocket.addEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
- socket = rawSocket;
- }
- }
- rawSocket.addEventListener(Event.CLOSE, onSocketClose);
- rawSocket.addEventListener(Event.CONNECT, onSocketConnect);
- rawSocket.addEventListener(IOErrorEvent.IO_ERROR, onSocketIoError);
- rawSocket.addEventListener(SecurityErrorEvent.SECURITY_ERROR, onSocketSecurityError);
- rawSocket.connect(host, port);
- }
-
- public function send(encData:String):int {
- var data:String = decodeURIComponent(encData);
- if (readyState == OPEN) {
- socket.writeByte(0x00);
- socket.writeUTFBytes(data);
- socket.writeByte(0xff);
- socket.flush();
- main.log("sent: " + data);
- return -1;
- } else if (readyState == CLOSED) {
- var bytes:ByteArray = new ByteArray();
- bytes.writeUTFBytes(data);
- bufferedAmount += bytes.length; // not sure whether it should include \x00 and \xff
- // We use return value to let caller know bufferedAmount because we cannot fire
- // stateChange event here which causes weird error:
- // > You are trying to call recursively into the Flash Player which is not allowed.
- return bufferedAmount;
- } else {
- main.fatal("INVALID_STATE_ERR: invalid state");
- return 0;
- }
- }
-
- public function close():void {
- main.log("close");
- dataQueue = [];
- try {
- socket.writeByte(0xff);
- socket.writeByte(0x00);
- socket.flush();
- socket.close();
- } catch (ex:Error) { }
- readyState = CLOSED;
- // We don't fire any events here because it causes weird error:
- // > You are trying to call recursively into the Flash Player which is not allowed.
- // We do something equivalent in JavaScript WebSocket#close instead.
- }
-
- public function getReadyState():int {
- return readyState;
- }
-
- public function getBufferedAmount():int {
- return bufferedAmount;
- }
-
- private function onSocketConnect(event:Event):void {
- main.log("connected");
-
- if (scheme == "wss") {
- main.log("starting SSL/TLS");
- tlsSocket.startTLS(rawSocket, host, tlsConfig);
- }
-
- dataQueue = [];
- var hostValue:String = host + (port == 80 ? "" : ":" + port);
- var cookie:String = "";
- if (main.getCallerHost() == host) {
- cookie = ExternalInterface.call("function(){return document.cookie}");
- }
- var key1:String = generateKey();
- var key2:String = generateKey();
- var key3:String = generateKey3();
- expectedDigest = getSecurityDigest(key1, key2, key3);
- var opt:String = "";
- if (protocol) opt += "WebSocket-Protocol: " + protocol + "\r\n";
- // if caller passes additional headers they must end with "\r\n"
- if (headers) opt += headers;
-
- var req:String = StringUtil.substitute(
- "GET {0} HTTP/1.1\r\n" +
- "Upgrade: WebSocket\r\n" +
- "Connection: Upgrade\r\n" +
- "Host: {1}\r\n" +
- "Origin: {2}\r\n" +
- "Cookie: {3}\r\n" +
- "Sec-WebSocket-Key1: {4}\r\n" +
- "Sec-WebSocket-Key2: {5}\r\n" +
- "{6}" +
- "\r\n",
- path, hostValue, origin, cookie, key1, key2, opt);
- main.log("request header:\n" + req);
- socket.writeUTFBytes(req);
- main.log("sent key3: " + key3);
- writeBytes(key3);
- socket.flush();
- }
-
- private function onSocketClose(event:Event):void {
- main.log("closed");
- readyState = CLOSED;
- notifyStateChange();
- dispatchEvent(new Event("close"));
- }
-
- private function onSocketIoError(event:IOErrorEvent):void {
- var message:String;
- if (readyState == CONNECTING) {
- message = "cannot connect to Web Socket server at " + url + " (IoError)";
- } else {
- message = "error communicating with Web Socket server at " + url + " (IoError)";
- }
- onError(message);
- }
-
- private function onSocketSecurityError(event:SecurityErrorEvent):void {
- var message:String;
- if (readyState == CONNECTING) {
- message =
- "cannot connect to Web Socket server at " + url + " (SecurityError)\n" +
- "make sure the server is running and Flash socket policy file is correctly placed";
- } else {
- message = "error communicating with Web Socket server at " + url + " (SecurityError)";
- }
- onError(message);
- }
-
- private function onError(message:String):void {
- var state:int = readyState;
- if (state == CLOSED) return;
- main.error(message);
- close();
- notifyStateChange();
- dispatchEvent(new Event(state == CONNECTING ? "close" : "error"));
- }
-
- private function onSocketData(event:ProgressEvent):void {
- var pos:int = buffer.length;
- socket.readBytes(buffer, pos);
- for (; pos < buffer.length; ++pos) {
- if (headerState < 4) {
- // try to find "\r\n\r\n"
- if ((headerState == 0 || headerState == 2) && buffer[pos] == 0x0d) {
- ++headerState;
- } else if ((headerState == 1 || headerState == 3) && buffer[pos] == 0x0a) {
- ++headerState;
- } else {
- headerState = 0;
- }
- if (headerState == 4) {
- buffer.position = 0;
- var headerStr:String = buffer.readUTFBytes(pos + 1);
- main.log("response header:\n" + headerStr);
- if (!validateHeader(headerStr)) return;
- removeBufferBefore(pos + 1);
- pos = -1;
- }
- } else if (headerState == 4) {
- if (pos == 15) {
- buffer.position = 0;
- var replyDigest:String = readBytes(buffer, 16);
- main.log("reply digest: " + replyDigest);
- if (replyDigest != expectedDigest) {
- onError("digest doesn't match: " + replyDigest + " != " + expectedDigest);
- return;
- }
- headerState = 5;
- removeBufferBefore(pos + 1);
- pos = -1;
- readyState = OPEN;
- notifyStateChange();
- dispatchEvent(new Event("open"));
- }
- } else {
- if (buffer[pos] == 0xff && pos > 0) {
- if (buffer[0] != 0x00) {
- onError("data must start with \\x00");
- return;
- }
- buffer.position = 1;
- var data:String = buffer.readUTFBytes(pos - 1);
- main.log("received: " + data);
- dataQueue.push(encodeURIComponent(data));
- dispatchEvent(new WebSocketMessageEvent("message", data.length.toString()));
- removeBufferBefore(pos + 1);
- pos = -1;
- } else if (pos == 1 && buffer[0] == 0xff && buffer[1] == 0x00) { // closing
- main.log("received closing packet");
- removeBufferBefore(pos + 1);
- pos = -1;
- close();
- notifyStateChange();
- dispatchEvent(new Event("close"));
- }
- }
- }
- }
-
- public function readSocketData():Array {
- var q:Array = dataQueue;
- if (dataQueue.length > 0) {
- // Reset to empty
- dataQueue = [];
- }
- return q;
- }
-
- private function validateHeader(headerStr:String):Boolean {
- var lines:Array = headerStr.split(/\r\n/);
- if (!lines[0].match(/^HTTP\/1.1 101 /)) {
- onError("bad response: " + lines[0]);
- return false;
- }
- var header:Object = {};
- for (var i:int = 1; i < lines.length; ++i) {
- if (lines[i].length == 0) continue;
- var m:Array = lines[i].match(/^(\S+): (.*)$/);
- if (!m) {
- onError("failed to parse response header line: " + lines[i]);
- return false;
- }
- header[m[1]] = m[2];
- }
- if (header["Upgrade"] != "WebSocket") {
- onError("invalid Upgrade: " + header["Upgrade"]);
- return false;
- }
- if (header["Connection"] != "Upgrade") {
- onError("invalid Connection: " + header["Connection"]);
- return false;
- }
- if (!header["Sec-WebSocket-Origin"]) {
- if (header["WebSocket-Origin"]) {
- onError(
- "The WebSocket server speaks old WebSocket protocol, " +
- "which is not supported by web-socket-js. " +
- "It requires WebSocket protocol 76 or later. " +
- "Try newer version of the server if available.");
- } else {
- onError("header Sec-WebSocket-Origin is missing");
- }
- return false;
- }
- var resOrigin:String = header["Sec-WebSocket-Origin"].toLowerCase();
- if (resOrigin != origin) {
- onError("origin doesn't match: '" + resOrigin + "' != '" + origin + "'");
- return false;
- }
- if (protocol && header["Sec-WebSocket-Protocol"] != protocol) {
- onError("protocol doesn't match: '" +
- header["WebSocket-Protocol"] + "' != '" + protocol + "'");
- return false;
- }
- return true;
- }
-
- private function removeBufferBefore(pos:int):void {
- if (pos == 0) return;
- var nextBuffer:ByteArray = new ByteArray();
- buffer.position = pos;
- buffer.readBytes(nextBuffer);
- buffer = nextBuffer;
- }
-
- private function notifyStateChange():void {
- dispatchEvent(new WebSocketStateEvent("stateChange", readyState, bufferedAmount));
- }
-
- private function initNoiseChars():void {
- noiseChars = new Array();
- for (var i:int = 0x21; i <= 0x2f; ++i) {
- noiseChars.push(String.fromCharCode(i));
- }
- for (var j:int = 0x3a; j <= 0x7a; ++j) {
- noiseChars.push(String.fromCharCode(j));
- }
- }
-
- private function generateKey():String {
- var spaces:uint = randomInt(1, 12);
- var max:uint = uint.MAX_VALUE / spaces;
- var number:uint = randomInt(0, max);
- var key:String = (number * spaces).toString();
- var noises:int = randomInt(1, 12);
- var pos:int;
- for (var i:int = 0; i < noises; ++i) {
- var char:String = noiseChars[randomInt(0, noiseChars.length - 1)];
- pos = randomInt(0, key.length);
- key = key.substr(0, pos) + char + key.substr(pos);
- }
- for (var j:int = 0; j < spaces; ++j) {
- pos = randomInt(1, key.length - 1);
- key = key.substr(0, pos) + " " + key.substr(pos);
- }
- return key;
- }
-
- private function generateKey3():String {
- var key3:String = "";
- for (var i:int = 0; i < 8; ++i) {
- key3 += String.fromCharCode(randomInt(0, 255));
- }
- return key3;
- }
-
- private function getSecurityDigest(key1:String, key2:String, key3:String):String {
- var bytes1:String = keyToBytes(key1);
- var bytes2:String = keyToBytes(key2);
- return MD5.rstr_md5(bytes1 + bytes2 + key3);
- }
-
- private function keyToBytes(key:String):String {
- var keyNum:uint = parseInt(key.replace(/[^\d]/g, ""));
- var spaces:uint = 0;
- for (var i:int = 0; i < key.length; ++i) {
- if (key.charAt(i) == " ") ++spaces;
- }
- var resultNum:uint = keyNum / spaces;
- var bytes:String = "";
- for (var j:int = 3; j >= 0; --j) {
- bytes += String.fromCharCode((resultNum >> (j * 8)) & 0xff);
- }
- return bytes;
- }
-
- // Writes byte sequence to socket.
- // bytes is String in special format where bytes[i] is i-th byte, not i-th character.
- private function writeBytes(bytes:String):void {
- for (var i:int = 0; i < bytes.length; ++i) {
- socket.writeByte(bytes.charCodeAt(i));
- }
- }
-
- // Reads specified number of bytes from buffer, and returns it as special format String
- // where bytes[i] is i-th byte (not i-th character).
- private function readBytes(buffer:ByteArray, numBytes:int):String {
- var bytes:String = "";
- for (var i:int = 0; i < numBytes; ++i) {
- // & 0xff is to make \x80-\xff positive number.
- bytes += String.fromCharCode(buffer.readByte() & 0xff);
- }
- return bytes;
- }
-
- private function randomInt(min:uint, max:uint):uint {
- return min + Math.floor(Math.random() * (Number(max) - min + 1));
- }
-
- // for debug
- private function dumpBytes(bytes:String):void {
- var output:String = "";
- for (var i:int = 0; i < bytes.length; ++i) {
- output += bytes.charCodeAt(i).toString() + ", ";
- }
- main.log(output);
- }
-
-}
-
-}
diff --git a/include/web-socket-js/flash-src/WebSocketMain.as b/include/web-socket-js/flash-src/WebSocketMain.as
deleted file mode 100644
index 41991e78..00000000
--- a/include/web-socket-js/flash-src/WebSocketMain.as
+++ /dev/null
@@ -1,94 +0,0 @@
-// Copyright: Hiroshi Ichikawa
-// License: New BSD License
-// Reference: http://dev.w3.org/html5/websockets/
-// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-31
-
-package {
-
-import flash.display.*;
-import flash.events.*;
-import flash.external.*;
-import flash.net.*;
-import flash.system.*;
-import flash.utils.*;
-import mx.core.*;
-import mx.controls.*;
-import mx.events.*;
-import mx.utils.*;
-import bridge.FABridge;
-
-public class WebSocketMain extends Sprite {
-
- private var policyLoaded:Boolean = false;
- private var callerUrl:String;
- private var debug:Boolean = false;
-
- public function WebSocketMain() {
-
- // This is to avoid "You are trying to call recursively into the Flash Player ..."
- // error which (I heard) happens when you pass bunch of messages.
- // This workaround was written here:
- // http://www.themorphicgroup.com/blog/2009/02/14/fabridge-error-you-are-trying-to-call-recursively-into-the-flash-player-which-is-not-allowed/
- FABridge.EventsToCallLater["flash.events::Event"] = "true";
- FABridge.EventsToCallLater["WebSocketMessageEvent"] = "true";
- FABridge.EventsToCallLater["WebSocketStateEvent"] = "true";
-
- var fab:FABridge = new FABridge();
- fab.rootObject = this;
- //log("Flash initialized");
-
- }
-
- public function setCallerUrl(url:String):void {
- callerUrl = url;
- }
-
- public function setDebug(val:Boolean):void {
- debug = val;
- }
-
- public function create(
- url:String, protocol:String,
- proxyHost:String = null, proxyPort:int = 0,
- headers:String = null):WebSocket {
- loadPolicyFile(null);
- return new WebSocket(this, url, protocol, proxyHost, proxyPort, headers);
- }
-
- public function getOrigin():String {
- return (URLUtil.getProtocol(this.callerUrl) + "://" +
- URLUtil.getServerNameWithPort(this.callerUrl)).toLowerCase();
- }
-
- public function getCallerHost():String {
- return URLUtil.getServerName(this.callerUrl);
- }
-
- public function loadPolicyFile(url:String):void {
- if (policyLoaded && !url) return;
- if (!url) {
- url = "xmlsocket://" + URLUtil.getServerName(this.callerUrl) + ":843";
- }
- log("policy file: " + url);
- Security.loadPolicyFile(url);
- policyLoaded = true;
- }
-
- public function log(message:String):void {
- if (debug) {
- ExternalInterface.call("webSocketLog", encodeURIComponent("[WebSocket] " + message));
- }
- }
-
- public function error(message:String):void {
- ExternalInterface.call("webSocketError", encodeURIComponent("[WebSocket] " + message));
- }
-
- public function fatal(message:String):void {
- ExternalInterface.call("webSocketError", encodeURIComponent("[WebSocket] " + message));
- throw message;
- }
-
-}
-
-}
diff --git a/include/web-socket-js/flash-src/WebSocketMain.swf b/include/web-socket-js/flash-src/WebSocketMain.swf
deleted file mode 100644
index 930b9075..00000000
Binary files a/include/web-socket-js/flash-src/WebSocketMain.swf and /dev/null differ
diff --git a/include/web-socket-js/flash-src/WebSocketMessageEvent.as b/include/web-socket-js/flash-src/WebSocketMessageEvent.as
deleted file mode 100644
index a1385a0d..00000000
--- a/include/web-socket-js/flash-src/WebSocketMessageEvent.as
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright: Hiroshi Ichikawa
-// License: New BSD License
-// Reference: http://dev.w3.org/html5/websockets/
-// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-31
-
-package {
-
-import flash.display.*;
-import flash.events.*;
-import flash.external.*;
-import flash.net.*;
-import flash.system.*;
-import flash.utils.*;
-import mx.core.*;
-import mx.controls.*;
-import mx.events.*;
-import mx.utils.*;
-
-public class WebSocketMessageEvent extends Event {
-
- public var data:String;
-
- public function WebSocketMessageEvent(type:String, data:String) {
- super(type);
- this.data = data;
- }
-
-}
-
-}
diff --git a/include/web-socket-js/flash-src/WebSocketStateEvent.as b/include/web-socket-js/flash-src/WebSocketStateEvent.as
deleted file mode 100644
index c2af6592..00000000
--- a/include/web-socket-js/flash-src/WebSocketStateEvent.as
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright: Hiroshi Ichikawa
-// License: New BSD License
-// Reference: http://dev.w3.org/html5/websockets/
-// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol-31
-
-package {
-
-import flash.display.*;
-import flash.events.*;
-import flash.external.*;
-import flash.net.*;
-import flash.system.*;
-import flash.utils.*;
-import mx.core.*;
-import mx.controls.*;
-import mx.events.*;
-import mx.utils.*;
-
-public class WebSocketStateEvent extends Event {
-
- public var readyState:int;
- public var bufferedAmount:int;
-
- public function WebSocketStateEvent(type:String, readyState:int, bufferedAmount:int) {
- super(type);
- this.readyState = readyState;
- this.bufferedAmount = bufferedAmount;
- }
-
-}
-
-}
diff --git a/include/web-socket-js/flash-src/bridge/FABridge.as b/include/web-socket-js/flash-src/bridge/FABridge.as
deleted file mode 100644
index d03dba01..00000000
--- a/include/web-socket-js/flash-src/bridge/FABridge.as
+++ /dev/null
@@ -1,943 +0,0 @@
-/*
-Copyright � 2006 Adobe Systems Incorporated
-
-Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"),
-to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense,
-and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
-
- The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
-
-
-THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
-FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
-LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
-OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-*/
-
-
-/*
- * The Bridge class, responsible for navigating JS instances
- */
-package bridge
-{
-
-/*
- * imports
- */
-import flash.external.ExternalInterface;
-import flash.utils.Timer;
-import flash.events.*;
-import flash.display.DisplayObject;
-import flash.system.ApplicationDomain;
-import flash.utils.Dictionary;
-import flash.utils.setTimeout;
-
-import mx.collections.errors.ItemPendingError;
-import mx.core.IMXMLObject;
-
-import flash.utils.getQualifiedClassName;
-import flash.utils.describeType;
-import flash.events.TimerEvent;
-
-/**
- * The FABridge class, responsible for proxying AS objects into javascript
- */
-public class FABridge extends EventDispatcher implements IMXMLObject
-{
-
- //holds a list of stuff to call later, to break the recurrence of the js <> as calls
- //you must use the full class name, as returned by the getQualifiedClassName() function
- public static const MethodsToCallLater:Object = new Object();
- MethodsToCallLater["mx.collections::ArrayCollection"]="refresh,removeItemAt";
-
- public static const EventsToCallLater:Object = new Object();
- EventsToCallLater["mx.data.events::UnresolvedConflictsEvent"]="true";
- EventsToCallLater["mx.events::PropertyChangeEvent"]="true";
-
- public static const INITIALIZED:String = "bridgeInitialized";
-
- // constructor
- public function FABridge()
- {
- super();
- initializeCallbacks();
- }
-
- // private vars
-
- /**
- * stores a cache of descriptions of AS types suitable for sending to JS
- */
- private var localTypeMap:Dictionary = new Dictionary();
-
- /**
- * stores an id-referenced dictionary of objects exported to JS
- */
- private var localInstanceMap:Dictionary = new Dictionary();
-
- /**
- * stores an id-referenced dictionary of functions exported to JS
- */
- private var localFunctionMap:Dictionary = new Dictionary();
-
- /**
- * stores an id-referenced dictionary of proxy functions imported from JS
- */
- private var remoteFunctionCache:Dictionary = new Dictionary();
-
- /**
- * stores a list of custom serialization functions
- */
- private var customSerializersMap:Dictionary = new Dictionary();
-
- /**
- * stores a map of object ID's and their reference count
- */
- private var refMap:Dictionary = new Dictionary();
- /**
- * a local counter for generating unique IDs
- */
- private var nextID:Number = 0;
-
- private var lastRef:int;
-
- /* values that can't be serialized natively across the bridge are packed and identified by type.
- These constants represent different serialization types */
- public static const TYPE_ASINSTANCE:uint = 1;
- public static const TYPE_ASFUNCTION:uint = 2;
- public static const TYPE_JSFUNCTION:uint = 3;
- public static const TYPE_ANONYMOUS:uint = 4;
-
- private var _initChecked:Boolean = false;
-
- // properties
-
- //getters and setters for the main component in the swf - the root
- public function get rootObject():DisplayObject {return _rootObject;}
- public function set rootObject(value:DisplayObject):void
- {
- _rootObject = value;
- checkInitialized();
- }
-
- /**
- * the bridge name
- */
- public var bridgeName:String;
- private var _registerComplete:Boolean = false;
-
- /**
- * increment the reference count for an object being passed over the bridge
- */
- public function incRef(objId:int):void
- {
- if(refMap[objId] == null) {
- //the object is being created; we now add it to the map and set its refCount = 1
- refMap[objId] = 1;
- } else {
- refMap[objId] = refMap[objId] +1;
- }
- }
-
- /**
- * when an object has been completely passed to JS its reference count is decreased with 1
- */
- public function releaseRef(objId:int):void
- {
- if(refMap[objId] != null)
- {
- var newRefVal:int = refMap[objId] - 1;
- // if the object exists in the referenceMap and its count equals or has dropped under 0 we clean it up
- if(refMap[objId] != null && newRefVal <= 0)
- {
- delete refMap[objId];
- delete localInstanceMap[objId];
- }
- else
- {
- refMap[objId] = newRefVal;
- }
- }
- }
-
- /**
- * attaches the callbacks to external interface
- */
- public function initializeCallbacks():void
- {
- if (ExternalInterface.available == false)
- {
- return;
- }
-
- ExternalInterface.addCallback("getRoot", js_getRoot);
- ExternalInterface.addCallback("getPropFromAS", js_getPropFromAS);
- ExternalInterface.addCallback("setPropInAS", js_setPropertyInAS);
- ExternalInterface.addCallback("invokeASMethod", js_invokeMethod);
- ExternalInterface.addCallback("invokeASFunction", js_invokeFunction);
- ExternalInterface.addCallback("releaseASObjects", js_releaseASObjects);
- ExternalInterface.addCallback("create", js_create);
- ExternalInterface.addCallback("releaseNamedASObject",js_releaseNamedASObject);
- ExternalInterface.addCallback("incRef", incRef);
- ExternalInterface.addCallback("releaseRef", releaseRef);
- }
-
- private var _rootObject:DisplayObject;
-
- private var _document:DisplayObject;
-
- /**
- * called to check whether the bridge has been initialized for the specified document/id pairs
- */
- public function initialized(document:Object, id:String):void
- {
- _document = (document as DisplayObject);
-
- if (_document != null)
- {
- checkInitialized();
- }
- }
-
- private function get baseObject():DisplayObject
- {
- return (rootObject == null)? _document:rootObject;
- }
-
-
- private function checkInitialized():void
- {
- if(_initChecked== true)
- {
- return;
- }
- _initChecked = true;
-
- // oops! timing error. Player team is working on it.
- var t:Timer = new Timer(200,1);
- t.addEventListener(TimerEvent.TIMER,auxCheckInitialized);
- t.start();
- }
-
- /**
- * auxiliary initialization check that is called after the timing has occurred
- */
- private function auxCheckInitialized(e:Event):void
- {
-
- var bCanGetParams:Boolean = true;
-
- try
- {
- var params:Object = baseObject.root.loaderInfo.parameters;
- }
- catch (e:Error)
- {
- bCanGetParams = false;
- }
-
- if (bCanGetParams == false)
- {
- var t:Timer = new Timer(100);
- var timerFunc:Function = function(e:TimerEvent):void
- {
- if(baseObject.root != null)
- {
- try
- {
- bCanGetParams = true;
- var params:Object = baseObject.root.loaderInfo.parameters;
- }
- catch (err:Error)
- {
- bCanGetParams = false;
- }
- if (bCanGetParams)
- {
- t.removeEventListener(TimerEvent.TIMER, timerFunc);
- t.stop();
- dispatchInit();
- }
- }
- }
- t.addEventListener(TimerEvent.TIMER, timerFunc);
- t.start();
- }
- else
- {
- dispatchInit();
- }
- }
-
- /**
- * call into JS to annunce that the bridge is ready to be used
- */
- private function dispatchInit(e:Event = null):void
- {
- if(_registerComplete == true)
- {
- return;
- }
-
- if (ExternalInterface.available == false)
- {
- return;
- }
-
- if (bridgeName == null)
- {
- bridgeName = baseObject.root.loaderInfo.parameters["bridgeName"];
-
- if(bridgeName == null)
- {
- bridgeName = "flash";
- }
- }
-
- _registerComplete = ExternalInterface.call("FABridge__bridgeInitialized", [bridgeName]);
- dispatchEvent(new Event(FABridge.INITIALIZED));
- }
-
- // serialization/deserialization
-
- /** serializes a value for transfer across the bridge. primitive types are left as is. Arrays are left as arrays, but individual
- * values in the array are serialized according to their type. Functions and class instances are inserted into a hash table and sent
- * across as keys into the table.
- *
- * For class instances, if the instance has been sent before, only its id is passed. If This is the first time the instance has been sent,
- * a ref descriptor is sent associating the id with a type string. If this is the first time any instance of that type has been sent
- * across, a descriptor indicating methods, properties, and variables of the type is also sent across
- */
- public function serialize(value:*, keep_refs:Boolean=false):*
- {
- var result:* = {};
- result.newTypes = [];
- result.newRefs = {};
-
- if (value is Number || value is Boolean || value is String || value == null || value == undefined || value is int || value is uint)
- {
- result = value;
- }
- else if (value is Array)
- {
- result = [];
- for(var i:int = 0; i < value.length; i++)
- {
- result[i] = serialize(value[i], keep_refs);
- }
- }
- else if (value is Function)
- {
- // serialize a class
- result.type = TYPE_ASFUNCTION;
- result.value = getFunctionID(value, true);
- }
- else if (getQualifiedClassName(value) == "Object")
- {
- result.type = TYPE_ANONYMOUS;
- result.value = value;
- }
- else
- {
- // serialize a class
- result.type = TYPE_ASINSTANCE;
- // make sure the type info is available
- var className:String = getQualifiedClassName(value);
-
- var serializer:Function = customSerializersMap[className];
-
- // try looking up the serializer under an alternate name
- if (serializer == null)
- {
- if (className.indexOf('$') > 0)
- {
- var split:int = className.lastIndexOf(':');
- if (split > 0)
- {
- var alternate:String = className.substring(split+1);
- serializer = customSerializersMap[alternate];
- }
- }
- }
-
- if (serializer != null)
- {
- return serializer.apply(null, [value, keep_refs]);
- }
- else
- {
- if (retrieveCachedTypeDescription(className, false) == null)
- {
- try
- {
- result.newTypes.push(retrieveCachedTypeDescription(className, true));
- }
- catch(err:Error)
- {
- var interfaceInfo:XMLList = describeType(value).implementsInterface;
- for each (var interf:XML in interfaceInfo)
- {
- className = interf.@type.toString();
- if (retrieveCachedTypeDescription(className, false) == null){
- result.newTypes.push(retrieveCachedTypeDescription(className, true));
- } //end if push new data type
-
- } //end for going through interfaces
- var baseClass:String = describeType(value).@base.toString();
- if (retrieveCachedTypeDescription(baseClass, false) == null){
- result.newTypes.push(retrieveCachedTypeDescription(baseClass, true));
- } //end if push new data type
- }
- }
-
- // make sure the reference is known
- var objRef:Number = getRef(value, false);
- var should_keep_ref:Boolean = false;
- if (isNaN(objRef))
- {
- //create the reference if necessary
- objRef = getRef(value, true);
- should_keep_ref = true;
- }
-
- result.newRefs[objRef] = className;
- //trace("serializing new reference: " + className + " with value" + value);
-
- //the result is a getProperty / invokeMethod call. How can we know how much you will need the object ?
- if (keep_refs && should_keep_ref) {
- incRef(objRef);
- }
- result.value = objRef;
- }
- }
- return result;
- }
-
- /**
- * deserializes a value passed in from javascript. See serialize for details on how values are packed and
- * unpacked for transfer across the bridge.
- */
- public function deserialize(valuePackage:*):*
- {
- var result:*;
- if (valuePackage is Number || valuePackage is Boolean || valuePackage is String || valuePackage === null || valuePackage === undefined || valuePackage is int || valuePackage is uint)
- {
- result = valuePackage;
- }
- else if(valuePackage is Array)
- {
- result = [];
- for (var i:int = 0; i < valuePackage.length; i++)
- {
- result[i] = deserialize(valuePackage[i]);
- }
- }
- else if (valuePackage.type == FABridge.TYPE_JSFUNCTION)
- {
- result = getRemoteFunctionProxy(valuePackage.value, true);
- }
- else if (valuePackage.type == FABridge.TYPE_ASFUNCTION)
- {
- throw new Error("as functions can't be passed back to as yet");
- }
- else if (valuePackage.type == FABridge.TYPE_ASINSTANCE)
- {
- result = resolveRef(valuePackage.value);
- }
- else if (valuePackage.type == FABridge.TYPE_ANONYMOUS)
- {
- result = valuePackage.value;
- }
- return result;
- }
-
- public function addCustomSerialization(className:String, serializationFunction:Function):void
- {
- customSerializersMap[className] = serializationFunction;
- }
-
-
- // type management
-
- /**
- * retrieves a type description for the type indicated by className, building one and caching it if necessary
- */
- public function retrieveCachedTypeDescription(className:String, createifNecessary:Boolean):Object
- {
- if(localTypeMap[className] == null && createifNecessary == true)
- {
- localTypeMap[className] = buildTypeDescription(className);
- }
- return localTypeMap[className];
- }
-
- public function addCachedTypeDescription(className:String, desc:Object):Object
- {
- if (localTypeMap[className] == null)
- {
- localTypeMap[className] = desc;
- }
- return localTypeMap[className];
- }
-
- /**
- * builds a type description for the type indiciated by className
- */
- public function buildTypeDescription(className:String):Object
- {
- var desc:Object = {};
-
- className = className.replace(/::/,".");
-
- var objClass:Class = Class(ApplicationDomain.currentDomain.getDefinition(className));
-
- var xData:XML = describeType(objClass);
-
- desc.name = xData.@name.toString();
-
- var methods:Array = [];
- var xMethods:XMLList = xData.factory.method;
- for (var i:int = 0; i < xMethods.length(); i++)
- {
- methods.push(xMethods[i].@name.toString());
- }
- desc.methods = methods;
-
- var accessors:Array = [];
- var xAcc:XMLList = xData.factory.accessor;
- for (i = 0; i < xAcc.length(); i++)
- {
- accessors.push(xAcc[i].@name.toString());
- }
- xAcc = xData.factory.variable;
- for (i = 0; i < xAcc.length(); i++)
- {
- accessors.push(xAcc[i].@name.toString());
- }
- desc.accessors = accessors;
-
- return desc;
- }
-
-// instance mgmt
-
- /**
- * resolves an instance id passed from JS to an instance previously cached for representing in JS
- */
- private function resolveRef(objRef:Number):Object
- {
- try
- {
- return (objRef == -1)? baseObject : localInstanceMap[objRef];
- }
- catch(e:Error)
- {
- return serialize("__FLASHERROR__"+"||"+e.message);
- }
-
- return (objRef == -1)? baseObject : localInstanceMap[objRef];
- }
-
- /**
- * returns an id associated with the object provided for passing across the bridge to JS
- */
- public function getRef(obj:Object, createIfNecessary:Boolean):Number
- {
- try
- {
- var ref:Number;
-
- if (createIfNecessary)
- {
- var newRef:Number = nextID++;
- localInstanceMap[newRef] = obj;
- ref = newRef;
- }
- else
- {
- for (var key:* in localInstanceMap)
- {
- if (localInstanceMap[key] === obj)
- {
- ref = key;
- break;
- }
- }
- }
- }
- catch(e:Error)
- {
- return serialize("__FLASHERROR__"+"||"+e.message)
- }
-
- return ref;
- }
-
-
- // function management
-
- /**
- * resolves a function ID passed from JS to a local function previously cached for representation in JS
- */
- private function resolveFunctionID(funcID:Number):Function
- {
- return localFunctionMap[funcID];
- }
-
- /**
- * associates a unique ID with a local function suitable for passing across the bridge to proxy in Javascript
- */
- public function getFunctionID(f:Function, createIfNecessary:Boolean):Number
- {
- var ref:Number;
-
- if (createIfNecessary)
- {
- var newID:Number = nextID++;
- localFunctionMap[newID] = f;
- ref = newID;
- }
- else
- {
- for (var key:* in localFunctionMap)
- {
- if (localFunctionMap[key] === f) {
- ref = key;
- }
- break;
- }
- }
-
- return ref;
- }
-
- /**
- * returns a proxy function that represents a function defined in javascript. This function can be called syncrhonously, and will
- * return any values returned by the JS function
- */
- public function getRemoteFunctionProxy(functionID:Number, createIfNecessary:Boolean):Function
- {
- try
- {
- if (remoteFunctionCache[functionID] == null)
- {
- remoteFunctionCache[functionID] = function(...args):*
- {
- var externalArgs:Array = args.concat();
- externalArgs.unshift(functionID);
- var serializedArgs:* = serialize(externalArgs, true);
-
- if(checkToThrowLater(serializedArgs[1]))
- {
- setTimeout(function a():* {
- try {
- var retVal:* = ExternalInterface.call("FABridge__invokeJSFunction", serializedArgs);
- for(var i:int = 0; i 0)
- {
- this.dispatchEvent(event);
- }
- }
- this.buffer = null;
- }
-
- private function redirectConnectEvent():void
- {
- super.removeEventListener(Event.CONNECT, onConnect);
- var deferredEventHandler:Object = this.deferredEventHandlers[Event.CONNECT];
- if (deferredEventHandler != null)
- {
- super.addEventListener(Event.CONNECT, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference);
- }
- }
-
- private function redirectSocketDataEvent():void
- {
- super.removeEventListener(ProgressEvent.SOCKET_DATA, onSocketData);
- var deferredEventHandler:Object = this.deferredEventHandlers[ProgressEvent.SOCKET_DATA];
- if (deferredEventHandler != null)
- {
- super.addEventListener(ProgressEvent.SOCKET_DATA, deferredEventHandler.listener, deferredEventHandler.useCapture, deferredEventHandler.priority, deferredEventHandler.useWeakReference);
- }
- }
-
- public override function addEventListener(type:String, listener:Function, useCapture:Boolean = false, priority:int=0.0, useWeakReference:Boolean=false):void
- {
- if (type == Event.CONNECT || type == ProgressEvent.SOCKET_DATA)
- {
- this.deferredEventHandlers[type] = {listener:listener,useCapture:useCapture, priority:priority, useWeakReference:useWeakReference};
- }
- else
- {
- super.addEventListener(type, listener, useCapture, priority, useWeakReference);
- }
- }
- }
-}
\ No newline at end of file
diff --git a/include/web-socket-js/flash-src/com/gsolo/encryption/MD5.as b/include/web-socket-js/flash-src/com/gsolo/encryption/MD5.as
deleted file mode 100644
index e5d9c4a4..00000000
--- a/include/web-socket-js/flash-src/com/gsolo/encryption/MD5.as
+++ /dev/null
@@ -1,375 +0,0 @@
-package com.gsolo.encryption {
- public class MD5 {
- /*
- * A JavaScript implementation of the RSA Data Security, Inc. MD5 Message
- * Digest Algorithm, as defined in RFC 1321.
- * Version 2.2-alpha Copyright (C) Paul Johnston 1999 - 2005
- * Other contributors: Greg Holt, Andrew Kepert, Ydnar, Lostinet
- * Distributed under the BSD License
- * See http://pajhome.org.uk/crypt/md5 for more info.
- *
- * Converted to AS3 By Geoffrey Williams
- */
-
- /*
- * Configurable variables. You may need to tweak these to be compatible with
- * the server-side, but the defaults work in most cases.
- */
-
- public static const HEX_FORMAT_LOWERCASE:uint = 0;
- public static const HEX_FORMAT_UPPERCASE:uint = 1;
-
- public static const BASE64_PAD_CHARACTER_DEFAULT_COMPLIANCE:String = "";
- public static const BASE64_PAD_CHARACTER_RFC_COMPLIANCE:String = "=";
-
- public static var hexcase:uint = 0; /* hex output format. 0 - lowercase; 1 - uppercase */
- public static var b64pad:String = ""; /* base-64 pad character. "=" for strict RFC compliance */
-
- public static function encrypt (string:String):String {
- return hex_md5 (string);
- }
-
- /*
- * These are the functions you'll usually want to call
- * They take string arguments and return either hex or base-64 encoded strings
- */
- public static function hex_md5 (string:String):String {
- return rstr2hex (rstr_md5 (str2rstr_utf8 (string)));
- }
-
- public static function b64_md5 (string:String):String {
- return rstr2b64 (rstr_md5 (str2rstr_utf8 (string)));
- }
-
- public static function any_md5 (string:String, encoding:String):String {
- return rstr2any (rstr_md5 (str2rstr_utf8 (string)), encoding);
- }
- public static function hex_hmac_md5 (key:String, data:String):String {
- return rstr2hex (rstr_hmac_md5 (str2rstr_utf8 (key), str2rstr_utf8 (data)));
- }
- public static function b64_hmac_md5 (key:String, data:String):String {
- return rstr2b64 (rstr_hmac_md5 (str2rstr_utf8 (key), str2rstr_utf8 (data)));
- }
- public static function any_hmac_md5 (key:String, data:String, encoding:String):String {
- return rstr2any(rstr_hmac_md5(str2rstr_utf8(key), str2rstr_utf8(data)), encoding);
- }
-
- /*
- * Perform a simple self-test to see if the VM is working
- */
- public static function md5_vm_test ():Boolean {
- return hex_md5 ("abc") == "900150983cd24fb0d6963f7d28e17f72";
- }
-
- /*
- * Calculate the MD5 of a raw string
- */
- public static function rstr_md5 (string:String):String {
- return binl2rstr (binl_md5 (rstr2binl (string), string.length * 8));
- }
-
- /*
- * Calculate the HMAC-MD5, of a key and some data (raw strings)
- */
- public static function rstr_hmac_md5 (key:String, data:String):String {
- var bkey:Array = rstr2binl (key);
- if (bkey.length > 16) bkey = binl_md5 (bkey, key.length * 8);
-
- var ipad:Array = new Array(16), opad:Array = new Array(16);
- for(var i:Number = 0; i < 16; i++) {
- ipad[i] = bkey[i] ^ 0x36363636;
- opad[i] = bkey[i] ^ 0x5C5C5C5C;
- }
-
- var hash:Array = binl_md5 (ipad.concat (rstr2binl (data)), 512 + data.length * 8);
- return binl2rstr (binl_md5 (opad.concat (hash), 512 + 128));
- }
-
- /*
- * Convert a raw string to a hex string
- */
- public static function rstr2hex (input:String):String {
- var hex_tab:String = hexcase ? "0123456789ABCDEF" : "0123456789abcdef";
- var output:String = "";
- var x:Number;
- for(var i:Number = 0; i < input.length; i++) {
- x = input.charCodeAt(i);
- output += hex_tab.charAt((x >>> 4) & 0x0F)
- + hex_tab.charAt( x & 0x0F);
- }
- return output;
- }
-
- /*
- * Convert a raw string to a base-64 string
- */
- public static function rstr2b64 (input:String):String {
- var tab:String = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
- var output:String = "";
- var len:Number = input.length;
- for(var i:Number = 0; i < len; i += 3) {
- var triplet:Number = (input.charCodeAt(i) << 16)
- | (i + 1 < len ? input.charCodeAt(i+1) << 8 : 0)
- | (i + 2 < len ? input.charCodeAt(i+2) : 0);
- for(var j:Number = 0; j < 4; j++) {
- if(i * 8 + j * 6 > input.length * 8) output += b64pad;
- else output += tab.charAt((triplet >>> 6*(3-j)) & 0x3F);
- }
- }
- return output;
- }
-
- /*
- * Convert a raw string to an arbitrary string encoding
- */
- public static function rstr2any(input:String, encoding:String):String {
- var divisor:Number = encoding.length;
- var remainders:Array = [];
- var i:Number, q:Number, x:Number, quotient:Array;
-
- /* Convert to an array of 16-bit big-endian values, forming the dividend */
- var dividend:Array = new Array(input.length / 2);
- for(i = 0; i < dividend.length; i++) {
- dividend[i] = (input.charCodeAt(i * 2) << 8) | input.charCodeAt(i * 2 + 1);
- }
-
- /*
- * Repeatedly perform a long division. The binary array forms the dividend,
- * the length of the encoding is the divisor. Once computed, the quotient
- * forms the dividend for the next step. We stop when the dividend is zero.
- * All remainders are stored for later use.
- */
- while(dividend.length > 0) {
- quotient = [];
- x = 0;
- for(i = 0; i < dividend.length; i++) {
- x = (x << 16) + dividend[i];
- q = Math.floor(x / divisor);
- x -= q * divisor;
- if(quotient.length > 0 || q > 0)
- quotient[quotient.length] = q;
- }
- remainders[remainders.length] = x;
- dividend = quotient;
- }
-
- /* Convert the remainders to the output string */
- var output:String = "";
- for(i = remainders.length - 1; i >= 0; i--)
- output += encoding.charAt (remainders[i]);
-
- return output;
- }
-
- /*
- * Encode a string as utf-8.
- * For efficiency, this assumes the input is valid utf-16.
- */
- public static function str2rstr_utf8 (input:String):String {
- var output:String = "";
- var i:Number = -1;
- var x:Number, y:Number;
-
- while(++i < input.length) {
- /* Decode utf-16 surrogate pairs */
- x = input.charCodeAt(i);
- y = i + 1 < input.length ? input.charCodeAt(i + 1) : 0;
- if(0xD800 <= x && x <= 0xDBFF && 0xDC00 <= y && y <= 0xDFFF) {
- x = 0x10000 + ((x & 0x03FF) << 10) + (y & 0x03FF);
- i++;
- }
-
- /* Encode output as utf-8 */
- if(x <= 0x7F)
- output += String.fromCharCode(x);
- else if(x <= 0x7FF)
- output += String.fromCharCode(0xC0 | ((x >>> 6 ) & 0x1F),
- 0x80 | ( x & 0x3F));
- else if(x <= 0xFFFF)
- output += String.fromCharCode(0xE0 | ((x >>> 12) & 0x0F),
- 0x80 | ((x >>> 6 ) & 0x3F),
- 0x80 | ( x & 0x3F));
- else if(x <= 0x1FFFFF)
- output += String.fromCharCode(0xF0 | ((x >>> 18) & 0x07),
- 0x80 | ((x >>> 12) & 0x3F),
- 0x80 | ((x >>> 6 ) & 0x3F),
- 0x80 | ( x & 0x3F));
- }
- return output;
- }
-
- /*
- * Encode a string as utf-16
- */
- public static function str2rstr_utf16le (input:String):String {
- var output:String = "";
- for(var i:Number = 0; i < input.length; i++)
- output += String.fromCharCode( input.charCodeAt(i) & 0xFF,
- (input.charCodeAt(i) >>> 8) & 0xFF);
- return output;
- }
-
- public static function str2rstr_utf16be (input:String):String {
- var output:String = "";
- for(var i:Number = 0; i < input.length; i++)
- output += String.fromCharCode((input.charCodeAt(i) >>> 8) & 0xFF,
- input.charCodeAt(i) & 0xFF);
- return output;
- }
-
- /*
- * Convert a raw string to an array of little-endian words
- * Characters >255 have their high-byte silently ignored.
- */
- public static function rstr2binl (input:String):Array {
- var output:Array = new Array(input.length >> 2);
- for(var i:Number = 0; i < output.length; i++)
- output[i] = 0;
- for(i = 0; i < input.length * 8; i += 8)
- output[i>>5] |= (input.charCodeAt(i / 8) & 0xFF) << (i%32);
- return output;
- }
-
- /*
- * Convert an array of little-endian words to a string
- */
- public static function binl2rstr (input:Array):String {
- var output:String = "";
- for(var i:Number = 0; i < input.length * 32; i += 8)
- output += String.fromCharCode((input[i>>5] >>> (i % 32)) & 0xFF);
- return output;
- }
-
- /*
- * Calculate the MD5 of an array of little-endian words, and a bit length.
- */
- public static function binl_md5 (x:Array, len:Number):Array {
- /* append padding */
- x[len >> 5] |= 0x80 << ((len) % 32);
- x[(((len + 64) >>> 9) << 4) + 14] = len;
-
- var a:Number = 1732584193;
- var b:Number = -271733879;
- var c:Number = -1732584194;
- var d:Number = 271733878;
-
- for(var i:Number = 0; i < x.length; i += 16) {
- var olda:Number = a;
- var oldb:Number = b;
- var oldc:Number = c;
- var oldd:Number = d;
-
- a = md5_ff(a, b, c, d, x[i+ 0], 7 , -680876936);
- d = md5_ff(d, a, b, c, x[i+ 1], 12, -389564586);
- c = md5_ff(c, d, a, b, x[i+ 2], 17, 606105819);
- b = md5_ff(b, c, d, a, x[i+ 3], 22, -1044525330);
- a = md5_ff(a, b, c, d, x[i+ 4], 7 , -176418897);
- d = md5_ff(d, a, b, c, x[i+ 5], 12, 1200080426);
- c = md5_ff(c, d, a, b, x[i+ 6], 17, -1473231341);
- b = md5_ff(b, c, d, a, x[i+ 7], 22, -45705983);
- a = md5_ff(a, b, c, d, x[i+ 8], 7 , 1770035416);
- d = md5_ff(d, a, b, c, x[i+ 9], 12, -1958414417);
- c = md5_ff(c, d, a, b, x[i+10], 17, -42063);
- b = md5_ff(b, c, d, a, x[i+11], 22, -1990404162);
- a = md5_ff(a, b, c, d, x[i+12], 7 , 1804603682);
- d = md5_ff(d, a, b, c, x[i+13], 12, -40341101);
- c = md5_ff(c, d, a, b, x[i+14], 17, -1502002290);
- b = md5_ff(b, c, d, a, x[i+15], 22, 1236535329);
-
- a = md5_gg(a, b, c, d, x[i+ 1], 5 , -165796510);
- d = md5_gg(d, a, b, c, x[i+ 6], 9 , -1069501632);
- c = md5_gg(c, d, a, b, x[i+11], 14, 643717713);
- b = md5_gg(b, c, d, a, x[i+ 0], 20, -373897302);
- a = md5_gg(a, b, c, d, x[i+ 5], 5 , -701558691);
- d = md5_gg(d, a, b, c, x[i+10], 9 , 38016083);
- c = md5_gg(c, d, a, b, x[i+15], 14, -660478335);
- b = md5_gg(b, c, d, a, x[i+ 4], 20, -405537848);
- a = md5_gg(a, b, c, d, x[i+ 9], 5 , 568446438);
- d = md5_gg(d, a, b, c, x[i+14], 9 , -1019803690);
- c = md5_gg(c, d, a, b, x[i+ 3], 14, -187363961);
- b = md5_gg(b, c, d, a, x[i+ 8], 20, 1163531501);
- a = md5_gg(a, b, c, d, x[i+13], 5 , -1444681467);
- d = md5_gg(d, a, b, c, x[i+ 2], 9 , -51403784);
- c = md5_gg(c, d, a, b, x[i+ 7], 14, 1735328473);
- b = md5_gg(b, c, d, a, x[i+12], 20, -1926607734);
-
- a = md5_hh(a, b, c, d, x[i+ 5], 4 , -378558);
- d = md5_hh(d, a, b, c, x[i+ 8], 11, -2022574463);
- c = md5_hh(c, d, a, b, x[i+11], 16, 1839030562);
- b = md5_hh(b, c, d, a, x[i+14], 23, -35309556);
- a = md5_hh(a, b, c, d, x[i+ 1], 4 , -1530992060);
- d = md5_hh(d, a, b, c, x[i+ 4], 11, 1272893353);
- c = md5_hh(c, d, a, b, x[i+ 7], 16, -155497632);
- b = md5_hh(b, c, d, a, x[i+10], 23, -1094730640);
- a = md5_hh(a, b, c, d, x[i+13], 4 , 681279174);
- d = md5_hh(d, a, b, c, x[i+ 0], 11, -358537222);
- c = md5_hh(c, d, a, b, x[i+ 3], 16, -722521979);
- b = md5_hh(b, c, d, a, x[i+ 6], 23, 76029189);
- a = md5_hh(a, b, c, d, x[i+ 9], 4 , -640364487);
- d = md5_hh(d, a, b, c, x[i+12], 11, -421815835);
- c = md5_hh(c, d, a, b, x[i+15], 16, 530742520);
- b = md5_hh(b, c, d, a, x[i+ 2], 23, -995338651);
-
- a = md5_ii(a, b, c, d, x[i+ 0], 6 , -198630844);
- d = md5_ii(d, a, b, c, x[i+ 7], 10, 1126891415);
- c = md5_ii(c, d, a, b, x[i+14], 15, -1416354905);
- b = md5_ii(b, c, d, a, x[i+ 5], 21, -57434055);
- a = md5_ii(a, b, c, d, x[i+12], 6 , 1700485571);
- d = md5_ii(d, a, b, c, x[i+ 3], 10, -1894986606);
- c = md5_ii(c, d, a, b, x[i+10], 15, -1051523);
- b = md5_ii(b, c, d, a, x[i+ 1], 21, -2054922799);
- a = md5_ii(a, b, c, d, x[i+ 8], 6 , 1873313359);
- d = md5_ii(d, a, b, c, x[i+15], 10, -30611744);
- c = md5_ii(c, d, a, b, x[i+ 6], 15, -1560198380);
- b = md5_ii(b, c, d, a, x[i+13], 21, 1309151649);
- a = md5_ii(a, b, c, d, x[i+ 4], 6 , -145523070);
- d = md5_ii(d, a, b, c, x[i+11], 10, -1120210379);
- c = md5_ii(c, d, a, b, x[i+ 2], 15, 718787259);
- b = md5_ii(b, c, d, a, x[i+ 9], 21, -343485551);
-
- a = safe_add(a, olda);
- b = safe_add(b, oldb);
- c = safe_add(c, oldc);
- d = safe_add(d, oldd);
- }
- return [a, b, c, d];
- }
-
- /*
- * These functions implement the four basic operations the algorithm uses.
- */
- public static function md5_cmn (q:Number, a:Number, b:Number, x:Number, s:Number, t:Number):Number {
- return safe_add (bit_rol (safe_add (safe_add (a, q), safe_add(x, t)), s), b);
- }
- public static function md5_ff (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
- return md5_cmn ((b & c) | ((~b) & d), a, b, x, s, t);
- }
- public static function md5_gg (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
- return md5_cmn ((b & d) | (c & (~d)), a, b, x, s, t);
- }
- public static function md5_hh (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
- return md5_cmn (b ^ c ^ d, a, b, x, s, t);
- }
- public static function md5_ii (a:Number, b:Number, c:Number, d:Number, x:Number, s:Number, t:Number):Number {
- return md5_cmn (c ^ (b | (~d)), a, b, x, s, t);
- }
-
- /*
- * Add integers, wrapping at 2^32. This uses 16-bit operations internally
- * to work around bugs in some JS interpreters.
- */
- public static function safe_add (x:Number, y:Number):Number {
- var lsw:Number = (x & 0xFFFF) + (y & 0xFFFF);
- var msw:Number = (x >> 16) + (y >> 16) + (lsw >> 16);
- return (msw << 16) | (lsw & 0xFFFF);
- }
-
- /*
- * Bitwise rotate a 32-bit number to the left.
- */
- public static function bit_rol (num:Number, cnt:Number):Number {
- return (num << cnt) | (num >>> (32 - cnt));
- }
-
- }
-}
diff --git a/include/web-socket-js/flash-src/com/hurlant b/include/web-socket-js/flash-src/com/hurlant
deleted file mode 120000
index f9f4c84c..00000000
--- a/include/web-socket-js/flash-src/com/hurlant
+++ /dev/null
@@ -1 +0,0 @@
-../../../as3crypto_patched/src/com/hurlant
\ No newline at end of file
diff --git a/include/web-socket-js/sample.html b/include/web-socket-js/sample.html
deleted file mode 100644
index ac9ca01a..00000000
--- a/include/web-socket-js/sample.html
+++ /dev/null
@@ -1,74 +0,0 @@
-
-
-
-
- Sample of web_socket.js
-
-
-
-
-
-
-
-
-
-
-
diff --git a/include/web-socket-js/web_socket.js b/include/web-socket-js/web_socket.js
index 5b0afc16..ad65dd1b 100755
--- a/include/web-socket-js/web_socket.js
+++ b/include/web-socket-js/web_socket.js
@@ -10,123 +10,103 @@
var console = window.console;
if (!console) console = {log: function(){ }, error: function(){ }};
- function hasFlash() {
- if ('navigator' in window && 'plugins' in navigator && navigator.plugins['Shockwave Flash']) {
- return !!navigator.plugins['Shockwave Flash'].description;
- }
- if ('ActiveXObject' in window) {
- try {
- return !!new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
- } catch (e) {}
- }
- return false;
- }
-
- if (!hasFlash()) {
+ if (!swfobject.hasFlashPlayerVersion("9.0.0")) {
console.error("Flash Player is not installed.");
return;
}
+ if (location.protocol == "file:") {
+ console.error(
+ "WARNING: web-socket-js doesn't work in file:///... URL " +
+ "unless you set Flash Security Settings properly. " +
+ "Open the page via Web server i.e. http://...");
+ }
WebSocket = function(url, protocol, proxyHost, proxyPort, headers) {
var self = this;
self.readyState = WebSocket.CONNECTING;
self.bufferedAmount = 0;
- WebSocket.__addTask(function() {
- self.__flash =
- WebSocket.__flash.create(url, protocol, proxyHost || null, proxyPort || 0, headers || null);
-
- self.__messageHandler = function() {
- var i, arr, data;
- arr = self.__flash.readSocketData();
- for (i=0; i < arr.length; i++) {
- data = decodeURIComponent(arr[i]);
- try {
- if (self.onmessage) {
- var e;
- if (window.MessageEvent) {
- e = document.createEvent("MessageEvent");
- e.initMessageEvent("message", false, false, data, null, null, window, null);
- } else { // IE
- e = {data: data};
- }
- self.onmessage(e);
- }
- } catch (e) {
- console.error(e.toString());
- }
- }
- };
-
- self.__flash.addEventListener("open", function(fe) {
- self.readyState = self.__flash.getReadyState();
-
- // For browsers (like Opera) that drop events, also poll for
- // message data
- if (self.__messageHandlerID) {
- clearInterval(self.__messageHandlerID);
- }
- self.__messageHandlerID = setInterval(function () {
- //console.log("polling for message data");
- self.__messageHandler; }, 500);
-
- try {
- if (self.onopen) {
- self.onopen();
- } else {
- // If "open" comes back in the same thread, then the
- // caller will not have set the onopen handler yet.
- setTimeout(function () {
- if (self.onopen) { self.onopen(); } }, 10);
- }
- } catch (e) {
- console.error(e.toString());
- }
+ // Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc.
+ // Otherwise, when onopen fires immediately, onopen is called before it is set.
+ setTimeout(function() {
+ WebSocket.__addTask(function() {
+ self.__createFlash(url, protocol, proxyHost, proxyPort, headers);
});
-
- self.__flash.addEventListener("close", function(fe) {
- self.readyState = self.__flash.getReadyState();
-
- if (self.__messageHandlerID) {
- clearInterval(self.__messageHandlerID);
- }
- try {
- if (self.onclose) self.onclose();
- } catch (e) {
- console.error(e.toString());
- }
- });
-
- self.__flash.addEventListener("message", self.__messageHandler);
-
- self.__flash.addEventListener("error", function(fe) {
- if (self.__messageHandlerID) {
- clearInterval(self.__messageHandlerID);
- }
- try {
- if (self.onerror) self.onerror();
- } catch (e) {
- console.error(e.toString());
- }
- });
-
- self.__flash.addEventListener("stateChange", function(fe) {
- try {
- self.readyState = fe.getReadyState();
- self.bufferedAmount = fe.getBufferedAmount();
- } catch (e) {
- console.error(e.toString());
- }
- });
-
- //console.log("[WebSocket] Flash object is ready");
- });
+ }, 1);
}
+
+ WebSocket.prototype.__createFlash = function(url, protocol, proxyHost, proxyPort, headers) {
+ var self = this;
+ self.__flash =
+ WebSocket.__flash.create(url, protocol, proxyHost || null, proxyPort || 0, headers || null);
+
+ self.__flash.addEventListener("open", function(fe) {
+ try {
+ self.readyState = self.__flash.getReadyState();
+ if (self.__timer) clearInterval(self.__timer);
+ if (window.opera) {
+ // Workaround for weird behavior of Opera which sometimes drops events.
+ self.__timer = setInterval(function () {
+ self.__handleMessages();
+ }, 500);
+ }
+ if (self.onopen) self.onopen();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
+
+ self.__flash.addEventListener("close", function(fe) {
+ try {
+ self.readyState = self.__flash.getReadyState();
+ if (self.__timer) clearInterval(self.__timer);
+ if (self.onclose) self.onclose();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
+
+ self.__flash.addEventListener("message", function() {
+ try {
+ self.__handleMessages();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
+
+ self.__flash.addEventListener("error", function(fe) {
+ try {
+ if (self.__timer) clearInterval(self.__timer);
+ if (self.onerror) self.onerror();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
+
+ self.__flash.addEventListener("stateChange", function(fe) {
+ try {
+ self.readyState = self.__flash.getReadyState();
+ self.bufferedAmount = fe.getBufferedAmount();
+ } catch (e) {
+ console.error(e.toString());
+ }
+ });
+
+ //console.log("[WebSocket] Flash object is ready");
+ };
WebSocket.prototype.send = function(data) {
- this.readyState = this.__flash.getReadyState();
+ if (this.__flash) {
+ this.readyState = this.__flash.getReadyState();
+ }
if (!this.__flash || this.readyState == WebSocket.CONNECTING) {
throw "INVALID_STATE_ERR: Web Socket connection has not been established";
}
+ // We use encodeURIComponent() here, because FABridge doesn't work if
+ // the argument includes some characters. We don't use escape() here
+ // because of this:
+ // https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#escape_and_unescape_Functions
+ // But it looks decodeURIComponent(encodeURIComponent(s)) doesn't
+ // preserve all Unicode characters either e.g. "\uffff" in Firefox.
var result = this.__flash.send(encodeURIComponent(data));
if (result < 0) { // success
return true;
@@ -145,9 +125,7 @@
// which causes weird error:
// > You are trying to call recursively into the Flash Player which is not allowed.
this.readyState = WebSocket.CLOSED;
- if (this.__messageHandlerID) {
- clearInterval(this.__messageHandlerID);
- }
+ if (this.__timer) clearInterval(this.__timer);
if (this.onclose) this.onclose();
};
@@ -167,7 +145,7 @@
this.__events[type] = [];
if ('function' == typeof this['on' + type]) {
this.__events[type].defaultHandler = this['on' + type];
- this['on' + type] = WebSocket_FireEvent(this, type);
+ this['on' + type] = this.__createEventHandler(this, type);
}
}
this.__events[type].push(listener);
@@ -216,12 +194,35 @@
}
};
+ WebSocket.prototype.__handleMessages = function() {
+ // Gets data using readSocketData() instead of getting it from event object
+ // of Flash event. This is to make sure to keep message order.
+ // It seems sometimes Flash events don't arrive in the same order as they are sent.
+ var arr = this.__flash.readSocketData();
+ for (var i = 0; i < arr.length; i++) {
+ var data = decodeURIComponent(arr[i]);
+ try {
+ if (this.onmessage) {
+ var e;
+ if (window.MessageEvent) {
+ e = document.createEvent("MessageEvent");
+ e.initMessageEvent("message", false, false, data, null, null, window, null);
+ } else { // IE
+ e = {data: data};
+ }
+ this.onmessage(e);
+ }
+ } catch (e) {
+ console.error(e.toString());
+ }
+ }
+ };
+
/**
- *
* @param {object} object
* @param {string} type
*/
- function WebSocket_FireEvent(object, type) {
+ WebSocket.prototype.__createEventHandler = function(object, type) {
return function(data) {
var event = new WebSocketEvent();
event.initEvent(type, true, true);
@@ -293,27 +294,39 @@
WebSocket.__tasks = [];
WebSocket.__initialize = function() {
- if (WebSocket__swfLocation) {
- WebSocket.__swfLocation = WebSocket__swfLocation;
+ if (WebSocket.__swfLocation) {
+ // For backword compatibility.
+ window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
}
- if (!WebSocket.__swfLocation) {
- console.error("[WebSocket] set WebSocket.__swfLocation to location of WebSocketMain.swf");
+ if (!window.WEB_SOCKET_SWF_LOCATION) {
+ console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
return;
}
var container = document.createElement("div");
container.id = "webSocketContainer";
- // Puts the Flash out of the window. Note that we cannot use display: none or visibility: hidden
- // here because it prevents Flash from loading at least in IE.
+ // Hides Flash box. We cannot use display: none or visibility: hidden because it prevents
+ // Flash from loading at least in IE. So we move it out of the screen at (-100, -100).
+ // But this even doesn't work with Flash Lite (e.g. in Droid Incredible). So with Flash
+ // Lite, we put it at (0, 0). This shows 1x1 box visible at left-top corner but this is
+ // the best we can do as far as we know now.
container.style.position = "absolute";
- container.style.left = "-100px";
- container.style.top = "-100px";
+ if (WebSocket.__isFlashLite()) {
+ container.style.left = "0px";
+ container.style.top = "0px";
+ } else {
+ container.style.left = "-100px";
+ container.style.top = "-100px";
+ }
var holder = document.createElement("div");
holder.id = "webSocketFlash";
container.appendChild(holder);
document.body.appendChild(container);
+ // See this article for hasPriority:
+ // http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html
swfobject.embedSWF(
- WebSocket.__swfLocation, "webSocketFlash", "8", "8", "9.0.0",
- null, {bridgeName: "webSocket"}, null, null,
+ WEB_SOCKET_SWF_LOCATION, "webSocketFlash",
+ "1" /* width */, "1" /* height */, "9.0.0" /* SWF version */,
+ null, {bridgeName: "webSocket"}, {hasPriority: true, allowScriptAccess: "always"}, null,
function(e) {
if (!e.success) console.error("[WebSocket] swfobject.embedSWF failed");
}
@@ -323,7 +336,7 @@
//console.log("[WebSocket] FABridge initializad");
WebSocket.__flash = FABridge.webSocket.root();
WebSocket.__flash.setCallerUrl(location.href);
- WebSocket.__flash.setDebug(!!WebSocket.__debug);
+ WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
for (var i = 0; i < WebSocket.__tasks.length; ++i) {
WebSocket.__tasks[i]();
}
@@ -340,7 +353,14 @@
} else {
WebSocket.__tasks.push(task);
}
- }
+ };
+
+ WebSocket.__isFlashLite = function() {
+ if (!window.navigator || !window.navigator.mimeTypes) return false;
+ var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"];
+ if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) return false;
+ return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false;
+ };
// called from Flash
window.webSocketLog = function(message) {
@@ -352,7 +372,7 @@
console.error(decodeURIComponent(message));
};
- if (!WebSocket.__disableAutoInitialization) {
+ if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) {
if (window.addEventListener) {
window.addEventListener("load", WebSocket.__initialize, false);
} else {