-
Notifications
You must be signed in to change notification settings - Fork 2.7k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add PreRouting and PostRouting pipeline filters #14503
Add PreRouting and PostRouting pipeline filters #14503
Conversation
This is great! Pinging @prjseal and @poornimanayar on this one as well for some verification. @ronaldbarendse The comments says to remove the default implementation on the interface in v13 - can we do that, is it not 2 majors that we need to wait? |
This is soooooooo good!!!! |
That totally works! And it works for almost everything that |
This is great @ronaldbarendse, it simplifies the process so much. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Great to see such good feedback 😄
@nul800sebastiaan We don't expect anyone to implement their own IUmbracoPipelineFilter
or IUmbracoApplicationBuilderContext
, so the default implementations are only really added to make these additions non-breaking. I've added some additional comments to further clean up the code, but those are all more 'nice to have' (and might be more breaking and therefore need to more strictly adhere to the 2 major versions rule) 👍🏻
{ | ||
} | ||
: this(name, null, null, null, null, null) | ||
{ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Although removing this constructor won't cause a source breaking change (because the new constructor with optional parameters can be used), it will be a binary breaking change. If you only provide the name parameter, there's no ambiguity either, since the constructor without optional parameters will be used (see overload resolution for named and optional parameters).
We might want to add a comment to remove this constructor in the next major version though:
{ } | |
{ | |
// TODO: Remove this constructor in Umbraco 13, because the signature is similar to the one with optional parameters | |
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you want to mark it as obsolete now as well?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's no need to obsolete this constructor, but it can be safely removed in the next major, because that would only be a source breaking change (since it will then use the constructor with optional parameters instead).
/// </summary> | ||
/// <value> | ||
/// The pre pipeline callback. | ||
/// </value> | ||
public Action<IApplicationBuilder>? PrePipeline { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Another suggestion for a future major (since it would be a breaking change), is to change the property setters to init
, so you can only set the callback when constructing a new instance:
public Action<IApplicationBuilder>? PrePipeline { get; set; } | |
public Action<IApplicationBuilder>? PrePipeline { get; init; } |
This does raise the question whether we still want the constructor with all the optional parameters (which is currently already flagged as having too many parameters) or going the complete opposite way and completely removing the property setters...
Any thoughts on which syntax is preferred based on the following example?
// Using parameters will more likely produce longer lines or weird parameter alignment (if you break it over multiple lines)
builder.Services.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new UmbracoPipelineFilter("Cors", postRouting: app => app.UseCors())))
// Using property setter will produce slightly more verbose code, but with nicer formatting
builder.Services.Configure<UmbracoPipelineOptions>(options => options.AddFilter(new UmbracoPipelineFilter("Cors")
{
PostRouting = app => app.UseCors()
}));
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally prefer the first one, which means it's probably the wrong choice and the latter is best 😁
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
There's nothing wrong with either choice, so let's leave this for now and allow both 😄
…r.cs Co-authored-by: Ronald Barendse <[email protected]>
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just a couple of quick things @ronaldbarendse, will test it in the meantime.
src/Umbraco.Web.Common/ApplicationBuilder/IUmbracoPipelineFilter.cs
Outdated
Show resolved
Hide resolved
/// </summary> | ||
/// <value> | ||
/// The pre pipeline callback. | ||
/// </value> | ||
public Action<IApplicationBuilder>? PrePipeline { get; set; } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I personally prefer the first one, which means it's probably the wrong choice and the latter is best 😁
{ | ||
} | ||
: this(name, null, null, null, null, null) | ||
{ } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Would you want to mark it as obsolete now as well?
Super, this works a treat and that composer/fetch combo is a very elegant test - thanks for making it easy @ronaldbarendse! Will ignore the other questions for now so this can be squeezed into the 12.1 RC. |
Prerequisites
This extends the options discussed in issue #10682 and added in PR #10702.
Description
Enabling CORS in Umbraco currently requires you to swap the
WithMiddleware()
call inStartup.cs
toWithCustomMiddleware()
and manually register all default Umbraco middleware, just to be able to addUseCors()
in the right order (after routing, but before authentication/authorization, see Paul Seals blogpost).You can already add middleware in different places by using
IUmbracoPipelineFilter
and thePrePipeline
,PostPipeline
andEndpoints
callbacks, so this PR extends these options withPreRouting
andPostRouting
callbacks.You can use
PreRouting
to add middleware that needs to run after the Umbraco static file middlewares are added, but before the routing middleware. And you can now usePostRouting
to add middleware (like CORS) after routing, but before authentication/authorization. See the recommended middleware order.Testing this PR can be done by adding the following composer:
You should be able to request
/echo
from any origin, but get an error when trying to fetch/echo2
. You can easily test this by pasting the following JavaScript code in your browser console when not on the local Umbraco website (e.g. on umbraco.com):This should return the following:
An additional bonus is that this doesn't require any changes in your
Startup.cs
file and also allows packages to enable CORS and configure their own policies. Users that currently useWithCustomMiddleware()
will need to add calls toRunPreRouting()
andRunPostRouting()
, but that's similar to Umbraco adding additional middleware in future versions...