// https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20151102
        // set by?
        // Z:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Extensions\TcpListenerExtensions.cs

        public static void Invoke(InternalGlobal g)
        {
            // did we ask the user for PIN ?


            var path = new FileInfo("ClientCertificate.crt");
            if (path.Exists)
            {
                try
                {
                    Console.WriteLine("enter InternalCassiniClientCertificateLoader "
                        + new { path.FullName }
                        //+ new { Environment.CurrentDirectory, typeof(InternalCassiniClientCertificateLoader).Assembly.Location }
                    );

                    // 'System.Security.Cryptography.X509Certificates.X509Certificate' to type 'System.Security.Cryptography.X509Certificates.X509Certificate2'.


                    var crt = new System.Security.Cryptography.X509Certificates.X509Certificate2();

                    crt.Import(File.ReadAllBytes(path.FullName));

                    g.ClientCertificate = crt;

                }
                catch (Exception err)
                {
                    Console.WriteLine(new { err });

                    throw;
                }
                finally
                {
                    File.Delete(path.FullName);
                }
            }

        }
        // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20151102
        // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201510/20151022/httprequest

        public static void InternalApplication_BeginRequest(InternalGlobal g)
        {
            //Console.WriteLine("InternalApplication_BeginRequest " + new { Environment.StackTrace });

            // is it ROSLYN friendly? no?
            // need to compile it by 2012?
            //AppDomain.CurrentDomain.UnhandledException +=
            //    (s, e) =>
            //    {

            //    };


            var BeginRequestStopwatch = Stopwatch.StartNew();


            var that = g.InternalApplication;
            var Context = that.Context;

            var Path = Context.Request.Path;

            #region WriteFile
            var CurrentFile = g.ToCurrentFile();

            if (CurrentFile != null)
            {
                // http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/


                //// http://www.mombu.com/programming/xbase/t-outputcache-directive-vs-responsecachesetcacheability-624773.html
                g.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
                g.Response.Cache.SetExpires(DateTime.Now.AddMinutes(15));

                //g.EndRequest +=
                //    (_s, _e) =>
                //    {
                //Console.WriteLine("cache " + CurrentFile.Name);


                //        // http://forums.asp.net/t/1123505.aspx
                //        HttpApplication application = (HttpApplication)_s;
                //        HttpContext context = application.Context;
                //g.Response.ExpiresAbsolute = DateTime.Now.AddDays(1);
                //context.Response.AddHeader("pragma", "no-cache");
                //g.Response.AddHeader("cache-control", "public");
                g.Response.AddHeader("Content-Length", "" + CurrentFile.Length);

                var ContentType = "application/octet-stream";
                var n = CurrentFile.Name;

                // http://www.webmaster-toolkit.com/mime-types.shtml
                if (n.EndsWith(".gif")) ContentType = "image/gif";
                else if (n.EndsWith(".htm")) ContentType = "text/html";

                else if (n.EndsWith(".png")) ContentType = "image/png";
                else if (n.EndsWith(".jpg")) ContentType = "image/jpg";
                else if (n.EndsWith(".svg")) ContentType = "image/svg+xml";

                else if (n.EndsWith(".js")) ContentType = "application/x-javascript";

                else if (n.EndsWith(".mp3")) ContentType = "audio/mpeg3";
                else if (n.EndsWith(".wav")) ContentType = "audio/wav";
                else if (n.EndsWith(".mid")) ContentType = "audio/midi";

                else if (n.EndsWith(".css")) ContentType = "text/css";

                that.Response.ContentType = ContentType;

                // to root
                Context.Response.WriteFile("/" + CurrentFile.Name);

                that.CompleteRequest();

                //context.Response.CacheControl = "no-cache";
                //};

                // fake lag
                //if (that.Request.Path.EndsWith(".js"))
                //    System.Threading.Thread.Sleep(1000);
                return;
            }
            #endregion




            StringAction Write =
                e =>
                {
                    // could we take the method pointer implicitly?
                    Context.Response.Write(e);
                };

            StringAction WriteLine =
                e =>
                {
                    // could we take the method pointer implicitly?
                    Write(e + Environment.NewLine);
                };




            var WebMethods = g.GetWebMethods();



            // X:\jsc.svn\examples\javascript\test\TestBaseFieldSync\TestBaseFieldSync\ApplicationWebService.cs

            #region WriteInternalFields InternalFields -> AppendCookie
            Action<InternalWebMethodInfo> WriteInternalFields =
                x =>
                {
                    // Z:\jsc.svn\examples\javascript\ubuntu\UbuntuSSLWebApplication\UbuntuSSLWebApplication\ApplicationWebService.cs


                    // does 304 check also look at 
                    // fields?

                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201403/20140323
                    // X:\jsc.svn\examples\javascript\forms\FormsDataBindingForEnabled\FormsDataBindingForEnabled\ApplicationWebService.cs

                    if (x.InternalFields == null)
                        return;

                    // typename instead?
                    var c = new HttpCookie("InternalFields");
                    // X:\jsc.svn\examples\javascript\Test\TestWebServiceTaskFields\TestWebServiceTaskFields\ApplicationWebService.cs

                    // X:\jsc.svn\examples\javascript\test\TestNullObjectFromWebService\TestNullObjectFromWebService\ApplicationWebService.cs

                    foreach (string InternalFieldName in x.InternalFields.Keys.ToArray())
                    {

                        var value = x.InternalFields[InternalFieldName];

                        //Console.WriteLine("WriteInternalFields " + new { InternalFieldName, value });

                        if (value != null)
                        {
                            // for /xml post
                            if (Context.Request.HttpMethod == "POST")
                            {
                                // GetParameterValue: { key = _0600000e_field_elapsed }

                                // if we write her. where are they read?
                                // Z:\jsc.svn\examples\javascript\Test\TestFirefoxWebServiceField\ApplicationWebService.cs
                                // firefox filters out spaces?
                                that.Context.Response.AddHeader(
                                    ".field-" + InternalFieldName,
                                    value
                                );

                                // .field-field_foo:<_02000013>%0d%0a  <_04000021>Z3Vlc3Q=</_04000021>%0d%0a</_02000013>
                                // Z:\jsc.svn\examples\javascript\Test\TestAfterInvokeResponseHeaders\ApplicationWebService.cs

                                // 204 No Content ?
                            }
                            else
                            {

                                // for / get
                                c[InternalFieldName] = value;
                            }
                        }
                    }

                    // Set-Cookie:InternalFields=field_Foo=7; path=/
                    //that.Context.Response.AppendCookie(c);
                    if (Context.Request.HttpMethod == "POST")
                    {

                    }
                    else
                    {
                        that.Context.Response.SetCookie(c);
                    }


                };
            #endregion



            var IsComplete = false;

            #region handler = WebServiceHandler
            var handler = new WebServiceHandler
            {
                ClientCertificate = g.ClientCertificate,
                ClientTrace = g.ClientTrace,

                Context = that.Context,

                CompleteRequest = delegate
                {
                    IsComplete = true;
                    that.CompleteRequest();
                },

                Applications = g.GetScriptApplications(),

                // tested by
                // X:\jsc.svn\examples\javascript\synergy\webgl\EvilChopperByPer\EvilChopperByPer\ApplicationWebService.cs
                // X:\jsc.svn\examples\javascript\synergy\webgl\WebGLDoomByInt13h\WebGLDoomByInt13h\ApplicationWebService.cs
                GetFiles = g.GetFiles,


                #region Default
                Default = delegate
                {
                    that.Response.ContentType = "text/html";
                    //that.Response.AddHeader("Access-Control-Allow-Origin", "*");

                    // todo: jsc: PHP workaround required
                    var apps = g.GetScriptApplications();
                    var app = apps[0];








                    var Host = that.Context.Request.Headers["Host"].TakeUntilIfAny(":");

                    var CacheManifest = false;
                    //var CacheManifest = true;

                    // should disable that for android webview?

                    //if (Host == that.Context.Request.UserHostAddress)
                    //    CacheManifest = false;

                    //// webdev?
                    //if ("127.0.0.1" == that.Context.Request.UserHostAddress)
                    //    CacheManifest = false;

                    // X:\jsc.svn\examples\javascript\test\TestServiceWorkerAssetCache\TestServiceWorkerAssetCache\Application.cs
                    app.WriteTo(Write, CacheManifest);

                    IsComplete = true;
                    that.CompleteRequest();
                },
                #endregion


                Diagnostics = delegate
                {
                    that.Response.ContentType = "text/html";
                    WriteDiagnostics(g, Write, WebMethods);

                    IsComplete = true;
                    that.CompleteRequest();
                },

                Redirect = delegate
                {
                    that.Response.Redirect("/#" + that.Request.Path);

                    IsComplete = true;
                    that.CompleteRequest();
                }
            };
            #endregion

            #region handler.WriteSource
            handler.WriteSource = app =>
            {
                handler.Context.Response.ContentType = "text/javascript";

                g.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);

                // are we not part of AppCache?
                g.Response.Cache.SetExpires(DateTime.Now.AddMinutes(15));

                //Console.WriteLine("IsConstructor WriteInternalFields");

                var Constructor = new InternalWebMethodInfo
                {
                    IsConstructor = true
                };

                // Method not found: '?'.
                // Additional information: Attempt by method 'mscorlib.<02000005IEnumerable\+ConvertToString>.ConvertToString(System.Collections.Generic.IEnumerable`1<TestIEnumerableForService.foo>)' 
                // to access method '<>f__AnonymousType6`1<System.__Canon>..ctor(System.__Canon)' failed.
                g.Invoke(Constructor);

                WriteInternalFields(Constructor);




                #region GetFiles
                var ff = g.GetFiles();

                // jsc packages js files? not for long:P will switch to gzip at some point!
                var app_references = app.References.Select(
                    // why wont Single work correctly?
                    // are we embedding one file multiple times?
                    item => ff.First(k => k.Name == item.AssemblyFile || k.Name == item.AssemblyFile + ".js")
                ).ToArray();
                #endregion



                app_references.WithEachIndex(
                    (app_ref, index) =>
                    {
                        // will this work an all platforms?
                        // need to test!
                        g.Response.AddHeader("X-Reference-" + index, app_ref.Name + " " + app_ref.Length);
                    }
                );


                // tested by
                // X:\jsc.svn\examples\javascript\android\com.abstractatech.adminshell\com.abstractatech.adminshell\ApplicationWebService.cs
                #region DiagnosticsMakeItSlowAndAddSalt
                if (app.DiagnosticsMakeItSlowAndAddSalt)
                {
                    Console.WriteLine("enter DiagnosticsMakeItSlowAndAddSalt");

                    handler.Context.Response.ContentType = "application/octet-stream";


                    #region composite
                    var composite =
                        new CompositeStream(
                           app_references.Select(
                            k =>
                            {
                                return new Func<Stream>(
                                    () =>
                                    {
                                        Console.WriteLine("composite: " + new { k.Name });
                                        return (Stream)File.OpenRead(k.Name);
                                    }
                                );
                            }
                        )
                    );
                    #endregion


                    Console.WriteLine("encrypting... ");

                    //var x = new MemoryStream();

                    var buffer = new byte[1024 * 40];
                    //var count = composite.GetBytes(buffer).Count();

                    #region count
                    var count = 0;


                    foreach (var y in composite.GetBytes(buffer))
                    {
                        count += y;

                        Console.WriteLine(new { count });
                    }

                    #endregion

                    // encrypting... { count = 58 }

                    Console.WriteLine("encrypting by splitting bytes... " + new { count });

                    var time = new Stopwatch();
                    time.Start();

                    var bytesleft = count;

                    g.Response.AddHeader("Content-Length", "" + (count * 2));
                    g.Response.AddHeader("X-DiagnosticsMakeItSlowAndAddSalt", "ok");


                    //                    lets write DiagnosticsMakeItSlowAndAddSalt
                    //enter DiagnosticsMakeItSlowAndAddSalt
                    //encrypting...
                    //enter GetBytes
                    //exit GetBytes
                    //encrypting... { count = 2282136 }
                    //enter GetBytes

                    // ? 
                    // needs to work in .net then in android!

                    var xbuffer = new byte[buffer.Length * 2];

                    foreach (var length in composite.GetBytes(buffer))
                    {
                        Console.WriteLine("before flush of " + new { length });

                        for (int i = 0; i < length; i++)
                        {
                            var item = buffer[i];

                            var lo = (byte)(item & 0xf);
                            var hi = (byte)((item & 0xf0) >> 4);


                            xbuffer[i * 2 + 0] = lo;
                            xbuffer[i * 2 + 1] = hi;

                            //h.Context.Response.OutputStream.WriteByte(lo);
                            //h.Context.Response.OutputStream.WriteByte(hi);



                            bytesleft--;




                        }

                        handler.Context.Response.OutputStream.Write(xbuffer, 0, length * 2);
                        handler.Context.Response.Flush();

                        var timetarget = 8000 - time.ElapsedMilliseconds;

                        //                 Caused by: java.lang.ArithmeticException: divide by zero
                        //at ScriptCoreLib.Ultra.WebService.InternalGlobalExtensions___c__DisplayClasse._InternalApplication_BeginRequest_b__7(InternalGlobalExtensions___c__DisplayClasse.java:235)

                        //var ms = (int)(timetarget / bytesleft);



                        Console.WriteLine("." + new
                        {
                            bytesleft
                            //, ms 
                        });

                        //if (timetarget > 0)
                        //{
                        //    Thread.Sleep(ms);
                        //}
                    }





                    Console.WriteLine("will upload done " + new { time.ElapsedMilliseconds });

                    return;
                }
                #endregion


                #region GZipAssemblyFile
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201301/20130103

                var AcceptEncoding = handler.Context.Request.Headers["Accept-Encoding"];

                if (!string.IsNullOrEmpty(AcceptEncoding))
                    if (AcceptEncoding.Contains("gzip"))
                    {
                        g.Response.AddHeader("Content-Encoding", "gzip");



                        g.Response.WriteFile("/" + app.GZipAssemblyFile);
                        handler.CompleteRequest();

                        return;
                    }
                #endregion

                g.Response.AddHeader("X-Comment", "gzip was disabled");

                #region the old way


                var app_size = app_references.Sum(k => k.Length);

                // Accept-Encoding:gzip,deflate,sdch

                g.Response.AddHeader("Content-Length", "" + app_size);
                //g.Response.AddHeader("X-GZipAssemblyFile", "" + app.GZipAssemblyFile);


                foreach (var item in app_references)
                {
                    // asp.net needs absolute paths
                    handler.Context.Response.WriteFile("/" + item.Name);
                }
                #endregion


                handler.CompleteRequest();
            };
            #endregion


            #region WebMethodMetadataToken
            if (Context.Request.HttpMethod == "POST")
            {
                var cWebMethodMetadataToken = Context.Request.Form.AllKeys.Contains("WebMethodMetadataToken");

                //Console.WriteLine("POST is expected to include WebMethodMetadataToken " + new { cWebMethodMetadataToken });
                // X:\jsc.svn\core\ScriptCoreLib\JavaScript\BCLImplementation\System\Net\WebClient.cs

                // who sets WebMethodMetadataToken ?
                // X:\jsc.svn\core\ScriptCoreLib.Ultra\ScriptCoreLib.Ultra\JavaScript\Remoting\InternalWebMethodRequest.cs
                // C:\Users\Arvo\AppData\Local\Temp\6796$ScriptCoreLib.Ultra.dll$v4.0.30319$NoDynamic\ScriptCoreLib.JavaScript.Remoting.InternalWebMethodRequest.cs

                // X:\jsc.svn\examples\javascript\css\Test\TestLongWebMethod\TestLongWebMethod\Application.cs

                // tested by
                // X:\jsc.svn\examples\javascript\Test\TestWebMethodIPAddress\TestWebMethodIPAddress\ApplicationWebService.cs
                // X:\jsc.internal.svn\compiler\jsc.meta\jsc.meta\Library\Templates\JavaScript\InternalWebMethodRequest.cs
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201401/20140110-xml

                //var WebMethodMetadataToken = Context.Request.QueryString[InternalWebMethodInfo.QueryKey];

                if (cWebMethodMetadataToken)
                {
                    var WebMethodMetadataToken = Context.Request.Form["WebMethodMetadataToken"];
                    //var value_Form = that.InternalContext.Request.Form[key];

                    // Z:\jsc.svn\examples\javascript\appengine\Test\TestUserHostAddress\ApplicationWebService.cs

                    if (WebMethodMetadataToken != null)
                        handler.WebMethod = InternalWebMethodInfo.First(
                            WebMethods,
                           WebMethodMetadataToken
                        );

                }
            }
            #endregion


            g.Serve(handler);

            if (IsComplete)
                return;


            #region POST
            if (Context.Request.HttpMethod == "POST")
            {
                // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140101
                //Console.WriteLine("about to load params for " + new { handler.WebMethod });

                if (handler.WebMethod == null)
                {
                    // let user defined handler handle it..
                }
                else
                {
                    // is it also supposed to load the fields?
                    handler.WebMethod.LoadParameters(that.Context);

                    //Console.WriteLine("enter invoke " + new { handler.WebMethod });

                    //about to load params for { WebMethod = { IsConstructor = false, MetadataToken = 06000002, Name = Insert, TypeFullName = WebCamAvatarsExperiment.ApplicationWebService, Parameters = 1 } }
                    //about to invoke { WebMethod = { IsConstructor = false, MetadataToken = 06000002, Name = Insert, TypeFullName = WebCamAvatarsExperiment.ApplicationWebService, Parameters = 1 } }
                    // when can we invoke the webmethod and not be at /xml?

                    //try
                    //{

                    // where is the code gen?
                    // X:\jsc.internal.svn\compiler\jsc.meta\jsc.meta\Commands\Rewrite\RewriteToJavaScriptDocument.WebService.cs

                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140107-dev/test
                    var WebMethodStopwatch = Stopwatch.StartNew();

                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201404/20140405/task
                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201405/20140517
                    // defined by X:\jsc.internal.svn\compiler\jsc.meta\jsc.meta\Commands\Rewrite\RewriteToJavaScriptDocument.WebService.cs

                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201408/20140811

                    // public abstract void Invoke(InternalWebMethodInfo e);
                    g.Invoke(handler.WebMethod);


                    // BeginRequestStopwatch
                    //that.Response.AddHeader("X-BeginRequestStopwatch", "" + BeginRequestStopwatch.ElapsedMilliseconds);

                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140110-stats
                    that.Response.AddHeader("X-ElapsedMilliseconds", "" + WebMethodStopwatch.ElapsedMilliseconds);
                    //that.Response.AddHeader("Access-Control-Allow-Origin", "*");

                    if (handler.WebMethod.AtElapsedMilliseconds != null)
                        handler.WebMethod.AtElapsedMilliseconds(WebMethodStopwatch.ElapsedMilliseconds);

                    //that.Response.AddHeader("X-WebMethodStopwatch", "" + SQLiteConnectionStringBuilderExtensions.ElapsedMilliseconds);

                    //}
                    //catch (Exception err)
                    //{
                    //    Console.WriteLine("boom! " + new { err });
                    //}

                    //Console.WriteLine("exit invoke " + new { handler.WebMethod });

                    //if (that.Context.Request.Path == "/xml")
                    if (that.Context.Request.Path != "/jsc")
                    {
                        // the diagnostics needs more attention down the road.


                        WriteInternalFields(handler.WebMethod);

                        // no yields
                        // why is handler.WebMethod.Results null??
                        #region 204
                        if (handler.WebMethod.Results.Length == 0)
                            if (handler.WebMethod.TaskResult == null)
                            {
                                // or should we send binary zip for webworker?
                                // NoContent
                                g.Context.Response.StatusCode = 204;
                                g.Context.Response.Flush();

                                that.CompleteRequest();
                                return;
                            }
                        #endregion


                        WriteXDocument(g, Write, handler.WebMethod);
                        that.CompleteRequest();
                        return;
                    }

                    that.Response.ContentType = "text/html";
                    WriteDiagnosticsResults(Write, handler.WebMethod);
                    WriteDiagnostics(g, Write, WebMethods);
                    that.CompleteRequest();
                    return;
                }
            }
            #endregion


            if (IsComplete)
                return;


            #region /favicon.ico
            if (Path == "/favicon.ico")
            {
                Context.Response.WriteFile("assets/ScriptCoreLib/jsc.ico");

                that.CompleteRequest();
                return;
            }
            #endregion



            #region /robots.txt
            if (Path == "/robots.txt")
            {
                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }
            #endregion

            #region /crossdomain.xml
            if (Path == "/crossdomain.xml")
            {
                // X:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\WebService\InternalGlobalExtensions.InternalApplication_BeginRequest.cs
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201401/20140109-webclient
                // http://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
                // X:\jsc.smokescreen.svn\market\appengine\xmoneseAIR\xmoneseAIR\ApplicationCanvas.cs
                Context.Response.Write(@"<?xml version='1.0'?>
<!-- http://www.osmf.org/crossdomain.xml -->
<!DOCTYPE cross-domain-policy SYSTEM 'http://www.adobe.com/xml/dtds/cross-domain-policy.dtd'>
<cross-domain-policy>
    <allow-access-from domain='*' />
    <site-control permitted-cross-domain-policies='all'/>
</cross-domain-policy>");

                that.CompleteRequest();
                return;
            }
            #endregion


            // cache manifest will not be needed
            // after ServiceWorker becomes useful
            // 20141230
            // X:\jsc.svn\examples\javascript\test\TestServiceWorkerAssetCache\TestServiceWorkerAssetCache\Application.cs
            #region WriteCacheManifest
            if (Path == "/" + WebApplicationCacheManifest.ManifestName)
            {
                // <html manifest="cache-manifest">

                //WriteCacheManifest(g, that, WriteLine);

                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }
            #endregion



            if (that.Request.Path == "/jsc")
            {
                handler.Diagnostics();
                return;
            }

            #region /view-source
            if (that.Request.Path == "/view-source")
            {


                var app = handler.Applications[0];

                // can we just invoke a ctor?
                // and have the fields returne?

                handler.WriteSource(app);

                return;
            }
            #endregion


            if (handler.IsDefaultPath)
            {
                handler.Default();
                return;
            }

            if (Context.Request.HttpMethod == "POST")
            {
                // Z:\jsc.svn\examples\javascript\test\TestMultipartRelated\Application.cs
                // Z:\jsc.svn\examples\javascript\ubuntu\UbuntuDualSSLWebApplication\UbuntuDualSSLWebApplication\ApplicationWebService.cs
                Console.WriteLine("invalid invoke? IE is that you?");

                // we dont know what to do with this POST..
                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }

            // we could invoke web service handler now?
            handler.Redirect();
            //h.Diagnostics();
        }
 public static bool FileExists(InternalGlobal g)
 {
     return(g.ToCurrentFile() != null);
 }
 public static DefaultProfile InternalGetProfile(InternalGlobal g)
 {
     var that = g.InternalApplication;
     return (DefaultProfile)that.Context.Profile;
 }
        private static void WriteXDocument(InternalGlobal g, StringAction Write, InternalWebMethodInfo WebMethod)
        {
            var that = g.InternalApplication;
            var Context = that.Context;

            #region document
            var w = new StringBuilder();


            w.Append("<document>");



            if (WebMethod.Results == null)
            {
                //Console.WriteLine("WriteXDocument Results null");
            }
            else
            {
                //Console.WriteLine("WriteXDocument Results " + new { WebMethod.Results.Length });

                foreach (var item in WebMethod.Results)
                {
                    w.Append("<" + item.MethodName + ">");

                    if (item.Parameters != null)
                    {
                        foreach (var p in item.Parameters)
                        {

                            if (p.Value == null)
                            {
                                // no parameter?
                                // X:\jsc.svn\examples\javascript\WebMethodXElementTransferExperiment\WebMethodXElementTransferExperiment\ApplicationWebService.cs
                            }
                            else
                            {
                                w.Append("<" + p.Name + ">");
                                w.Append(escapeXML(p.Value));
                                w.Append("</" + p.Name + ">");
                            }


                        }
                    }

                    w.Append("</" + item.MethodName + ">");

                }
            }

            if (WebMethod.TaskComplete)
            {
                w.Append("<TaskComplete>");

                if (WebMethod.TaskResult != null)
                {
                    //Console.WriteLine(new { WebMethod.TaskResult });

                    w.Append("<TaskResult>");
                    w.Append(escapeXML(WebMethod.TaskResult));
                    w.Append("</TaskResult>");
                }

                w.Append("</TaskComplete>");
            }

            w.Append("</document>");
            #endregion



            var ws = w.ToString();
            var wsbytes = Encoding.UTF8.GetBytes(ws);


            // http://stackoverflow.com/questions/1999824/whats-the-shortest-pair-of-strings-that-causes-an-md5-collision

            var ETagbytes = wsbytes.ToMD5Bytes();
            var newETag = ETagbytes.ToHexString();
            // does the client already have a copy of the same response?
            // if so, send 304 ?
            // http://www.codeproject.com/Articles/23857/The-Performance-Woe-of-Binary-XML
            // are we ready for encrypted binary xml?
            // http://msdn.microsoft.com/en-us/library/cc219210.aspx
            // file:///C:/Users/Arvo/Downloads/03-002r9_Binary_Extensible_Markup_Language_BXML_Encoding_Specification.pdf
            // is this the beginning of a binary diff service?


            // allow http to https calls
            Context.Response.AddHeader("Access-Control-Allow-Origin", "*");
            Context.Response.AddHeader("ETag", Convert.ToBase64String(ETagbytes));

            var hasETag = Context.Request.Form.AllKeys.Contains("ETag");
            if (hasETag)
            {
                var oldETag64 = Context.Request.Form["ETag"];
                var oldETagbytes = Convert.FromBase64String(oldETag64);
                var clientETag = oldETagbytes.ToHexString();

                //{ MethodName = Gravatar, MetadataToken = 06000001, oldETag = 1706b464adc232a9df3dd4539a206569 }
                //{ MethodName = Gravatar, MetadataToken = 06000001, ETag = 1706b464adc232a9df3dd4539a206569 }

                //Console.WriteLine(new { WebMethod.MethodName, WebMethod.MetadataToken, clientETag });

                //I/System.Console( 3988): #17 POST /xml/Gravatar HTTP/1.1
                //D/FastDormancy(  220):  before ======= ENTER DORMANCY =======
                //W/Threeg  (  918): Failed to read packet and byte counts from wifi interface
                //D/dalvikvm( 3988): GC_CONCURRENT freed 819K, 56% free 3157K/7111K, external 2013K/2108K, paused 2ms+2ms
                //I/System.Console( 3988): { MethodName = Gravatar, MetadataToken = 06000001, oldETag = d41d8cd98f00b204e9800998ecf8427e }
                //I/System.Console( 3988): { MethodName = Gravatar, MetadataToken = 06000001, ETag = 5a62b5d768653ae632ba4ff7e0b7a03c }
                //I/Web Console( 3988): %c0:312066ms InternalWebMethodRequest.Complete { Name = Gravatar, Length = 0 } at http://192.168.43.1:14691/view-source:37081
                //I/Web Console( 3988): 0:312076ms { Name = Gravatar, MetadataToken = 06000001, ETag = d41d8cd98f00b204e9800998ecf8427e, ElapsedMilliseconds = 5 } at http://192.168.43.1:14691/view-source:37040


#if ETagTestedForIE11
                if (clientETag == newETag)
                {
                    //Console.WriteLine("Client already has the answer, sending 304");
                    // X:\jsc.svn\examples\javascript\forms\FormsDataBindingForEnabled\FormsDataBindingForEnabled\ApplicationControl.cs

                    // what will web client do with 304?
                    g.Context.Response.StatusCode = 304;
                    g.Context.Response.Flush();

                    that.CompleteRequest();
                    return;
                }
#endif


            }

            //Console.WriteLine(new { WebMethod.MethodName, WebMethod.MetadataToken, newETag, ws.Length });

            //I/System.Console( 4563): #4 POST /xml/Gravatar HTTP/1.1
            //I/System.Console( 4563): { MethodName = Gravatar, MetadataToken = 06000001, newETag = 1706b464adc232a9df3dd4539a206569, Length = 239 }

            //I/Web Console( 4563): %c0:22236ms InternalWebMethodRequest.Complete { Name = Gravatar, Length = 0 } at http://192.168.43.1:6686/view-source:37081
            //I/Web Console( 4563): 0:22345ms { Name = Gravatar, MetadataToken = 06000001, ETag = d41d8cd98f00b204e9800998ecf8427e, ElapsedMilliseconds = 25 } at http://192.168.43.1:6686/view-source:37040


            Context.Response.ContentType = "text/xml";

            // https://developer.mozilla.org/en-US/docs/HTTP/Access_control_CORS?redirectlocale=en-US&redirectslug=HTTP_access_control


            Write(ws);

            that.CompleteRequest();
        }
        private static void WriteDiagnostics(InternalGlobal g, StringAction Write, InternalWebMethodInfo[] WebMethods)
        {
            // should the diagnostics be a separate rich Browser Application? :)

            var Context = g.InternalApplication.Context;

            Write("<title>jsc-solutions.net</title>");
            Write("<br/><center><a href='/'>Launch Application</a></center><br/>");

            Write("<a href='http://jsc-solutions.net'><img border='0' src='/assets/ScriptCoreLib/jsc.png' /></a>");


            Write("<blockquote>");
            Write("<h2>Special pages</h2>");
            Write("<blockquote>");

            // like CON in filesystem?
            Write("<br /> " + "special page: " + "<a href='/robots.txt'>/robots.txt</a>");
            Write("<br /> " + "special page: " + "<a href='/xml'>/xml</a>");
            Write("<br /> " + "special page: " + "<a href='/crossdomain.xml'>/crossdomain.xml</a>");
            Write("<br /> " + "special page: " + "<a href='/favicon.ico'>/favicon.ico</a>");
            Write("<br /> " + "special page: " + "<a href='/jsc'>/jsc</a>");
            Write("<br /> " + "special page: " + "<a href='/view-source'>/view-source</a>");
            Write("</blockquote>");

            Write("<h2>Methods</h2>");
            Write("<blockquote>");
            foreach (var item in WebMethods)
            {
                WriteWebMethodForm(Write, item);
            }
            Write("</blockquote>");


            Write("<br /> Path: '" + Context.Request.Path + "'");
            Write("<br /> HttpMethod: '" + Context.Request.HttpMethod + "'");

            Write("<h2>Form</h2>");
            foreach (var item in Context.Request.Form.AllKeys)
            {
                Write("<br /> " + "<img src='http://i.msdn.microsoft.com/w144atby.pubproperty(en-us,VS.90).gif' /> <code>");
                Write(item);
                Write(" = ");
                Write(escapeXML(Context.Request.Form[item]));
                Write("</code>");
            }

            Write("<h2>QueryString</h2>");
            foreach (var item in Context.Request.QueryString.AllKeys)
            {
                Write("<br /> " + "<img src='http://i.msdn.microsoft.com/w144atby.pubproperty(en-us,VS.90).gif' /> <code>");
                Write(item);
                Write(" = ");
                Write(escapeXML(Context.Request.QueryString[item]));
                Write("</code>");
            }

            var ff = g.GetFiles();

            // http://msdn.microsoft.com/en-us/library/y47ychfe.aspx

            Write("<h2>Applications</h2>");
            Write("<blockquote>");

            foreach (var app in g.GetScriptApplications())
            {
                Write("<br /> ");

                Write("<img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' />");

                Write(" <code style='color: darkcyan;'>" + app.TypeName + "</code>");

                // var app_references = app.References.Select(
                //    item => ff.First(k => k.Name == item.AssemblyFile + ".js")
                //).ToArray();

                // var app_size = app_references.Sum(k => k.Length);

                // Write(" <span style='color: gray;'>(" + app_size + " bytes)</span>");

                foreach (var r in app.References)
                {
                    Write("<br /> &nbsp;&nbsp;&nbsp;&nbsp;");

                    Write("<img src='http://i.msdn.microsoft.com/dynimg/IC477625.png' />");
                    Write(" " + r.AssemblyFile);

                }
            }
            Write("</blockquote>");

            Write("<h2>Files</h2>");
            Write("<blockquote>");

            Action<string> separator = delegate { };

            foreach (var item in g.GetFiles())
            {
                separator(item.Name);

                Write(
                    "<br /> "
                    + " file: <a href='" + item.Name + "'>" + item.Name + "</a>" + " size: " + item.Length
                );


                // do we need this?
                //var itemref_csharp4 = item;

                separator =
                    next =>
                    {
                        if (next.TakeUntilLastOrEmpty("/") == item.Name.TakeUntilLastOrEmpty("/"))
                        {
                            return;
                        }

                        Write(
                            "<br /> "
                        );

                    };

            }
            Write("</blockquote>");
            Write("</blockquote>");

        }
        private static void WriteCacheManifest(InternalGlobal g, System.Web.HttpApplication that, StringAction WriteLine)
        {
            // should the app be able to control manifest on its own?

            // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201303/20130330-cache-manifest
            // http://html5doctor.com/go-offline-with-application-cache/
            that.Response.ContentType = WebApplicationCacheManifest.ManifestContentType;
            that.Response.AddHeader("Cache-Control", "no-cache, private");
            that.Response.AddHeader("Expires", "0");
            // http://stackoverflow.com/questions/1715568/how-to-properly-invalidate-an-html5-cache-manifest-for-online-offline-web-apps
            // Cache-Control: no-cache, private

            #region w
            var w = new StringBuilder();

            // http://www.whatwg.org/specs/web-apps/current-work/multipage/offline.html

            w.AppendLine("CACHE MANIFEST");

            var files = g.GetFiles();
            var bytes = 0;

            // do we need these?
            //w.AppendLine(WebApplicationIcon.Icon);
            //w.AppendLine(WebApplicationIcon.Image);

            //Explicit entries

            w.AppendLine("/");
            w.AppendLine("/view-source");


            foreach (var item in files)
            {

                var Command = item.Name;

                bytes += item.Length;

                // webkit seems to have 5MB limit.
                // http://groups.google.com/a/chromium.org/group/chromium-html5/browse_thread/thread/e911f18b905d28ee/9f54c8cc1e8afb5d
                // http://stackoverflow.com/questions/2908459/mobile-safari-5mb-html5-application-cache-limit
                // http://www.yuiblog.com/blog/2010/07/12/mobile-browser-cache-limits-revisited/

                // hack.

                // we need to figure out how to make the application fit to the cache limits.
                // we could be optimizing javascript.

                if (Command.EndsWith(".css"))
                    w.AppendLine(Command);

                if (Command.EndsWith(".swf"))
                    w.AppendLine(Command);

                // There’s no technical benefit to WOFF over TTF.
                if (Command.EndsWith(".ttf"))
                    w.AppendLine(Command);
            }

            w.AppendLine("");


            // what about fake pages used by historic api?
            // X:\jsc.svn\examples\javascript\async\AsyncHistoricActivities\AsyncHistoricActivities\Application.cs
            //w.AppendLine("FALLBACK:");
            //w.AppendLine("/fake-right /#/fake-right");

            // Application Cache Error event: Resource fetch failed (-1) http://192.168.43.252:30821/fake-right 
            // http://alistapart.com/article/application-cache-is-a-douchebag


            w.AppendLine("SETTINGS:");
            w.AppendLine("prefer-online");

            // http://html5doctor.com/go-offline-with-application-cache/
            // The first value is the request URI to match, and the second is the resource sent upon matching. It caches the resource on the right for offline use, so this should be an explicit path.
            //w.AppendLine("FALLBACK:");
            //w.AppendLine("/ /#offline");




            w.AppendLine("");
            w.AppendLine("NETWORK:");
            w.AppendLine("*");

            var now = DateTime.Now;

            // Application Cache Error event: Manifest changed during update, scheduling retry 
            w.AppendLine("");
            w.AppendLine("# " + new { bytes });
            w.AppendLine("");
            #endregion

            //            Implementation not found for type import :
            //type: System.Text.StringBuilder
            //method: Int32 get_Length()
            //Did you forget to add the [Script] attribute?
            //Please double check the signature!


            that.Response.AddHeader("Content-Length", "" + w.Length);
            // chrome://appcache-internals/
            that.Response.Write(w.ToString());


            that.CompleteRequest();
        }
 public static bool FileExists(InternalGlobal g)
 {
     return g.ToCurrentFile() != null;
 }
