private void handleEndRequest(object sender, EventArgs e) { if (!FrameworkInitialized || RequestState == null) { return; } // Do not set a status code since we may have already set one or set a redirect page. ExecuteWithBasicExceptionHandling(() => RequestState.CleanUp(), false, false); RequestState = null; }
private void handleBeginRequest(object sender, EventArgs e) { if (!FrameworkInitialized) { // We can't redirect to a normal page to communicate this information because since initialization failed, the request for that page will trigger // another BeginRequest event that puts us in an infinite loop. We can't rely on anything except an HTTP return code. Suppress exceptions; there is no // way to report them since even our basic exception handling may not work if the application isn't initialized. try { set500StatusCode("Initialization Failure"); } catch {} return; } ExecuteWithBasicExceptionHandling( delegate { if (RequestState != null) { RequestState = null; throw new ApplicationException("AppRequestState was not properly cleaned up from a previous request."); } // This used to be just HttpContext.Current.Request.Url, but that doesn't work with Azure due to the use of load balancing. An Azure load balancer // will bind to the ip/host/port through which all web requests should come in, and then the request is redirected to one of the server instances // running this web application. For example, a user will request mydomain.com. In Azure, there may be two instances running this web site, on // someIp:81 and someIp:82. For some reason, HttpContext.Current.Request.Url ends up using the host and port from one of these addresses instead of // using the host and port from the HTTP Host header, which is what the client is actually "viewing". Basically, HttpContext.Current.Request.Url // returns http://someIp:81?something=1 instead of http://mydomain.com?something=1. See // http://stackoverflow.com/questions/9560838/azure-load-balancer-causes-400-error-invalid-hostname-on-postback. var baseUrl = getRequestBaseUrl(Request); if (!baseUrl.Any()) { setStatusCode(400); return; } var appRelativeUrl = GetRequestAppRelativeUrl(Request, disableLeadingSlashRemoval: true); // If the base URL doesn't include a path and the app-relative URL is just a slash, don't include this trailing slash in the URL since it will not be // present in the canonical URLs that we construct and therefore it would cause problems with URL normalization. var url = !getRequestBasePath(Request).Any() && appRelativeUrl.Length == "/".Length ? baseUrl : baseUrl + appRelativeUrl; // This blocks until the entire request has been received from the client. // This won't compile unless it is assigned to something, which is why it is unused. var stream = Request.InputStream; RequestState = new AppRequestState(url); }, false, true); }
private void handleEndRequest(object sender, EventArgs e) { if (!FrameworkInitialized || RequestState == null) { return; } ExecuteWithBasicExceptionHandling( delegate { try { // This 404 condition covers two types of requests: // 1. Requests where we set the status code in handleError // 2. Requests to handlers that set the status code directly instead of throwing exceptions, e.g. the IIS static file handler if (Response.StatusCode == 404 && !handleErrorIfOnErrorPage("A status code of 404 was produced", null)) { transferRequest(getErrorPage(MetaLogicFactory.CreatePageNotAvailableErrorPageInfo(!RequestState.HomeUrlRequest)), false); } if (RequestState.TransferRequestPath.Length > 0) { // NOTE: If we transfer to a path with no query string, TransferRequest adds the current query string. Because of this bug we need to make sure all // pages we transfer to have at least one parameter. Server.TransferRequest(RequestState.TransferRequestPath, false, "GET", null); } } catch { RequestState.RollbackDatabaseTransactions(); DataAccessState.Current.ResetCache(); throw; } }, true, true); // Do not set a status code since we may have already set one or set a redirect page. ExecuteWithBasicExceptionHandling(delegate { RequestState.CleanUp(); }, false, false); RequestState = null; }
/// <summary> /// Call this from Application_Start in your Global.asax.cs file. Besides this call, there should be no other code in the method. /// </summary> /// <param name="globalInitializer">The system's global initializer. Do not pass null.</param> /// <param name="appInitializer">The application initializer, which performs web-site specific initialization and cleanup. If you have one of these you /// should name the class AppInitializer.</param> public static void InitStatics(SystemInitializer globalInitializer, SystemInitializer appInitializer = null) { // This is a hack to support data-access state in WCF services. var wcfDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState()); // Initialize system. var initTimeDataAccessState = new ThreadLocal <DataAccessState>(() => new DataAccessState()); try { GlobalInitializationOps.InitStatics( globalInitializer, Path.GetFileName(Path.GetDirectoryName(HttpRuntime.AppDomainAppPath)), false, mainDataAccessStateGetter: () => { return(EwfApp.Instance != null ? EwfApp.Instance.RequestState != null ? EwfApp.Instance.RequestState.DataAccessState : initTimeDataAccessState.Value : System.ServiceModel.OperationContext.Current != null ? wcfDataAccessState.Value : null); }); } catch { // Suppress all exceptions since there is no way to report them. return; } ewlInitialized = true; // Initialize web application. if (!GlobalInitializationOps.SecondaryInitFailed) { EwfApp.ExecuteWithBasicExceptionHandling( () => { EwfConfigurationStatics.Init(); GlobalConfiguration.Configure(WebApiStatics.ConfigureWebApi); var miniProfilerOptions = new MiniProfilerOptions(); miniProfilerOptions.IgnoredPaths.Clear(); MiniProfiler.Configure(miniProfilerOptions); var globalType = BuildManager.GetGlobalAsaxType().BaseType; var providerGetter = new SystemProviderGetter( globalType.Assembly, globalType.Namespace + ".Providers", providerName => @"{0} provider not found in application. To implement, create a class named {0} in ""Your Web Site\Providers"" that derives from App{0}Provider." .FormatWith(providerName)); if (ExternalFunctionalityStatics.SamlFunctionalityEnabled) { ExternalFunctionalityStatics.ExternalSamlProvider.InitAppStatics( providerGetter, () => AuthenticationStatics.SamlIdentityProviders.Select( identityProvider => { using (var client = new HttpClient()) { client.Timeout = new TimeSpan(0, 0, 10); var metadata = Task.Run( async() => { using (var response = await client.GetAsync(identityProvider.MetadataUrl, HttpCompletionOption.ResponseHeadersRead)) { response.EnsureSuccessStatusCode(); var document = new XmlDocument(); using (var stream = await response.Content.ReadAsStreamAsync()) using (var reader = XmlReader.Create(stream)) document.Load(reader); return(document.DocumentElement); } }) .Result; return(metadata, identityProvider.EntityId); } }) .Materialize()); } UrlHandlingStatics.Init( (baseUrlString, appRelativeUrl) => AppRequestState.ExecuteWithUrlHandlerStateDisabled(() => UrlHandlingStatics.ResolveUrl(baseUrlString, appRelativeUrl)?.Last())); CssPreprocessingStatics.Init(globalInitializer.GetType().Assembly, globalType.Assembly); ResourceBase.Init( (requestTransferred, resource) => { if (requestTransferred) { var urlHandlers = new List <BasicUrlHandler>(); UrlHandler urlHandler = resource; do { urlHandlers.Add(urlHandler); }while((urlHandler = urlHandler.GetParent()) != null); AppRequestState.Instance.SetUrlHandlers(urlHandlers); AppRequestState.Instance.SetNewUrlParameterValuesEffective(false); AppRequestState.Instance.SetResource(resource); } else { AppRequestState.Instance.SetResource(resource); } }, () => AppRequestState.Instance.Resource); PageBase.Init( (() => BasePageStatics.AppProvider.GetPageViewDataModificationMethod(), () => BasePageStatics.AppProvider.JavaScriptDocumentReadyFunctionCall), BasicPageContent.GetContent); HyperlinkBehaviorExtensionCreators.Init(ModalBox.GetBrowsingModalBoxOpenStatements); FileUpload.Init(() => ((BasicPageContent)PageBase.Current.BasicContent).FormUsesMultipartEncoding = true); ModalBox.Init(() => ((BasicPageContent)PageBase.Current.BasicContent).BrowsingModalBoxId); CreditCardCollector.Init(() => ((BasicPageContent)PageBase.Current.BasicContent).IncludesStripeCheckout = true); BasePageStatics.Init(providerGetter.GetProvider <AppStandardPageLogicProvider>("StandardPageLogic")); BasicPageContent.Init( contentObjects => { var contentUsesUi = contentObjects.Any(i => i is UiPageContent); var cssInfos = new List <ResourceInfo>(); cssInfos.Add( new ExternalResource( "//fonts.googleapis.com/css2?family=Libre+Franklin:wght@500;600;700&family=Open+Sans:ital,wght@0,400;0,600;0,700;1,400&display=fallback")); cssInfos.Add(new ExternalResource("//maxcdn.bootstrapcdn.com/font-awesome/4.5.0/css/font-awesome.min.css")); cssInfos.Add(new StaticFiles.Versioned.Third_party.Jquery_ui.Jquery_ui_1114custom_v2.Jquery_uiminCss()); cssInfos.Add(new StaticFiles.Third_party.Select_cssCss()); cssInfos.Add(new StaticFiles.Versioned.Third_party.Chosen.Chosen_v187.ChosenminCss()); cssInfos.Add(new StaticFiles.Third_party.Time_picker.StylesCss()); cssInfos.Add(new ExternalResource("//cdn.jsdelivr.net/qtip2/2.2.1/jquery.qtip.min.css")); cssInfos.Add(new ExternalResource("//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.css")); cssInfos.Add(new StaticFiles.Styles.BasicCss()); if (contentUsesUi) { cssInfos.AddRange( new ResourceInfo[] { new StaticFiles.Styles.Ui.ColorsCss(), new StaticFiles.Styles.Ui.FontsCss(), new StaticFiles.Styles.Ui.LayoutCss(), new StaticFiles.Styles.Ui.TransitionsCss() }); } foreach (var resource in BasePageStatics.AppProvider.GetStyleSheets()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); cssInfos.Add(resource); } if (contentUsesUi) { foreach (var resource in EwfUiStatics.AppProvider.GetStyleSheets()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); cssInfos.Add(resource); } } else { foreach (var resource in BasePageStatics.AppProvider.GetCustomUiStyleSheets()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); cssInfos.Add(resource); } } return(cssInfos); }, (markup, includeStripeCheckout) => { string getElement(ResourceInfo resource) => "<script src=\"{0}\" defer></script>".FormatWith(resource.GetUrl()); var infos = new List <ResourceInfo>(); infos.Add(new ExternalResource("//code.jquery.com/jquery-1.12.3.min.js")); infos.Add(new StaticFiles.Versioned.Third_party.Jquery_ui.Jquery_ui_1114custom_v2.Jquery_uiminJs()); infos.Add(new StaticFiles.Versioned.Third_party.Chosen.Chosen_v187.ChosenjqueryminJs()); infos.Add(new StaticFiles.Third_party.Time_picker.CodeJs()); infos.Add(new ExternalResource("//cdn.jsdelivr.net/qtip2/2.2.1/jquery.qtip.min.js")); infos.Add(new ExternalResource("//cdnjs.cloudflare.com/ajax/libs/dialog-polyfill/0.4.9/dialog-polyfill.min.js")); infos.Add(new StaticFiles.Third_party.Spin_js.SpinminJs()); infos.Add(new ExternalResource("//cdn.ckeditor.com/4.5.8/full/ckeditor.js")); infos.Add(new ExternalResource("https://cdnjs.cloudflare.com/ajax/libs/Chart.js/2.9.4/Chart.min.js")); infos.Add(new ExternalResource("https://instant.page/5.1.0")); if (includeStripeCheckout) { infos.Add(new ExternalResource("https://checkout.stripe.com/checkout.js")); } infos.Add(new StaticFiles.CodeJs()); foreach (var i in infos.Select(getElement)) { markup.Append(i); } markup.Append(MiniProfiler.Current.RenderIncludes().ToHtmlString()); foreach (var resource in BasePageStatics.AppProvider.GetJavaScriptFiles()) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(resource); markup.Append(getElement(resource)); } }, () => { var icons = new List <(ResourceInfo, string, string)>(); var faviconPng48X48 = BasePageStatics.AppProvider.FaviconPng48X48; if (faviconPng48X48 != null) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(faviconPng48X48); icons.Add((faviconPng48X48, "icon", "48x48")); } var favicon = BasePageStatics.AppProvider.Favicon; if (favicon != null) { assertResourceIsIntermediateInstallationPublicResourceWhenNecessary(favicon); icons.Add((favicon, "icon", "")); } return(icons); }, hideWarnings => { var url = AppRequestState.Instance.Url; if (AppRequestState.Instance.UserAccessible && AppRequestState.Instance.ImpersonatorExists) { url = new UserManagement.Pages.Impersonate( url, optionalParameterSetter: (specifier, parameters) => specifier.User = AppTools.User != null ? AppTools.User.Email : UserManagement.Pages.Impersonate.AnonymousUser).GetUrl(); } return(new NonLiveLogIn( url, optionalParameterSetter: (specifier, parameters) => { specifier.Password = ConfigurationStatics.SystemGeneralProvider.IntermediateLogInPassword; specifier.HideWarnings = hideWarnings; }).GetUrl()); }, () => { if (!AppRequestState.Instance.UserAccessible || !AppRequestState.Instance.ImpersonatorExists || (ConfigurationStatics.IsIntermediateInstallation && !AppRequestState.Instance.IntermediateUserExists)) { return(null); } return("User impersonation is in effect.", new HyperlinkSetup(new UserManagement.Pages.Impersonate(AppRequestState.Instance.Url), "Change user").Append <ActionComponentSetup>( new ButtonSetup( "End impersonation", behavior: new PostBackBehavior( postBack: PostBack.CreateFull( id: "ewfEndImpersonation", modificationMethod: UserImpersonationStatics.EndImpersonation, actionGetter: () => new PostBackAction( new ExternalResource( EwfConfigurationStatics.AppConfiguration.DefaultBaseUrl.GetUrlString( EwfConfigurationStatics.AppSupportsSecureConnections))))))) .Materialize()); }); EwfUiStatics.Init(providerGetter.GetProvider <AppEwfUiProvider>("EwfUi")); AuthenticationStatics.Init( providerGetter.GetProvider <AppAuthenticationProvider>("Authentication"), (user, code) => new UserManagement.Pages.LogIn( "", optionalParameterSetter: (specifier, parameters) => { specifier.User = user; specifier.Code = code; }).GetUrl(), destinationUrl => new UserManagement.Pages.ChangePassword(destinationUrl).GetUrl(disableAuthorizationCheck: true)); Admin.EntitySetup.Init(() => RequestDispatchingStatics.AppProvider.GetFrameworkUrlParent()); RequestDispatchingStatics.Init(providerGetter.GetProvider <AppRequestDispatchingProvider>("RequestDispatching")); EwfInitializationOps.appInitializer = appInitializer; appInitializer?.InitStatics(); executeWithAutomaticDatabaseConnections(AuthenticationStatics.InitAppSpecificLogicDependencies); if (AuthenticationStatics.SamlIdentityProviders.Any() || ExternalFunctionalityStatics.SamlFunctionalityEnabled) { executeWithAutomaticDatabaseConnections(ExternalFunctionalityStatics.ExternalSamlProvider.InitAppSpecificLogicDependencies); } initTimeDataAccessState = null; EwfApp.FrameworkInitialized = true; },
private void handleBeginRequest( object sender, EventArgs e ) { if( !FrameworkInitialized ) { // We can't redirect to a normal page to communicate this information because since initialization failed, the request for that page will trigger // another BeginRequest event that puts us in an infinite loop. We can't rely on anything except an HTTP return code. Suppress exceptions; there is no // way to report them since even our basic exception handling may not work if the application isn't initialized. try { set500StatusCode( "Initialization Failure" ); } catch {} return; } ExecuteWithBasicExceptionHandling( delegate { if( RequestState != null ) { RequestState = null; throw new ApplicationException( "AppRequestState was not properly cleaned up from a previous request." ); } // This used to be just HttpContext.Current.Request.Url, but that doesn't work with Azure due to the use of load balancing. An Azure load balancer // will bind to the ip/host/port through which all web requests should come in, and then the request is redirected to one of the server instances // running this web application. For example, a user will request mydomain.com. In Azure, there may be two instances running this web site, on // someIp:81 and someIp:82. For some reason, HttpContext.Current.Request.Url ends up using the host and port from one of these addresses instead of // using the host and port from the HTTP Host header, which is what the client is actually "viewing". Basically, HttpContext.Current.Request.Url // returns http://someIp:81?something=1 instead of http://mydomain.com?something=1. See // http://stackoverflow.com/questions/9560838/azure-load-balancer-causes-400-error-invalid-hostname-on-postback. var baseUrl = getRequestBaseUrl( Request ); if( !baseUrl.Any() ) { setStatusCode( 400 ); return; } var appRelativeUrl = GetRequestAppRelativeUrl( Request, disableLeadingSlashRemoval: true ); // If the base URL doesn't include a path and the app-relative URL is just a slash, don't include this trailing slash in the URL since it will not be // present in the canonical URLs that we construct and therefore it would cause problems with URL normalization. var url = !getRequestBasePath( Request ).Any() && appRelativeUrl.Length == "/".Length ? baseUrl : baseUrl + appRelativeUrl; // This blocks until the entire request has been received from the client. // This won't compile unless it is assigned to something, which is why it is unused. var stream = Request.InputStream; RequestState = new AppRequestState( url ); }, false, true ); }