Esempio n. 1
0
 internal static async Task ManageRequest(HttpContext context, FileContentReference fileContent, string contentType = "application/javascript")
 {
     await ManageRequestHeaders(context, contentType, fileContent.ETag, fileContent.ContentLength, async() =>
     {
         await context.Response.WriteAsync(fileContent.Value);
     });
 }
Esempio n. 2
0
        private static FileContentReference GetPatchedBlazorServerFile()
        {
            if (_patchedBlazorServerFile == null)
            {
                var assembly = GetAspNetCoreComponentsServerAssembly();

                var resources    = assembly.GetManifestResourceNames();
                var resourceName = resources.Single(str => str.EndsWith("blazor.server.js"));

                using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                    using (StreamReader reader = new StreamReader(stream))
                    {
                        string js = reader.ReadToEnd();

                        //Patch Descriptor Regex as it make Babel crash during transform
                        js = js.Replace("/\\W*Blazor:[^{]*(?<descriptor>.*)$/;", @"/[\0-\/:-@\[-\^`\{-\uFFFF]*Blazor:(?:(?!\{)[\s\S])*(.*)$/;");

                        //Transpile code to ES5 for IE11 before manual patching
                        js = Transform(js, "blazor.server.js", "{\"plugins\":[\"proposal-class-properties\",\"proposal-object-rest-spread\"],\"presets\":[[\"env\",{\"targets\":{\"browsers\":[\"ie 11\"]}}], \"es2015\",\"es2016\",\"es2017\",\"stage-3\"], \"sourceType\": \"script\"}");

                        //At this point, Babel has unminified the code, and fixed IE11 issues, like 'import' method calls.
                        //We still need to fix 'descriptor' regex evaluation code, as it was expecting a named capture group.
                        js = Regex.Replace(js, "([a-zA-Z]+)(.groups[ ]*&&[ ]*[a-zA-Z]+.groups.descriptor)", "$1[1]");

                        //Minify with AjaxMin (we don't want an additional external tool with NPM or else for managing this
                        //kind of thing here...
                        js = Uglify.Js(js).Code;

                        //Computing ETag. Should be computed last !
                        string Etag = EtagGenerator.GenerateEtagFromString(js);

                        //Computing Build time for the Last-Modified Http Header
                        //We should rely on the creation date of the Microsoft API
                        //not the Blazor.Polyfill.Server one as the Microsoft.AspNetCore.Components.Server
                        //assembly may be updated in time. We will rely on the current creation/modification date on disk
                        DateTime buildTime = GetAssemblyCreationDate(assembly);

                        _patchedBlazorServerFile = new FileContentReference()
                        {
                            Value         = js,
                            ETag          = Etag,
                            LastModified  = buildTime,
                            ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                        };
                    }
            }

            return(_patchedBlazorServerFile);
        }
        internal static async Task ManageRequest(HttpContext context, FileContentReference fileContent, string contentType = "application/javascript")
        {
            context.Response.ContentType = contentType;
            context.Response.Headers.Append(HeaderNames.CacheControl, "no-cache");
            context.Response.Headers.Append(HeaderNames.LastModified, fileContent.LastModified.ToString("r"));
            context.Response.Headers.Append(HeaderNames.ETag, fileContent.ETag);

            //In this case we should return the entire response
            if (RequestHasTheNoCacheHeaderSet(context.Request) ||
                RequestHasNoCachingFeatureSet(context.Request) ||
                RequestHasCacheFeaturesExpired(context.Request, fileContent))
            {
                context.Response.Headers.Append(HeaderNames.ContentLength, fileContent.ContentLength);
                context.Response.StatusCode = (int)HttpStatusCode.OK;
                await context.Response.WriteAsync(fileContent.Value);
            }
            else
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotModified;
            }
        }
        private static bool RequestHasCacheFeaturesExpired(HttpRequest request, FileContentReference fileContent)
        {
            string IfModifiedSince = null;
            string IfNoneMatch     = null;

            DateTime IfModifiedSinceDate = default;

            //Must be in first check, as the library may update in the future but we can't be totally aware of the modification
            //date as it's related to the Microsoft library, not this one.
            if (request.Headers.ContainsKey(HeaderNames.IfNoneMatch))
            {
                IfNoneMatch = request.Headers[HeaderNames.IfNoneMatch].ToString();

                if (fileContent.ETag == IfNoneMatch)
                {
                    return(false);
                }
                else
                {
                    return(true);
                }
            }
            else if (request.Headers.ContainsKey(HeaderNames.IfModifiedSince))
            {
                IfModifiedSince = request.Headers[HeaderNames.IfModifiedSince].ToString();
                if (DateTime.TryParseExact(IfModifiedSince, "r", CultureInfo.InvariantCulture, DateTimeStyles.None, out IfModifiedSinceDate))
                {
                    if (IfModifiedSinceDate == fileContent.LastModified)
                    {
                        return(false);
                    }
                    else
                    {
                        return(true);
                    }
                }
            }

            return(true);
        }
