// https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108 // X:\jsc.svn\examples\javascript\android\com.abstractatech.appmanager\com.abstractatech.appmanager\Application.cs // tested by // X:\jsc.svn\examples\javascript\android\com.abstractatech.adminshell\com.abstractatech.adminshell\Application.cs //02000066 ScriptCoreLib.JavaScript.Experimental.X+<>c__DisplayClassc+<<GetAwaiter>b__7>d__11 //script: error JSC1000: if block not detected correctly, opcode was { Branch = [0x0020] beq +0 -2{[0x0019] ldfld +1 -1{[0x0018] ldarg.0 +1 -0} } {[0x001e] ldc.i4.s +1 -0} , Location = // assembly: T:\com.abstractatech.adminshell.Application.exe // type: ScriptCoreLib.JavaScript.Experimental.X+<>c__DisplayClassc+<<GetAwaiter>b__7>d__11, com.abstractatech.adminshell.Application, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null // offset: 0x0020 // method:Int32 <>02000019<>06000044<>MoveNext<0000>.try(<>02000019<>06000044<>MoveNext, <<GetAwaiter>b__7>d__11 ByRef, System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]] ByRef, System.Runtime.CompilerServices.TaskAwaiter`1[System.Byte[]] ByRef) } //public static object // .NET 4.5!!! public static TaskAwaiter<InternalScriptApplicationSource> GetAwaiter(this Type __e) { Console.WriteLine("enter ScriptCoreLib.JavaScript.Experimental " + new { __e.Name }); // http://stackoverflow.com/questions/9713058/sending-post-data-with-a-xmlhttprequest var y = new TaskCompletionSource<InternalScriptApplicationSource>(); //var ysource = Native.window.sessionStorage[__e.Name]; //if (ysource != null) //{ // y.SetResult(ysource); // return y.Task.GetAwaiter(); //} //return //InternalInitializeInlineWorker Report: { __IProgress_Report = { value = [object Object] } } // view-source:27346 //{ Name = a, loaded = 4538818, total = 4538818 } view-source:27346 // view-source:27346 //loading secondary app in a moment... { responseType = arraybuffer, ManagedThreadId = 10 } // view-source:27346 //loading secondary app in a moment... { Length = 4538818 } decrypting... // view-source:27346 //loading secondary app in a moment... { Length = 2269409 } done! var bar = new IHTMLDiv { }.AttachToDocument(); bar.style.SetLocation(0, -2); bar.style.position = IStyle.PositionEnum.@fixed; bar.style.height = "3px"; bar.style.backgroundColor = "red"; //bar.style.borderBottom = "1px solid darkred"; // http://stackoverflow.com/questions/9670075/css-transition-shorthand-with-multiple-properties (bar.style as dynamic).webkitTransition = "top 0.5s linear"; //(bar.style as dynamic).webkitTransitionProperty = "top, width, background-color"; (bar.style as dynamic).webkitTransitionProperty = "top, width"; var state = new { __e.Name, backgroundColor = "red", loaded = default(long), total = default(long), source = default(string), Native.document.location.href, references = new InternalScriptApplicationReference[0] }; Console.WriteLine("call Task.Factory.StartNewWithProgress"); // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/15-dualvr/20160108 Task.Factory.StartNewWithProgress( state, progress: x => { bar.style.top = "0px"; #region bar if (x.loaded > 0) if (x.total > 0) { //if (x.loaded == x.total) //{ //} //else //{ // bar.style.SetLocation(0, 0); //} var xx = (int)(100 * x.loaded / x.total); ; // // 3% is the minimum we want to show var per = Math.Max(3, xx) + "%"; //Console.WriteLine(new { per, x.loaded, x.total, x.backgroundColor }); bar.style.backgroundColor = x.backgroundColor; bar.style.width = per; } #endregion //Console.WriteLine( // new { x.Name, x.loaded, x.total } //); #region SetResult x.source.With( async source => { // // should we analyze? IFunction //Console.WriteLine("wall save source to localStorage " + new { __e.Name, source.Length }); // sessionStorage out of memory? //Native.window.sessionStorage[__e.Name] = source; //Native.window.eval( // //x.responseText // source //); bar.style.backgroundColor = "yellow"; await Task.Delay(300); bar.style.backgroundColor = "red"; await Task.Delay(300); bar.style.backgroundColor = "yellow"; await Task.Delay(300); bar.style.backgroundColor = "red"; await Task.Delay(300); bar.Orphanize(); // { index = 0, name = ScriptCoreLib.dll.js, size = 1330538 } view-source:27530 // view-source:27530 //{ index = 1, name = WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js, size = 507500 } view-source:2753 y.SetResult( new InternalScriptApplicationSource { source = source, references = x.references } ); } ); #endregion }, function: tuple => { var progress = tuple.Item1; var scope = tuple.Item2; // http://stackoverflow.com/questions/13870853/how-to-upload-files-in-web-workers-when-formdata-is-not-defined // FormData is not defined //var f = new FormData(); //f.append("Application", scope.Name); // can we use WebClient instead now? var x = new IXMLHttpRequest(); // { src = /more-source } // { src = blob:http%3A//192.168.43.252%3A5485/fdec11d3-735f-4165-937a-43f25ef8d8d3#worker/more-source } // worker location might not help us talk to our server! //var src = Native.worker.location.href + "/more-source"; //POST http://public:[email protected]:14356//more-source 400 (Bad Request) var src = scope.href; Console.WriteLine(new { src }); x.open(ScriptCoreLib.Shared.HTTPMethodEnum.POST, src, async: true, user: "******", password: "******" ); // Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable. x.setRequestHeader( "X-Application", scope.Name ); // what about progress? // http://stackoverflow.com/questions/10956574/why-might-xmlhttprequest-progressevent-lengthcomputable-be-false var xprogress = new { scope.loaded, scope.total }; // AppEngine will not report progress #region onprogress x.onprogress += e => { // make room for decrypt progress var loaded = e.loaded / 2; xprogress = new { loaded, e.total }; //Console.WriteLine(); progress.Report( new { scope.Name, scope.backgroundColor, xprogress.loaded, xprogress.total, scope.source, scope.href, scope.references } ); }; #endregion #region decrypt Action<byte[]> decrypt = response => { var AllResponseHeaders = x.getAllResponseHeaders(); //AllResponseHeaders = Date: Wed, 11 Sep 2013 14:31:43 GMT //X-Reference-0: ScriptCoreLib.dll.js 1330538 //Server: ASP.NET Development Server/11.0.0.0 //X-AspNet-Version: 4.0.30319 //X-Reference-1: WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js 487668 //X-DiagnosticsMakeItSlowAndAddSalt: ok //Content-Type: application/octet-stream //Cache-Control: public //Connection: Close //Content-Length: 3636412 //Expires: Wed, 11 Sep 2013 14:46:43 GMT var prefix = "X-Reference-"; var references = AllResponseHeaders.Split(new[] { "\r\n" }, StringSplitOptions.RemoveEmptyEntries).Where(k => k.StartsWith(prefix)).Select( k => { var text = k.Substring(prefix.Length); var index = int.Parse(text.TakeUntilIfAny(":")); var name = text.SkipUntilIfAny(":").TakeUntilLastIfAny(" "); var size = int.Parse(text.SkipUntilIfAny(":").SkipUntilLastIfAny(" ")); return new InternalScriptApplicationReference { index = index, name = name, size = size }; } ).ToArray(); Console.WriteLine( "loading secondary app in a moment... " + new { response.Length, Thread.CurrentThread.ManagedThreadId } + " decrypting..."); // loading secondary app in a moment... { Length = 6265416, ManagedThreadId = 10 } decrypting... // X-Reference-0:ScriptCoreLib.dll.js 1330538 //X-Reference-1:WorkerInsideSecondaryApplicationWithBackButton.Application+x.exe.js 485234 // "X:\jsc.svn\examples\javascript\WorkerInsideSecondaryApplication\WorkerInsideSecondaryApplication.sln" //y.SetResult(new { x.responseText.Length }.ToString()); // X:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\WebService\InternalGlobalExtensions.cs var mstopwatch = Stopwatch.StartNew(); var m = new MemoryStream(); var lo = default(byte); var lo_set = false; foreach (var item in response) { if (lo_set) { lo_set = false; var hi = (byte)(item << 4); m.WriteByte( (byte)(lo | hi) ); if ((m.Length % 1024 * 8) == 0) { var loaded = xprogress.total / 2 + m.Length; xprogress = new { loaded, xprogress.total }; //Console.WriteLine(new //{ // Thread.CurrentThread.ManagedThreadId, // mstopwatch.ElapsedMilliseconds, // xprogress //}); progress.Report( new { scope.Name, backgroundColor = "cyan", xprogress.loaded, xprogress.total, scope.source, scope.href, scope.references } ); } } else { lo = item; lo_set = true; } } // decrypted Console.WriteLine("UTF8.GetString " + new { m.Length }); var source = Encoding.UTF8.GetString(m.ToArray()); Console.WriteLine("loading secondary app in a moment... " + new { source.Length } + " done!"); //return new { response.Length, responseText = source }; progress.Report( new { scope.Name, backgroundColor = "green", xprogress.loaded, xprogress.total, source, scope.href, references } ); }; #endregion Action send = async delegate { var response = await x.bytes; decrypt(response); }; send(); // no changes yet return scope; } ); return y.Task.GetAwaiter(); }
// called by // X:\jsc.svn\core\ScriptCoreLib.Ultra\ScriptCoreLib.Ultra\JavaScript\Remoting\InternalWebMethodRequest.cs public Task<byte[]> UploadValuesTaskAsync(Uri address, NameValueCollection data) { //Console.WriteLine("enter WebClient.UploadValuesTaskAsync! " + new { address }); // Z:\jsc.svn\examples\javascript\Test\TestAfterInvokeResponseHeaders\ApplicationWebService.cs // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201511/20151123/uploadvaluestaskasync // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201511/20151123/ubuntumidexperiment var r = new TaskCompletionSource<byte[]> { }; // Z:\jsc.svn\examples\javascript\ubuntu\Test\UbuntuTestUploadValues\Application.cs // "Z:\jsc.svn\examples\javascript\ubuntu\Test\UbuntuTestUserHostAddress\UbuntuTestUserHostAddress.sln" // http://stackoverflow.com/questions/9713058/sending-post-data-with-a-xmlhttprequest // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201401/20140119 // http://stackoverflow.com/questions/8286934/post-formdata-via-xmlhttprequest-object-in-js-cross-browser // http://stackoverflow.com/questions/16917772/ie-lags-on-sending-post-data // http://robertnyman.com/2013/02/11/using-formdata-to-send-forms-with-xhr-as-keyvalue-pairs/ // https://blog.yorkxin.org/posts/2014/02/06/ajax-with-formdata-is-broken-on-ie10-ie11/ var x = new IXMLHttpRequest(); // InvalidStateException //x.withCredentials = true; x.open(Shared.HTTPMethodEnum.POST, address.ToString(), async: true); x.setRequestHeader("Content-Type", "application/x-www-form-urlencoded"); var xFormDataString = ToFormDataString(data); //Uncaught InvalidStateError: Failed to execute 'send' on 'XMLHttpRequest': the object's state must be OPENED. // X:\jsc.svn\examples\javascript\Test\TestUploadValuesAsync\TestUploadValuesAsync\Application.cs // UploadValuesAsync { responseType = , response = <document><TaskComplete><TaskResult>13</TaskResult></TaskComplete></document> } x.InvokeOnComplete( delegate { //Console.WriteLine("after WebClient.UploadValuesTaskAsync! " + new { address }); #region complete var response = new byte[0]; // UploadValuesAsync { status = 204, responseType = arraybuffer, response = [object Uint8ClampedArray] } //if (x.status == 204) // 304? //if (x.status == IXMLHttpRequest.HTTPStatusCodes.NoContent) //{ // // android webview wants us to do this // response = new byte[0]; //} //Uncaught InvalidStateError: Failed to read the 'responseText' property from 'XMLHttpRequest': // The value is only accessible if the object's 'responseType' is '' or 'text' (was 'arraybuffer'). // X:\jsc.svn\examples\javascript\android\com.abstractatech.battery\com.abstractatech.battery\ApplicationWebService.cs //Console.WriteLine("UploadValuesAsync " + new { x.status, x.responseType }); //I/chromium(10616): [INFO:CONSOLE(36216)] "%c0:576ms UploadValuesAsync { status = 204, responseType = arraybuffer }", source: http://192.168.1.103:10129/view-source (36216) //I/chromium(10616): [INFO:CONSOLE(49940)] "Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.", source: http://192.168.1.103:10129/view-source (49940) // what about android webview? if (x.response == null) { //Console.WriteLine("UploadValuesAsync " + new { x.status, x.responseType, x.response, x.responseText }); //I/Web Console( 5012): %c0:198484ms UploadValuesAsync { status = 200, responseType = arraybuffer } at http://192.168.43.1:9417/view-source:37081 //I/Web Console( 5012): %c0:198500ms UploadValuesAsync { status = 200, responseType = arraybuffer, response = , responseText = <document><avatar><obj>aHR0cDovL3d3dy5ncmF2YXRhci5jb20vYXZhdGFyLzhlNmQzZGUw //I/Web Console( 5012): %c0:198524ms InternalWebMethodRequest.Complete { Name = Gravatar, Length = 0 } at http://192.168.43.1:9417/view-source:37081 // did we not fix it already? // android 2.3 only seems to have responseText // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201404/20140413 try { response = Encoding.UTF8.GetBytes(x.responseText); } catch { //I/chromium(30556): [INFO:CONSOLE(37861)] "%c92:28288ms UploadValuesAsync { status = 204, responseType = arraybuffer }", source: http://192.168.43.7:4394/view-source (37861) //I/chromium(30556): [INFO:CONSOLE(37861)] "%c92:28290ms responseText failed. thanks webview devs. { status = 204 }", source: http://192.168.43.7:4394/view-source (37861) // X:\jsc.svn\examples\javascript\p2p\SharedBrowserSessionExperiment\SharedBrowserSessionExperiment\ApplicationWebService.cs Console.WriteLine("responseText failed? " + new { x.status }); } } else { // http://stackoverflow.com/questions/8022425/getting-blob-data-from-xhr-request var a = (ArrayBuffer)x.response; //Console.WriteLine("UploadValuesAsync " + new { x.status, x.responseType, a.byteLength }); // IE? //var u8 = new Uint8Array(array: a); // X:\jsc.svn\core\ScriptCoreLib.Async\ScriptCoreLib.Async\JavaScript\DOM\FileEntryAsyncExtensions.cs var u8c = new Uint8ClampedArray(array: a); response = u8c; } //Console.WriteLine("UploadValuesAsync " + new { x.status, x.responseType, response }); #region ResponseHeaders this.ResponseHeaders = new WebHeaderCollection(); //this.ResponseHeaders.Clear(); var ResponseHeaders = x.getAllResponseHeaders(); // Z:\jsc.svn\examples\javascript\Test\TestAfterInvokeResponseHeaders\ApplicationWebService.cs //Console.WriteLine("after WebClient.UploadValuesTaskAsync! " + new { ResponseHeaders }); //0:8209ms { ResponseHeaders = Date: Sat, 15 Mar 2014 12:25:45 GMT //Server: ASP.NET Development Server/11.0.0.0 //X-AspNet-Version: 4.0.30319 //ETag: BqShORsRkdny750pWBdVyQ== //X-ElapsedMilliseconds: 10 //Content-Type: text/xml; charset=utf-8 //Access-Control-Allow-Origin: * //Cache-Control: private //Connection: Close //Content-Length: 239 foreach (var item in ResponseHeaders.Split('\n')) { var u = item.IndexOf(":"); if (u > 0) { var ukey = item.Substring(0, u); var uvalue = item.Substring(u + 1).Trim(); //Console.WriteLine(new { ukey, uvalue }); this.ResponseHeaders[ukey] = uvalue; } } #endregion //Console.WriteLine(new { ResponseHeaders }); r.SetResult(response); #endregion } ); x.responseType = "arraybuffer"; // Z:\jsc.svn\examples\javascript\ubuntu\UbuntuSSLWebApplication\UbuntuSSLWebApplication\Application.cs // allow basejump? // breaks Task<> call? //x.responseType = "text"; // is IE actually sending it? or is our server decoding it wrong? //Console.WriteLine("WebClient.UploadValuesAsync IXMLHttpRequest " + new { xFormDataString }); x.send(xFormDataString); return r.Task; }