Ejemplo n.º 9
0
        // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/20151102
        // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2015/201510/20151022/httprequest

        public static void InternalApplication_BeginRequest(InternalGlobal g)
        {
            //Console.WriteLine("InternalApplication_BeginRequest " + new { Environment.StackTrace });

            // is it ROSLYN friendly? no?
            // need to compile it by 2012?
            //AppDomain.CurrentDomain.UnhandledException +=
            //    (s, e) =>
            //    {

            //    };


            var BeginRequestStopwatch = Stopwatch.StartNew();


            var that    = g.InternalApplication;
            var Context = that.Context;

            var Path = Context.Request.Path;

            #region WriteFile
            var CurrentFile = g.ToCurrentFile();

            if (CurrentFile != null)
            {
                // http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/


                //// http://www.mombu.com/programming/xbase/t-outputcache-directive-vs-responsecachesetcacheability-624773.html
                g.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
                g.Response.Cache.SetExpires(DateTime.Now.AddMinutes(15));

                //g.EndRequest +=
                //    (_s, _e) =>
                //    {
                //Console.WriteLine("cache " + CurrentFile.Name);


                //        // http://forums.asp.net/t/1123505.aspx
                //        HttpApplication application = (HttpApplication)_s;
                //        HttpContext context = application.Context;
                //g.Response.ExpiresAbsolute = DateTime.Now.AddDays(1);
                //context.Response.AddHeader("pragma", "no-cache");
                //g.Response.AddHeader("cache-control", "public");
                g.Response.AddHeader("Content-Length", "" + CurrentFile.Length);

                var ContentType = "application/octet-stream";
                var n           = CurrentFile.Name;

                // http://www.webmaster-toolkit.com/mime-types.shtml
                if (n.EndsWith(".gif"))
                {
                    ContentType = "image/gif";
                }
                else if (n.EndsWith(".htm"))
                {
                    ContentType = "text/html";
                }

                else if (n.EndsWith(".png"))
                {
                    ContentType = "image/png";
                }
                else if (n.EndsWith(".jpg"))
                {
                    ContentType = "image/jpg";
                }
                else if (n.EndsWith(".svg"))
                {
                    ContentType = "image/svg+xml";
                }

                else if (n.EndsWith(".js"))
                {
                    ContentType = "application/x-javascript";
                }

                else if (n.EndsWith(".mp3"))
                {
                    ContentType = "audio/mpeg3";
                }
                else if (n.EndsWith(".wav"))
                {
                    ContentType = "audio/wav";
                }
                else if (n.EndsWith(".mid"))
                {
                    ContentType = "audio/midi";
                }

                else if (n.EndsWith(".css"))
                {
                    ContentType = "text/css";
                }

                that.Response.ContentType = ContentType;

                // to root
                Context.Response.WriteFile("/" + CurrentFile.Name);

                that.CompleteRequest();

                //context.Response.CacheControl = "no-cache";
                //};

                // fake lag
                //if (that.Request.Path.EndsWith(".js"))
                //    System.Threading.Thread.Sleep(1000);
                return;
            }
            #endregion



            StringAction Write =
                e =>
            {
                // could we take the method pointer implicitly?
                Context.Response.Write(e);
            };

            StringAction WriteLine =
                e =>
            {
                // could we take the method pointer implicitly?
                Write(e + Environment.NewLine);
            };



            var WebMethods = g.GetWebMethods();



            // X:\jsc.svn\examples\javascript\test\TestBaseFieldSync\TestBaseFieldSync\ApplicationWebService.cs

            #region WriteInternalFields InternalFields -> AppendCookie
            Action <InternalWebMethodInfo> WriteInternalFields =
                x =>
            {
                // Z:\jsc.svn\examples\javascript\ubuntu\UbuntuSSLWebApplication\UbuntuSSLWebApplication\ApplicationWebService.cs


                // does 304 check also look at
                // fields?

                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201403/20140323
                // X:\jsc.svn\examples\javascript\forms\FormsDataBindingForEnabled\FormsDataBindingForEnabled\ApplicationWebService.cs

                if (x.InternalFields == null)
                {
                    return;
                }

                // typename instead?
                var c = new HttpCookie("InternalFields");
                // X:\jsc.svn\examples\javascript\Test\TestWebServiceTaskFields\TestWebServiceTaskFields\ApplicationWebService.cs

                // X:\jsc.svn\examples\javascript\test\TestNullObjectFromWebService\TestNullObjectFromWebService\ApplicationWebService.cs

                foreach (string InternalFieldName in x.InternalFields.Keys.ToArray())
                {
                    var value = x.InternalFields[InternalFieldName];

                    //Console.WriteLine("WriteInternalFields " + new { InternalFieldName, value });

                    if (value != null)
                    {
                        // for /xml post
                        if (Context.Request.HttpMethod == "POST")
                        {
                            // GetParameterValue: { key = _0600000e_field_elapsed }

                            // if we write her. where are they read?
                            // Z:\jsc.svn\examples\javascript\Test\TestFirefoxWebServiceField\ApplicationWebService.cs
                            // firefox filters out spaces?
                            that.Context.Response.AddHeader(
                                ".field-" + InternalFieldName,
                                value
                                );

                            // .field-field_foo:<_02000013>%0d%0a  <_04000021>Z3Vlc3Q=</_04000021>%0d%0a</_02000013>
                            // Z:\jsc.svn\examples\javascript\Test\TestAfterInvokeResponseHeaders\ApplicationWebService.cs

                            // 204 No Content ?
                        }
                        else
                        {
                            // for / get
                            c[InternalFieldName] = value;
                        }
                    }
                }

                // Set-Cookie:InternalFields=field_Foo=7; path=/
                //that.Context.Response.AppendCookie(c);
                if (Context.Request.HttpMethod == "POST")
                {
                }
                else
                {
                    that.Context.Response.SetCookie(c);
                }
            };
            #endregion



            var IsComplete = false;

            #region handler = WebServiceHandler
            var handler = new WebServiceHandler
            {
                ClientCertificate = g.ClientCertificate,
                ClientTrace       = g.ClientTrace,

                Context = that.Context,

                CompleteRequest = delegate
                {
                    IsComplete = true;
                    that.CompleteRequest();
                },

                Applications = g.GetScriptApplications(),

                // tested by
                // X:\jsc.svn\examples\javascript\synergy\webgl\EvilChopperByPer\EvilChopperByPer\ApplicationWebService.cs
                // X:\jsc.svn\examples\javascript\synergy\webgl\WebGLDoomByInt13h\WebGLDoomByInt13h\ApplicationWebService.cs
                GetFiles = g.GetFiles,


                #region Default
                Default = delegate
                {
                    that.Response.ContentType = "text/html";
                    //that.Response.AddHeader("Access-Control-Allow-Origin", "*");

                    // todo: jsc: PHP workaround required
                    var apps = g.GetScriptApplications();
                    var app  = apps[0];



                    var Host = that.Context.Request.Headers["Host"].TakeUntilIfAny(":");

                    var CacheManifest = false;
                    //var CacheManifest = true;

                    // should disable that for android webview?

                    //if (Host == that.Context.Request.UserHostAddress)
                    //    CacheManifest = false;

                    //// webdev?
                    //if ("127.0.0.1" == that.Context.Request.UserHostAddress)
                    //    CacheManifest = false;

                    // X:\jsc.svn\examples\javascript\test\TestServiceWorkerAssetCache\TestServiceWorkerAssetCache\Application.cs
                    app.WriteTo(Write, CacheManifest);

                    IsComplete = true;
                    that.CompleteRequest();
                },
                #endregion


                Diagnostics = delegate
                {
                    that.Response.ContentType = "text/html";
                    WriteDiagnostics(g, Write, WebMethods);

                    IsComplete = true;
                    that.CompleteRequest();
                },

                Redirect = delegate
                {
                    that.Response.Redirect("/#" + that.Request.Path);

                    IsComplete = true;
                    that.CompleteRequest();
                }
            };
            #endregion

            #region handler.WriteSource
            handler.WriteSource = app =>
            {
                handler.Context.Response.ContentType = "text/javascript";

                g.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);

                // are we not part of AppCache?
                g.Response.Cache.SetExpires(DateTime.Now.AddMinutes(15));

                //Console.WriteLine("IsConstructor WriteInternalFields");

                var Constructor = new InternalWebMethodInfo
                {
                    IsConstructor = true
                };

                // Method not found: '?'.
                // Additional information: Attempt by method 'mscorlib.<02000005IEnumerable\+ConvertToString>.ConvertToString(System.Collections.Generic.IEnumerable`1<TestIEnumerableForService.foo>)'
                // to access method '<>f__AnonymousType6`1<System.__Canon>..ctor(System.__Canon)' failed.
                g.Invoke(Constructor);

                WriteInternalFields(Constructor);



                #region GetFiles
                var ff = g.GetFiles();

                // jsc packages js files? not for long:P will switch to gzip at some point!
                var app_references = app.References.Select(
                    // why wont Single work correctly?
                    // are we embedding one file multiple times?
                    item => ff.First(k => k.Name == item.AssemblyFile || k.Name == item.AssemblyFile + ".js")
                    ).ToArray();
                #endregion



                app_references.WithEachIndex(
                    (app_ref, index) =>
                {
                    // will this work an all platforms?
                    // need to test!
                    g.Response.AddHeader("X-Reference-" + index, app_ref.Name + " " + app_ref.Length);
                }
                    );


                // tested by
                // X:\jsc.svn\examples\javascript\android\com.abstractatech.adminshell\com.abstractatech.adminshell\ApplicationWebService.cs
                #region DiagnosticsMakeItSlowAndAddSalt
                if (app.DiagnosticsMakeItSlowAndAddSalt)
                {
                    Console.WriteLine("enter DiagnosticsMakeItSlowAndAddSalt");

                    handler.Context.Response.ContentType = "application/octet-stream";


                    #region composite
                    var composite =
                        new CompositeStream(
                            app_references.Select(
                                k =>
                    {
                        return(new Func <Stream>(
                                   () =>
                        {
                            Console.WriteLine("composite: " + new { k.Name });
                            return (Stream)File.OpenRead(k.Name);
                        }
                                   ));
                    }
                                )
                            );
                    #endregion


                    Console.WriteLine("encrypting... ");

                    //var x = new MemoryStream();

                    var buffer = new byte[1024 * 40];
                    //var count = composite.GetBytes(buffer).Count();

                    #region count
                    var count = 0;


                    foreach (var y in composite.GetBytes(buffer))
                    {
                        count += y;

                        Console.WriteLine(new { count });
                    }

                    #endregion

                    // encrypting... { count = 58 }

                    Console.WriteLine("encrypting by splitting bytes... " + new { count });

                    var time = new Stopwatch();
                    time.Start();

                    var bytesleft = count;

                    g.Response.AddHeader("Content-Length", "" + (count * 2));
                    g.Response.AddHeader("X-DiagnosticsMakeItSlowAndAddSalt", "ok");


                    //                    lets write DiagnosticsMakeItSlowAndAddSalt
                    //enter DiagnosticsMakeItSlowAndAddSalt
                    //encrypting...
                    //enter GetBytes
                    //exit GetBytes
                    //encrypting... { count = 2282136 }
                    //enter GetBytes

                    // ?
                    // needs to work in .net then in android!

                    var xbuffer = new byte[buffer.Length * 2];

                    foreach (var length in composite.GetBytes(buffer))
                    {
                        Console.WriteLine("before flush of " + new { length });

                        for (int i = 0; i < length; i++)
                        {
                            var item = buffer[i];

                            var lo = (byte)(item & 0xf);
                            var hi = (byte)((item & 0xf0) >> 4);


                            xbuffer[i * 2 + 0] = lo;
                            xbuffer[i * 2 + 1] = hi;

                            //h.Context.Response.OutputStream.WriteByte(lo);
                            //h.Context.Response.OutputStream.WriteByte(hi);



                            bytesleft--;
                        }

                        handler.Context.Response.OutputStream.Write(xbuffer, 0, length * 2);
                        handler.Context.Response.Flush();

                        var timetarget = 8000 - time.ElapsedMilliseconds;

                        //                 Caused by: java.lang.ArithmeticException: divide by zero
                        //at ScriptCoreLib.Ultra.WebService.InternalGlobalExtensions___c__DisplayClasse._InternalApplication_BeginRequest_b__7(InternalGlobalExtensions___c__DisplayClasse.java:235)

                        //var ms = (int)(timetarget / bytesleft);



                        Console.WriteLine("." + new
                        {
                            bytesleft
                            //, ms
                        });

                        //if (timetarget > 0)
                        //{
                        //    Thread.Sleep(ms);
                        //}
                    }



                    Console.WriteLine("will upload done " + new { time.ElapsedMilliseconds });

                    return;
                }
                #endregion


                #region GZipAssemblyFile
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2013/201301/20130103

                var AcceptEncoding = handler.Context.Request.Headers["Accept-Encoding"];

                if (!string.IsNullOrEmpty(AcceptEncoding))
                {
                    if (AcceptEncoding.Contains("gzip"))
                    {
                        g.Response.AddHeader("Content-Encoding", "gzip");



                        g.Response.WriteFile("/" + app.GZipAssemblyFile);
                        handler.CompleteRequest();

                        return;
                    }
                }
                #endregion

                g.Response.AddHeader("X-Comment", "gzip was disabled");

                #region the old way


                var app_size = app_references.Sum(k => k.Length);

                // Accept-Encoding:gzip,deflate,sdch

                g.Response.AddHeader("Content-Length", "" + app_size);
                //g.Response.AddHeader("X-GZipAssemblyFile", "" + app.GZipAssemblyFile);


                foreach (var item in app_references)
                {
                    // asp.net needs absolute paths
                    handler.Context.Response.WriteFile("/" + item.Name);
                }
                #endregion


                handler.CompleteRequest();
            };
            #endregion


            #region WebMethodMetadataToken
            if (Context.Request.HttpMethod == "POST")
            {
                var cWebMethodMetadataToken = Context.Request.Form.AllKeys.Contains("WebMethodMetadataToken");

                //Console.WriteLine("POST is expected to include WebMethodMetadataToken " + new { cWebMethodMetadataToken });
                // X:\jsc.svn\core\ScriptCoreLib\JavaScript\BCLImplementation\System\Net\WebClient.cs

                // who sets WebMethodMetadataToken ?
                // X:\jsc.svn\core\ScriptCoreLib.Ultra\ScriptCoreLib.Ultra\JavaScript\Remoting\InternalWebMethodRequest.cs
                // C:\Users\Arvo\AppData\Local\Temp\6796$ScriptCoreLib.Ultra.dll$v4.0.30319$NoDynamic\ScriptCoreLib.JavaScript.Remoting.InternalWebMethodRequest.cs

                // X:\jsc.svn\examples\javascript\css\Test\TestLongWebMethod\TestLongWebMethod\Application.cs

                // tested by
                // X:\jsc.svn\examples\javascript\Test\TestWebMethodIPAddress\TestWebMethodIPAddress\ApplicationWebService.cs
                // X:\jsc.internal.svn\compiler\jsc.meta\jsc.meta\Library\Templates\JavaScript\InternalWebMethodRequest.cs
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201401/20140110-xml

                //var WebMethodMetadataToken = Context.Request.QueryString[InternalWebMethodInfo.QueryKey];

                if (cWebMethodMetadataToken)
                {
                    var WebMethodMetadataToken = Context.Request.Form["WebMethodMetadataToken"];
                    //var value_Form = that.InternalContext.Request.Form[key];

                    // Z:\jsc.svn\examples\javascript\appengine\Test\TestUserHostAddress\ApplicationWebService.cs

                    if (WebMethodMetadataToken != null)
                    {
                        handler.WebMethod = InternalWebMethodInfo.First(
                            WebMethods,
                            WebMethodMetadataToken
                            );
                    }
                }
            }
            #endregion


            g.Serve(handler);

            if (IsComplete)
            {
                return;
            }


            #region POST
            if (Context.Request.HttpMethod == "POST")
            {
                // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140101
                //Console.WriteLine("about to load params for " + new { handler.WebMethod });

                if (handler.WebMethod == null)
                {
                    // let user defined handler handle it..
                }
                else
                {
                    // is it also supposed to load the fields?
                    handler.WebMethod.LoadParameters(that.Context);

                    //Console.WriteLine("enter invoke " + new { handler.WebMethod });

                    //about to load params for { WebMethod = { IsConstructor = false, MetadataToken = 06000002, Name = Insert, TypeFullName = WebCamAvatarsExperiment.ApplicationWebService, Parameters = 1 } }
                    //about to invoke { WebMethod = { IsConstructor = false, MetadataToken = 06000002, Name = Insert, TypeFullName = WebCamAvatarsExperiment.ApplicationWebService, Parameters = 1 } }
                    // when can we invoke the webmethod and not be at /xml?

                    //try
                    //{

                    // where is the code gen?
                    // X:\jsc.internal.svn\compiler\jsc.meta\jsc.meta\Commands\Rewrite\RewriteToJavaScriptDocument.WebService.cs

                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140107-dev/test
                    var WebMethodStopwatch = Stopwatch.StartNew();

                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201404/20140405/task
                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201405/20140517
                    // defined by X:\jsc.internal.svn\compiler\jsc.meta\jsc.meta\Commands\Rewrite\RewriteToJavaScriptDocument.WebService.cs

                    // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201408/20140811

                    // public abstract void Invoke(InternalWebMethodInfo e);
                    g.Invoke(handler.WebMethod);


                    // BeginRequestStopwatch
                    //that.Response.AddHeader("X-BeginRequestStopwatch", "" + BeginRequestStopwatch.ElapsedMilliseconds);

                    // https://sites.google.com/a/jsc-solutions.net/work/knowledge-base/04-monese/2014/201401/20140110-stats
                    that.Response.AddHeader("X-ElapsedMilliseconds", "" + WebMethodStopwatch.ElapsedMilliseconds);
                    //that.Response.AddHeader("Access-Control-Allow-Origin", "*");

                    if (handler.WebMethod.AtElapsedMilliseconds != null)
                    {
                        handler.WebMethod.AtElapsedMilliseconds(WebMethodStopwatch.ElapsedMilliseconds);
                    }

                    //that.Response.AddHeader("X-WebMethodStopwatch", "" + SQLiteConnectionStringBuilderExtensions.ElapsedMilliseconds);

                    //}
                    //catch (Exception err)
                    //{
                    //    Console.WriteLine("boom! " + new { err });
                    //}

                    //Console.WriteLine("exit invoke " + new { handler.WebMethod });

                    //if (that.Context.Request.Path == "/xml")
                    if (that.Context.Request.Path != "/jsc")
                    {
                        // the diagnostics needs more attention down the road.


                        WriteInternalFields(handler.WebMethod);

                        // no yields
                        // why is handler.WebMethod.Results null??
                        #region 204
                        if (handler.WebMethod.Results.Length == 0)
                        {
                            if (handler.WebMethod.TaskResult == null)
                            {
                                // or should we send binary zip for webworker?
                                // NoContent
                                g.Context.Response.StatusCode = 204;
                                g.Context.Response.Flush();

                                that.CompleteRequest();
                                return;
                            }
                        }
                        #endregion


                        WriteXDocument(g, Write, handler.WebMethod);
                        that.CompleteRequest();
                        return;
                    }

                    that.Response.ContentType = "text/html";
                    WriteDiagnosticsResults(Write, handler.WebMethod);
                    WriteDiagnostics(g, Write, WebMethods);
                    that.CompleteRequest();
                    return;
                }
            }
            #endregion


            if (IsComplete)
            {
                return;
            }


            #region /favicon.ico
            if (Path == "/favicon.ico")
            {
                Context.Response.WriteFile("assets/ScriptCoreLib/jsc.ico");

                that.CompleteRequest();
                return;
            }
            #endregion



            #region /robots.txt
            if (Path == "/robots.txt")
            {
                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }
            #endregion

            #region /crossdomain.xml
            if (Path == "/crossdomain.xml")
            {
                // X:\jsc.svn\core\ScriptCoreLib.Ultra.Library\ScriptCoreLib.Ultra.Library\Ultra\WebService\InternalGlobalExtensions.InternalApplication_BeginRequest.cs
                // https://sites.google.com/a/jsc-solutions.net/backlog/knowledge-base/2014/201401/20140109-webclient
                // http://www.adobe.com/devnet/adobe-media-server/articles/cross-domain-xml-for-streaming.html
                // X:\jsc.smokescreen.svn\market\appengine\xmoneseAIR\xmoneseAIR\ApplicationCanvas.cs
                Context.Response.Write(@"<?xml version='1.0'?>
<!-- http://www.osmf.org/crossdomain.xml -->
<!DOCTYPE cross-domain-policy SYSTEM 'http://www.adobe.com/xml/dtds/cross-domain-policy.dtd'>
<cross-domain-policy>
    <allow-access-from domain='*' />
    <site-control permitted-cross-domain-policies='all'/>
</cross-domain-policy>");

                that.CompleteRequest();
                return;
            }
            #endregion


            // cache manifest will not be needed
            // after ServiceWorker becomes useful
            // 20141230
            // X:\jsc.svn\examples\javascript\test\TestServiceWorkerAssetCache\TestServiceWorkerAssetCache\Application.cs
            #region WriteCacheManifest
            if (Path == "/" + WebApplicationCacheManifest.ManifestName)
            {
                // <html manifest="cache-manifest">

                //WriteCacheManifest(g, that, WriteLine);

                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }
            #endregion



            if (that.Request.Path == "/jsc")
            {
                handler.Diagnostics();
                return;
            }

            #region /view-source
            if (that.Request.Path == "/view-source")
            {
                var app = handler.Applications[0];

                // can we just invoke a ctor?
                // and have the fields returne?

                handler.WriteSource(app);

                return;
            }
            #endregion


            if (handler.IsDefaultPath)
            {
                handler.Default();
                return;
            }

            if (Context.Request.HttpMethod == "POST")
            {
                // Z:\jsc.svn\examples\javascript\test\TestMultipartRelated\Application.cs
                // Z:\jsc.svn\examples\javascript\ubuntu\UbuntuDualSSLWebApplication\UbuntuDualSSLWebApplication\ApplicationWebService.cs
                Console.WriteLine("invalid invoke? IE is that you?");

                // we dont know what to do with this POST..
                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }

            // we could invoke web service handler now?
            handler.Redirect();
            //h.Diagnostics();
        }
        public static void InternalApplication_BeginRequest(InternalGlobal g)
        {
            var that = g.InternalApplication;
            var Context = that.Context;

            var Path = Context.Request.Path;

            var CurrentFile = g.ToCurrentFile();

            if (CurrentFile != null)
            {
                // http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/


                //// http://www.mombu.com/programming/xbase/t-outputcache-directive-vs-responsecachesetcacheability-624773.html
                //g.Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
                //g.Response.Cache.SetExpires(DateTime.Now.AddMinutes(15));


                g.Response.AddHeader("x-handler", "http://jsc-solutions.net");

                // to root
                Context.Response.WriteFile("/" + CurrentFile.Name);

                that.CompleteRequest();

                return;
            }



            if (Path == "/favicon.ico")
            {
                Context.Response.WriteFile("assets/ScriptCoreLib/jsc.ico");

                that.CompleteRequest();
                return;
            }



            if (Path == "/robots.txt")
            {
                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }

            if (Path == "/crossdomain.xml")
            {
                Context.Response.StatusCode = 404;
                that.CompleteRequest();
                return;
            }

            StringAction Write =
              e =>
              {
                  // could we take the method pointer implicitly?
                  Context.Response.Write(e);
              };

            StringAction WriteLine =
                e =>
                {
                    // could we take the method pointer implicitly?
                    Write(e + Environment.NewLine);
                };

            var WebMethods = g.GetWebMethods();

            var IsComplete = false;

            that.Response.ContentType = "text/html";
            WriteDiagnostics(g, Write, WebMethods);


            IsComplete = true;
            that.CompleteRequest();
        }
        public static void WriteDiagnostics(InternalGlobal g, StringAction Write, InternalWebMethodInfo[] WebMethods)
        {
            // should the diagnostics be a separate rich Browser Application? :)

            var Context = g.InternalApplication.Context;

            Write("<title>jsc-solutions.net</title>");

            Write("<center>");
            Write("<div style='background-color: black; color: white; padding: 2em;'>");
            Write("&laquo; Rotate your device to left to <b>launch</b>");
            Write("</div>");
            Write("</center>");

            Write("<br/><center><a href='/'>Launch Application</a></center><br/>");

            //Write("<h1>" + Context.Request.Headers["Host"] + "</h1>");

            foreach (var HeaderKey in Context.Request.Headers.AllKeys)
            {
                var HeaderValue = Context.Request.Headers[HeaderKey];

                Write("<code style='color: gray;'>" + HeaderKey + "</code>:");
                Write("<code style='color: green;'>" + HeaderValue + "</code><br />");
            }


            Write("<a href='http://jsc-solutions.net'><img border='0' src='/assets/ScriptCoreLib/jsc.png' /></a>");

            #region Special pages
            Write("<h2>Special pages</h2>");


            Write("<br /> " + "special page: " + "<a href='/robots.txt'>/robots.txt</a>");
            Write("<br /> " + "special page: " + "<a href='/xml'>/xml</a>");
            Write("<br /> " + "special page: " + "<a href='/crossdomain.xml'>/crossdomain.xml</a>");
            Write("<br /> " + "special page: " + "<a href='/favicon.ico'>/favicon.ico</a>");
            Write("<br /> " + "special page: " + "<a href='/jsc'>/jsc</a>");
            #endregion

            Write("<h2>WebMethods (" + WebMethods.Length + ")</h2>");



            foreach (var item in WebMethods)
            {
                InternalGlobalExtensions.WriteWebMethodForm(Write, item);
            }


            //Write("<br /> Path: '" + Context.Request.Path + "'");
            //Write("<br /> HttpMethod: '" + Context.Request.HttpMethod + "'");

            Write("<h2>Form</h2>");
            foreach (var item in Context.Request.Form.AllKeys)
            {
                Write("<br /> " + "<img src='http://i.msdn.microsoft.com/w144atby.pubproperty(en-us,VS.90).gif' /> <code>");
                Write(item);
                Write(" = ");
                Write(escapeXML(Context.Request.Form[item]));
                Write("</code>");
            }

            #region QueryString
            Write("<h2>QueryString</h2>");
            foreach (var item in Context.Request.QueryString.AllKeys)
            {
                Write("<br /> " + "<img src='http://i.msdn.microsoft.com/w144atby.pubproperty(en-us,VS.90).gif' /> <code>");
                Write(item);
                Write(" = ");
                Write(escapeXML(Context.Request.QueryString[item]));
                Write("</code>");
            }
            #endregion


            Write("<h2>Script Applications</h2>");

            foreach (var item in g.GetScriptApplications())
            {
                Write("<br /> " + "script application: " + item.TypeName);

                foreach (var r in item.References)
                {
                    Write("<br /> &nbsp;&nbsp;&nbsp;&nbsp;");

                    Write("<img src='http://i.msdn.microsoft.com/yxcx7skw.pubclass(en-us,VS.90).gif' /> reference: ");
                    Write(r.AssemblyFile);

                }
            }

            Write("<h2>Files</h2>");

            foreach (var item in g.GetFiles())
            {
                Write("<br /> " + " file: <a href='" + item.Name + "'>" + item.Name + "</a>");
            }



        }