diff --git a/AD_LICENSE b/AD_LICENSE index 652c4c2..191c4d2 100644 --- a/AD_LICENSE +++ b/AD_LICENSE @@ -4,3 +4,4 @@ * license: MIT license * link: http://stackoverflow.com/questions/105034/how-to-create-a-guid-uuid-in-javascript/21963136#21963136 **/ +/** @license zlib.js 2012 - imaya [ https://github.com/imaya/zlib.js ] The MIT License */ diff --git a/botanjs/service/jclassresv.py b/botanjs/service/jclassresv.py index acd30ea..536c2d6 100644 --- a/botanjs/service/jclassresv.py +++ b/botanjs/service/jclassresv.py @@ -1,9 +1,4 @@ - -import os -import re -import base64 -import zlib -import hashlib +import os, re, base64, zlib, hashlib, binascii import xml.etree.ElementTree as ET PY_SEP = os.path.sep @@ -200,7 +195,7 @@ class BotanClassResolver: # Root file date dates.append( os.path.getmtime( os.path.join( self.R, "_this.js" ) ) ); - if self.useCache( cFile, dates ) and self.flagCompress == True: + if self.flagCompress and self.useCache( cFile, dates ): return cFHash if self.returnHash else self.BotanCache( cFile ) elif self.useCache( oFile, dates ): @@ -303,7 +298,6 @@ class BotanClassResolver: self.resv._reload() flag = mode[0] requestAPIs = code - sp = "/" if flag == "o": mode = mode[1:] @@ -312,12 +306,16 @@ class BotanClassResolver: self.flagCompress = False else: self.returnHash = True + + try: requestAPIs = ( # decode -> decompress -> split zlib.decompress( base64.b64decode( code, None, True ) ) .decode( "utf-8" ) ) sp = "," + except binascii.Error: + sp = "/" # strip malicious requestAPIs = ( diff --git a/botanjs/service/webapi.py b/botanjs/service/webapi.py index 08b238d..54a62ea 100755 --- a/botanjs/service/webapi.py +++ b/botanjs/service/webapi.py @@ -2,6 +2,7 @@ from flask import Flask from flask import Response from flask import render_template +from flask import request from botanjs.service.jclassresv import BotanClassResolver as JCResv from botanjs.service.jwork import app as CeleryApp, JWork from botanjs.config import Config, DEBUG @@ -25,12 +26,12 @@ class WebAPI: if brokerURL != None: CeleryApp.conf.update( BROKER_URL = brokerURL ) - print( __name__ ) self.app = Flask( __name__, static_url_path = self.BCache, static_folder = self.BCache ) self.app.jinja_env.add_extension( "compressinja.html.HtmlCompressor" ) self.app.add_url_rule( "/" , view_func = self.index ) - self.app.add_url_rule( "//" , view_func = self.api_request ) + self.app.add_url_rule( "//" , view_func = lambda mode: self.api_request( mode, "zpayload" ) ) + self.app.add_url_rule( "//" , view_func = self.api_request ) self.app.run( host = Config[ "Service" ][ "BindAddress" ] @@ -41,6 +42,10 @@ class WebAPI: return "Hello, this is the BotanJS Service API.", 200 def api_request( self, mode, code ): + + if code == "zpayload": + code = request.args.get( "p" ) + try: t = mode[1:] if t == "js": diff --git a/botanjs/src/System/Compression/Zlib.js b/botanjs/src/System/Compression/Zlib.js new file mode 100644 index 0000000..a321853 --- /dev/null +++ b/botanjs/src/System/Compression/Zlib.js @@ -0,0 +1,34 @@ +(function() { + 'use strict'; + var ns = __namespace( "System.Compression.Zlib" ); + + // From github imaya/zlib.js + // aa is the scope + var n=void 0,w=!0,aa={}; + var ba = function(f,d){ + var c=f.split("."),e=aa; + !(c[0]in e) && e.execScript&&e.execScript("var "+c[0]); + for(var b;c.length&&(b=c.shift());) + !c.length&&d!==n?e[b]=d:e=e[b]?e[b]:e[b]={} + }; + var C="undefined"!==typeof Uint8Array&&"undefined"!==typeof Uint16Array&&"undefined"!==typeof Uint32Array&&"undefined"!==typeof DataView;function K(f,d){this.index="number"===typeof d?d:0;this.e=0;this.buffer=f instanceof(C?Uint8Array:Array)?f:new (C?Uint8Array:Array)(32768);if(2*this.buffer.length<=this.index)throw Error("invalid index");this.buffer.length<=this.index&&ca(this)}function ca(f){var d=f.buffer,c,e=d.length,b=new (C?Uint8Array:Array)(e<<1);if(C)b.set(d);else for(c=0;c>>8&255]<<16|L[f>>>16&255]<<8|L[f>>>24&255])>>32-d:L[f]>>8-d);if(8>d+a)g=g<>d-m-1&1,8===++a&&(a=0,e[b++]=L[g],g=0,b===e.length&&(e=ca(this)));e[b]=g;this.buffer=e;this.e=a;this.index=b};K.prototype.finish=function(){var f=this.buffer,d=this.index,c;0M;++M){for(var N=M,S=N,ea=7,N=N>>>1;N;N>>>=1)S<<=1,S|=N&1,--ea;da[M]=(S<>>0}var L=da;function ia(f){this.buffer=new (C?Uint16Array:Array)(2*f);this.length=0}ia.prototype.getParent=function(f){return 2*((f-2)/4|0)};ia.prototype.push=function(f,d){var c,e,b=this.buffer,a;c=this.length;b[this.length++]=d;for(b[this.length++]=f;0b[e])a=b[c],b[c]=b[e],b[e]=a,a=b[c+1],b[c+1]=b[e+1],b[e+1]=a,c=e;else break;return this.length}; + ia.prototype.pop=function(){var f,d,c=this.buffer,e,b,a;d=c[0];f=c[1];this.length-=2;c[0]=c[this.length];c[1]=c[this.length+1];for(a=0;;){b=2*a+2;if(b>=this.length)break;b+2c[b]&&(b+=2);if(c[b]>c[a])e=c[a],c[a]=c[b],c[b]=e,e=c[a+1],c[a+1]=c[b+1],c[b+1]=e;else break;a=b}return{index:f,value:d,length:this.length}};function ka(f,d){this.d=la;this.i=0;this.input=C&&f instanceof Array?new Uint8Array(f):f;this.c=0;d&&(d.lazy&&(this.i=d.lazy),"number"===typeof d.compressionType&&(this.d=d.compressionType),d.outputBuffer&&(this.a=C&&d.outputBuffer instanceof Array?new Uint8Array(d.outputBuffer):d.outputBuffer),"number"===typeof d.outputIndex&&(this.c=d.outputIndex));this.a||(this.a=new (C?Uint8Array:Array)(32768))}var la=2,na={NONE:0,h:1,g:la,n:3},T=[],U; + for(U=0;288>U;U++)switch(w){case 143>=U:T.push([U+48,8]);break;case 255>=U:T.push([U-144+400,9]);break;case 279>=U:T.push([U-256+0,7]);break;case 287>=U:T.push([U-280+192,8]);break;default:throw"invalid literal: "+U;} + ka.prototype.f=function(){var f,d,c,e,b=this.input;switch(this.d){case 0:c=0;for(e=b.length;c>>8&255;l[h++]=p&255;l[h++]=p>>>8&255;if(C)l.set(a,h),h+=a.length,l=l.subarray(0,h);else{t=0;for(u=a.length;tv)for(;0v?v:138,A>v-3&&A=A?(E[D++]=17,E[D++]=A-3,H[17]++):(E[D++]=18,E[D++]=A-11,H[18]++),v-=A;else if(E[D++]=F[r],H[F[r]]++,v--,3>v)for(;0v?v:6,A>v-3&&Ay;y++)ja[y]=ga[La[y]];for(Q=19;4=b:return[265,b-11,1];case 14>=b:return[266,b-13,1];case 16>=b:return[267,b-15,1];case 18>=b:return[268,b-17,1];case 22>=b:return[269,b-19,2];case 26>=b:return[270,b-23,2];case 30>=b:return[271,b-27,2];case 34>=b:return[272,b-31,2];case 42>=b:return[273,b-35,3];case 50>=b:return[274,b-43,3];case 58>=b:return[275,b-51,3];case 66>=b:return[276,b-59,3];case 82>=b:return[277,b-67,4];case 98>=b:return[278,b-83,4];case 114>=b:return[279,b-99,4];case 130>=b:return[280,b-115,4];case 162>=b:return[281,b-131,5];case 194>=b:return[282,b-163,5];case 226>=b:return[283,b-195,5];case 257>=b:return[284,b-227,5];case 258===b:return[285,b-258,0];default:throw"invalid length: "+b;}}var d=[],c,e;for(c=3;258>=c;c++)e=f(c),d[c]=e[2]<<24|e[1]<<16|e[0];return d}(),Ha=C?new Uint32Array(sa):sa; + function oa(f,d){function c(b,c){var a=b.k,d=[],e=0,f;f=Ha[b.length];d[e++]=f&65535;d[e++]=f>>16&255;d[e++]=f>>24;var g;switch(w){case 1===a:g=[0,a-1,0];break;case 2===a:g=[1,a-2,0];break;case 3===a:g=[2,a-3,0];break;case 4===a:g=[3,a-4,0];break;case 6>=a:g=[4,a-5,1];break;case 8>=a:g=[5,a-7,1];break;case 12>=a:g=[6,a-9,2];break;case 16>=a:g=[7,a-13,2];break;case 24>=a:g=[8,a-17,3];break;case 32>=a:g=[9,a-25,3];break;case 48>=a:g=[10,a-33,4];break;case 64>=a:g=[11,a-49,4];break;case 96>=a:g=[12,a-65,5];break;case 128>=a:g=[13,a-97,5];break;case 192>=a:g=[14,a-129,6];break;case 256>=a:g=[15,a-193,6];break;case 384>=a:g=[16,a-257,7];break;case 512>=a:g=[17,a-385,7];break;case 768>=a:g=[18,a-513,8];break;case 1024>=a:g=[19,a-769,8];break;case 1536>=a:g=[20,a-1025,9];break;case 2048>=a:g=[21,a-1537,9];break;case 3072>=a:g=[22,a-2049,10];break;case 4096>=a:g=[23,a-3073,10];break;case 6144>=a:g=[24,a-4097,11];break;case 8192>=a:g=[25,a-6145,11];break;case 12288>=a:g=[26,a-8193,12];break;case 16384>=a:g=[27,a-12289,12];break;case 24576>=a:g=[28,a-16385,13];break;case 32768>=a:g=[29,a-24577,13];break;default:throw"invalid distance";}f=g;d[e++]=f[0];d[e++]=f[1];d[e++]=f[2];var k,m;k=0;for(m=d.length;k=a;)s[a++]=0;for(a=0;29>=a;)x[a++]=0}s[256]=1;e=0;for(b=d.length;e=b){u&&c(u,-1);a=0;for(g=b-e;ag&&d+ga&&(b=e,a=g);if(258===g)break}return new ra(a,d-b)} + function pa(f,d){var c=f.length,e=new ia(572),b=new (C?Uint8Array:Array)(c),a,g,m,k,p;if(!C)for(k=0;k2*b[h-1]+a[h]&&(b[h]=2*b[h-1]+a[h]),m[h]=Array(b[h]),k[h]=Array(b[h]);for(l=0;lf[l]?(m[h][q]=s,k[h][q]=d,x+=2):(m[h][q]=f[l],k[h][q]=l,++l);p[h]=0;1===a[h]&&e(h)}return g} + function qa(f){var d=new (C?Uint16Array:Array)(f.length),c=[],e=[],b=0,a,g,m,k;a=0;for(g=f.length;a>>=1}return d};function Ka(f,d){this.input=f;this.a=new (C?Uint8Array:Array)(32768);this.d=V.g;var c={},e;if((d||!(d={}))&&"number"===typeof d.compressionType)this.d=d.compressionType;for(e in d)c[e]=d[e];c.outputBuffer=this.a;this.j=new ka(this.input,c)}var V=na;Ka.prototype.f=function(){var f,d,c,e,b,a,g=0;a=this.a;switch(8){case 8:f=Math.LOG2E*Math.log(32768)-8;break;default:throw Error("invalid compression method");}d=f<<4|8;a[g++]=d;switch(8){case 8:switch(this.d){case V.NONE:e=0;break;case V.h:e=1;break;case V.g:e=2;break;default:throw Error("unsupported compression type");}break;default:throw Error("invalid compression method");}c=e<<6|0;a[g++]=c|31-(256*d+c)%31;var m=this.input;if("string"===typeof m){var k=m.split(""),p,t;p=0;for(t=k.length;p>>0;m=k}for(var u=1,l=0,h=m.length,q,s=0;0>>0;this.j.c=g;a=this.j.f();g=a.length;C&&(a=new Uint8Array(a.buffer),a.length<=g+4&&(this.a=new Uint8Array(a.length+4),this.a.set(a),a=this.a),a=a.subarray(0,g+4));a[g++]=b>>24&255;a[g++]=b>>16&255;a[g++]=b>>8&255;a[g++]=b&255;return a};ba("Deflate",Ka);ba("Deflate.compress",function(f,d){return(new Ka(f,d)).f()});ba("Deflate.prototype.compress",Ka.prototype.f);var Ma={NONE:V.NONE,FIXED:V.h,DYNAMIC:V.g},Na,Oa,W,Pa;if(Object.keys)Na=Object.keys(Ma);else for(Oa in Na=[],W=0,Ma)Na[W++]=Oa;W=0;for(Pa=Na.length;W> 6) | 192; + out[p++] = (c & 63) | 128; + } else if ( + ((c & 0xFC00) == 0xD800) && (i + 1) < str.length && + ((str.charCodeAt(i + 1) & 0xFC00) == 0xDC00)) { + // Surrogate Pair + c = 0x10000 + ((c & 0x03FF) << 10) + (str.charCodeAt(++i) & 0x03FF); + out[p++] = (c >> 18) | 240; + out[p++] = ((c >> 12) & 63) | 128; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; + } else { + out[p++] = (c >> 12) | 224; + out[p++] = ((c >> 6) & 63) | 128; + out[p++] = (c & 63) | 128; + } + } + return out; + }; + + ns[ NS_EXPORT ]( EX_FUNC, "Encode", Encode ); + +})(); diff --git a/botanjs/src/System/Encoding/_this.js b/botanjs/src/System/Encoding/_this.js new file mode 100644 index 0000000..33bddc4 --- /dev/null +++ b/botanjs/src/System/Encoding/_this.js @@ -0,0 +1,3 @@ +(function(){ + var ns = __namespace( "System.Encoding" ); +})(); diff --git a/botanjs/src/System/Net/ClassLoader.js b/botanjs/src/System/Net/ClassLoader.js index d81175b..6139a5b 100644 --- a/botanjs/src/System/Net/ClassLoader.js +++ b/botanjs/src/System/Net/ClassLoader.js @@ -1,17 +1,22 @@ (function(){ var ns = __namespace( "System.Net" ); - var className = "ClassLoader"; /** @type {System.utils} */ var utils = __import( "System.utils" ); /** @type {System.utils.IKey} */ var IKey = __import( "System.utils.IKey" ); + /** @type {System.Encoding.CodePage} */ + var Utf8 = __import( "System.Encoding.Utf8" ); + /** @type {System.Encoding.CodePage} */ + var Base64 = __import( "System.Encoding.Base64" ); /** @type {Dandelion} */ var Dand = __import( "Dandelion" ); + var Deflate = __import( "System.Compression.Zlib.Deflate" ); + var LoadedClasses = {}; - var loadFile = function ( sapi, request, mode ) + var loadFile = function ( sapi, payload, mode ) { var head = Dand.tag( "head" )[0]; @@ -22,7 +27,7 @@ , IKey.quickDef( "rel", "stylesheet" , "type", "text/css" - , "href", sapi + mode + "css/" + request + , "href", sapi + mode + "css/?p=" + payload ) ) ); @@ -33,7 +38,7 @@ "script" , IKey.quickDef( "type", "text/javascript" - , "src", sapi + mode + "js/" + request + , "src", sapi + mode + "js/?p=" + payload ) ) ); @@ -42,7 +47,7 @@ var Loader = function( sapi, mode ) { - mode = ( mode === undefined ) ? "o" : mode; + mode = ( mode === undefined ) ? "" : mode; this.load = function( classes, handler ) { @@ -75,18 +80,14 @@ // Excludes utils.objMap( excludes , function( v ) { return "-" + v; } ); - var loadc = null; - var sp = mode ? { 'o': '/', 'r': '/' }[ mode ] : ','; + // Compile the payload + var payload = needed.join( ',' ) + ',' + excludes.join( ',' ); + payload = encodeURIComponent( Base64.Encode( Deflate( Utf8.Encode( payload ) ) ) ); - loadFile( - sapi - , needed.join( sp ) + sp + excludes.join( sp ) - , mode - ); + loadFile( sapi, payload, mode ); BotanJS.addEventListener( "NS_INIT", onLoad ); - BotanJS.addEventListener( "NS_EXPORT", function( e ) { if( e.data.name ) diff --git a/botanjs/src/System/_this.js b/botanjs/src/System/_this.js index 4801f9e..e7164ce 100644 --- a/botanjs/src/System/_this.js +++ b/botanjs/src/System/_this.js @@ -1,3 +1,3 @@ (function(){ - var ns = __namespace( "System" ) + var ns = __namespace( "System" ); })(); diff --git a/botanjs/src/_this.js b/botanjs/src/_this.js index cfb3b66..eeade27 100644 --- a/botanjs/src/_this.js +++ b/botanjs/src/_this.js @@ -309,13 +309,13 @@ __import = __import || function( ns, noCache ) { if( wildcard && j[0] == EX_CLASS ) { - nsObj[ i ] = j[1]; + __const( nsObj, i, j[1] ); } else if( j[0] == EX_FUNC ) { - nsObj[ i ] = j[1]; + __const( nsObj, i, j[1] ); } - else if( j[0] == EX_CONST ) + else if( j[0] == EX_CONST ) { Object.defineProperty( nsObj, i, { get: function() { @@ -326,7 +326,7 @@ __import = __import || function( ns, noCache ) }.bind( { p: i } ) }); } - else if( j[0] == EX_VAR ) + else if( j[0] == EX_VAR ) { Object.defineProperty( nsObj, i, { get: function() { @@ -347,6 +347,11 @@ __import = __import || function( ns, noCache ) }); } } + // import the namespace + else if( wildcard && j.__TRIGGERS ) + { + __const( nsObj, i, __import( nss + "." + i ) ); + } } _cacheIMP[ ns ] = nsObj; diff --git a/botanjs/src/externs/System.Compression.Zlib.js b/botanjs/src/externs/System.Compression.Zlib.js new file mode 100644 index 0000000..2af8e60 --- /dev/null +++ b/botanjs/src/externs/System.Compression.Zlib.js @@ -0,0 +1,8 @@ +/** @type {constructor} */ +System.Compression.Zlib = function(){}; + +/** @type {constructor} */ +System.Compression.Zlib.Deflate = function(){}; + +/** @type {Function} */ +System.Compression.Zlib.Deflate.compress; diff --git a/botanjs/src/externs/System.Compression.js b/botanjs/src/externs/System.Compression.js new file mode 100644 index 0000000..69a378c --- /dev/null +++ b/botanjs/src/externs/System.Compression.js @@ -0,0 +1,2 @@ +/** @constructor */ +System.Compression = function(){}; diff --git a/botanjs/src/externs/System.Encoding.Base64.js b/botanjs/src/externs/System.Encoding.Base64.js new file mode 100644 index 0000000..2a97c53 --- /dev/null +++ b/botanjs/src/externs/System.Encoding.Base64.js @@ -0,0 +1,4 @@ +/** @type {Function} */ +System.Encoding.Base64 = function(){}; +/** @type {Function} */ +System.Encoding.Base64.Encode = function(){}; diff --git a/botanjs/src/externs/System.Encoding.Utf8.js b/botanjs/src/externs/System.Encoding.Utf8.js new file mode 100644 index 0000000..1f8a650 --- /dev/null +++ b/botanjs/src/externs/System.Encoding.Utf8.js @@ -0,0 +1,4 @@ +/** @type {Function} */ +System.Encoding.Utf8 = function(){}; +/** @type {Function} */ +System.Encoding.Utf8.Encode = function(){}; diff --git a/botanjs/src/externs/System.Encoding.js b/botanjs/src/externs/System.Encoding.js new file mode 100644 index 0000000..eeef902 --- /dev/null +++ b/botanjs/src/externs/System.Encoding.js @@ -0,0 +1,2 @@ +/** @constructor */ +System.Encoding = function(){};