Esempio n. 5
0
        private static FileContentReference GetBlazorPolyfillFile(bool isIE11, bool isMinified)
        {
            if (!isIE11)
            {
                if (_fakeie11Polyfill == null)
                {
                    var assembly = GetBlazorPolyfillAssembly();

                    var resources    = assembly.GetManifestResourceNames();
                    var resourceName = resources.Single(str => str.EndsWith("fake.polyfill.js"));

                    using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            string js = reader.ReadToEnd();

                            //Computing ETag. Should be computed last !
                            string Etag = CryptographyHelper.CreateSHA256(js);

                            //Computing Build time for the Last-Modified Http Header
                            DateTime buildTime = GetBlazorPolyfillServerBuildDate();

                            _fakeie11Polyfill = new FileContentReference()
                            {
                                Value         = js,
                                ETag          = Etag,
                                LastModified  = buildTime,
                                ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                            };
                        }
                    }
                }

                return(_fakeie11Polyfill);
            }
            else
            {
                if (isMinified)
                {
                    if (_ie11PolyfillMin == null)
                    {
                        var assembly = GetBlazorPolyfillAssembly();

                        var resources    = assembly.GetManifestResourceNames();
                        var resourceName = resources.Single(str => str.EndsWith("blazor.polyfill.min.js"));

                        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                string js = reader.ReadToEnd();

                                //Should inject es5 module override before launch
                                js = GetOptions().GetJavascriptToInject() + js;

                                //Computing ETag. Should be computed last !
                                string Etag = CryptographyHelper.CreateSHA256(js);

                                //Computing Build time for the Last-Modified Http Header
                                DateTime buildTime = GetBlazorPolyfillServerBuildDate();

                                _ie11PolyfillMin = new FileContentReference()
                                {
                                    Value         = js,
                                    ETag          = Etag,
                                    LastModified  = buildTime,
                                    ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                                };
                            }
                        }
                    }

                    return(_ie11PolyfillMin);
                }
                else
                {
                    if (_ie11Polyfill == null)
                    {
                        var assembly = GetBlazorPolyfillAssembly();

                        var resources    = assembly.GetManifestResourceNames();
                        var resourceName = resources.Single(str => str.EndsWith("blazor.polyfill.js"));

                        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                        {
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                string js = reader.ReadToEnd();

                                //Should inject es5 module override before launch
                                js = GetOptions().GetJavascriptToInject() + js;

                                //Computing ETag. Should be computed last !
                                string Etag = CryptographyHelper.CreateSHA256(js);

                                //Computing Build time for the Last-Modified Http Header
                                DateTime buildTime = GetBlazorPolyfillServerBuildDate();

                                _ie11Polyfill = new FileContentReference()
                                {
                                    Value         = js,
                                    ETag          = Etag,
                                    LastModified  = buildTime,
                                    ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                                };
                            }
                        }
                    }

                    return(_ie11Polyfill);
                }
            }
        }
