Example #1
0
        public async Task InvokeAsync(HttpContext context)
        {
            // If Umbraco hasn't been installed yet, the middleware shouldn't do anything (interacting with the
            // redirects service will fail as the database isn't setup yet)
            if (_runtimeState.Level == RuntimeLevel.Install)
            {
                await _next(context);

                return;
            }

            string pathAndQuery = context.Request.GetEncodedPathAndQuery();

            // Ignore all /umbraco/ requests
            if (pathAndQuery.IndexOf("/umbraco/", StringComparison.InvariantCultureIgnoreCase) == 0)
            {
                await _next(context);

                return;
            }

            context.Response.OnStarting(() => {
                switch (context.Response.StatusCode)
                {
                case StatusCodes.Status404NotFound: {
                    // Get the URI of the inbound request
                    Uri uri = context.Request.GetUri();

                    // Invoke the pre lookup event
                    RedirectPreLookupNotification preLookup = new(context);
                    _eventAggregator.Publish <IRedirectPreLookupNotification>(preLookup);

                    // Get the destination URL from the arguments (in case a value has been set
                    // from an notification handler)
                    string destinationUrl = preLookup.DestinationUrl;

                    // Declare a variable for the redirect (either from the pre lookup or a lookup via the service)
                    IRedirect redirect = preLookup.Redirect ?? _redirectsService.GetRedirectByRequest(context.Request);

                    // Return if we neither have a redirect or a destination URL
                    if (redirect == null && string.IsNullOrWhiteSpace(destinationUrl))
                    {
                        return(Task.CompletedTask);
                    }

                    // Determine the redirect type
                    RedirectType redirectType = preLookup.RedirectType ?? redirect?.Type ?? RedirectType.Temporary;

                    // Calculate the destination URL
                    destinationUrl ??= _redirectsService.GetDestinationUrl(redirect, uri);

                    // Invoke the post lookup event
                    RedirectPostLookupNotification postLookup = new(context, redirect, redirectType, destinationUrl);
                    _eventAggregator.Publish <IRedirectPostLookupNotification>(postLookup);

                    // Extract the values from the notification
                    redirectType   = postLookup.RedirectType;
                    destinationUrl = postLookup.DestinationUrl;

                    // The destination URL should have a value at this point. If the value is empty, it's most
                    // likely because it was emptied via the post look up notification
                    if (string.IsNullOrWhiteSpace(destinationUrl))
                    {
                        return(Task.CompletedTask);
                    }

                    // Respond with a redirect based on the redirect type
                    switch (redirectType)
                    {
                    // If redirect is of type permanent, trigger a 301 redirect
                    case RedirectType.Permanent:
                        context.Response.Redirect(destinationUrl, true);
                        break;

                    // If redirect is of type temporary, trigger a 307 redirect
                    case RedirectType.Temporary:
                        context.Response.Redirect(destinationUrl, false, true);
                        break;
                    }

                    break;
                }
                }

                return(Task.CompletedTask);
            });

            await _next(context);
        }
Example #2
0
 /// <summary>
 /// Returns the calculated destination URL for the specified <paramref name="redirect"/>.
 /// </summary>
 /// <param name="redirect">The redirect.</param>
 /// <param name="uri">The inbound URL.</param>
 /// <param name="redirectsService">A reference to the current redirects service.</param>
 /// <returns>The destination URL.</returns>
 public static string GetDestinationUrl(this OutboundRedirect redirect, Uri uri, IRedirectsService redirectsService)
 {
     return(redirectsService.GetDestinationUrl(redirect, uri));
 }