Esempio n. 6
0
        private static FileContentReference GetPatchedBlazorServerFile()
        {
            if (_patchedBlazorServerFile == null)
            {
                BlazorPolyfillOptions option = GetOptions();

                if (option.UsePackagedBlazorServerLibrary)
                {
                    //Get packaged blazor.server.js
                    var assembly = GetBlazorPolyfillAssembly();

                    var resources    = assembly.GetManifestResourceNames();
                    var resourceName = resources.Single(str => str.EndsWith("blazor.server.packaged.js"));

                    using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            string js = reader.ReadToEnd();

                            string Etag = CryptographyHelper.CreateSHA256(js);

                            //We should rely on ETag and not on LastModifed informations
                            DateTime buildTime = GetAssemblyCreationDate(assembly);

                            _patchedBlazorServerFile = new FileContentReference()
                            {
                                Value         = js,
                                ETag          = Etag,
                                LastModified  = buildTime,
                                ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                            };
                        }
                    }
                }
                else
                {
                    var assembly = GetAspNetCoreComponentsServerAssembly();

                    var resources    = assembly.GetManifestResourceNames();
                    var resourceName = resources.Single(str => str.EndsWith("blazor.server.js"));

                    using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                    {
                        using (StreamReader reader = new StreamReader(stream))
                        {
                            string js = reader.ReadToEnd();


                            #region Patch Regex

                            //Patch Descriptor Regex as it make Babel crash during transform
                            js = js.Replace("/\\W*Blazor:[^{]*(?<descriptor>.*)$/;", @"/[\0-\/:-@\[-\^`\{-\uFFFF]*Blazor:(?:(?!\{)[\s\S])*(.*)$/;");

                            js = js.Replace("/^\\s*Blazor-Component-State:(?<state>[a-zA-Z0-9\\+\\/=]+)$/", @"/^[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*Blazor\x2DComponent\x2DState:([\+\/-9=A-Za-z]+)$/");

                            js = js.Replace("/^\\s*Blazor:[^{]*(?<descriptor>.*)$/", @"/^[\t-\r \xA0\u1680\u2000-\u200A\u2028\u2029\u202F\u205F\u3000\uFEFF]*Blazor:(?:(?!\{)[\s\S])*(.*)$/");

                            #endregion Patch Regex

                            //Transpile code to ES5 for IE11 before manual patching
                            js = BabelHelper.Transform(js, "blazor.server.js");

                            #region Regex named groups fix

                            //At this point, Babel has unminified the code, and fixed IE11 issues, like 'import' method calls.

                            //We still need to fix 'descriptor' regex evaluation code, as it was expecting a named capture group.
                            js = Regex.Replace(js, "([_a-zA-Z0-9]+)(.groups[ ]*&&[ ]*[_a-zA-Z0-9]+.groups.descriptor)", "$1[1]");

                            //We still need to fix 'state' regex evaluation code, as it was expecting a named capture group.
                            js = Regex.Replace(js, "([_a-zA-Z0-9]+)(.groups[ ]*&&[ ]*[_a-zA-Z0-9]+.groups.state)", "$1[1]");

                            //Here we fix invalids interopRequireWildcard(require(''.concat(n))) to _interopRequireWildcard(''.concat(n)) (works for '' or "")
                            //Warning: " is written "" here but must be read as " from the regex logic: We are in a verbatim string
                            js = Regex.Replace(js, @"(require\((['""]['""].concat\([a-zA-Z]+\))\))", "$2");

                            #endregion Regex named groups fix

                            //Minify with AjaxMin (we don't want an additional external tool with NPM or else for managing this
                            //kind of thing here...
                            js = Uglify.Js(js).Code;

                            //Computing ETag. Should be computed last !
                            string Etag = CryptographyHelper.CreateSHA256(js);

                            //Computing Build time for the Last-Modified Http Header
                            //We should rely on the creation date of the Microsoft API
                            //not the Blazor.Polyfill.Server one as the Microsoft.AspNetCore.Components.Server
                            //assembly may be updated in time. We will rely on the current creation/modification date on disk
                            DateTime buildTime = GetAssemblyCreationDate(assembly);

                            _patchedBlazorServerFile = new FileContentReference()
                            {
                                Value         = js,
                                ETag          = Etag,
                                LastModified  = buildTime,
                                ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                            };
                        }
                    }
                }
            }

            return(_patchedBlazorServerFile);
        }
Esempio n. 7
0
        private static FileContentReference GetIE11BlazorPolyfill(bool isIE11, bool isMinified)
        {
            if (!isIE11)
            {
                if (_fakeie11Polyfill == null)
                {
                    string fakeContent = "var _fakeBlazorPolyfill = { };";

                    //Computing ETag. Should be computed last !
                    string Etag = EtagGenerator.GenerateEtagFromString(fakeContent);

                    //Computing Build time for the Last-Modified Http Header
                    DateTime buildTime = GetBlazorPolyfillServerBuildDate();

                    _fakeie11Polyfill = new FileContentReference()
                    {
                        Value         = fakeContent,
                        ETag          = Etag,
                        LastModified  = buildTime,
                        ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(fakeContent).ToString(CultureInfo.InvariantCulture)
                    };
                }

                return(_fakeie11Polyfill);
            }
            else
            {
                if (isMinified)
                {
                    if (_ie11PolyfillMin == null)
                    {
                        var assembly = GetBlazorPolyfillAssembly();

                        var resources    = assembly.GetManifestResourceNames();
                        var resourceName = resources.Single(str => str.EndsWith("blazor.polyfill.min.js"));

                        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                string js = reader.ReadToEnd();

                                //Computing ETag. Should be computed last !
                                string Etag = EtagGenerator.GenerateEtagFromString(js);

                                //Computing Build time for the Last-Modified Http Header
                                DateTime buildTime = GetBlazorPolyfillServerBuildDate();

                                _ie11PolyfillMin = new FileContentReference()
                                {
                                    Value         = js,
                                    ETag          = Etag,
                                    LastModified  = buildTime,
                                    ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                                };
                            }
                    }

                    return(_ie11PolyfillMin);
                }
                else
                {
                    if (_ie11Polyfill == null)
                    {
                        var assembly = GetBlazorPolyfillAssembly();

                        var resources    = assembly.GetManifestResourceNames();
                        var resourceName = resources.Single(str => str.EndsWith("blazor.polyfill.js"));

                        using (Stream stream = assembly.GetManifestResourceStream(resourceName))
                            using (StreamReader reader = new StreamReader(stream))
                            {
                                string js = reader.ReadToEnd();

                                //Computing ETag. Should be computed last !
                                string Etag = EtagGenerator.GenerateEtagFromString(js);

                                //Computing Build time for the Last-Modified Http Header
                                DateTime buildTime = GetBlazorPolyfillServerBuildDate();

                                _ie11Polyfill = new FileContentReference()
                                {
                                    Value         = js,
                                    ETag          = Etag,
                                    LastModified  = buildTime,
                                    ContentLength = System.Text.UTF8Encoding.UTF8.GetByteCount(js).ToString(CultureInfo.InvariantCulture)
                                };
                            }
                    }

                    return(_ie11Polyfill);
                }
            }
        }