Skip to content
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

Make Proxied Request Path Configurable #5

Open
DanielStout5 opened this issue Oct 22, 2021 · 8 comments
Open

Make Proxied Request Path Configurable #5

DanielStout5 opened this issue Oct 22, 2021 · 8 comments

Comments

@DanielStout5
Copy link

I haven't been able to fully test this yet (as per my other issue) but from reading the code, I think that the line the line endpoints.Map("/{**catch-all}" in IEndpointRouteBuilderExtensions would make it so the .Net application itself can't have a "catch all" handler - which is I think a relatively common requirement.

I need to be able to have only certain requests proxied - e.g. those starting with /dist/ and other paths specific to the hot reloading features of Webpack. That would let the .Net application handle all other requests, including not matched ones.

I'm thinking that MapSpaYarp should at very least accept the string pattern as a parameter

@berhir
Copy link
Owner

berhir commented Oct 30, 2021

Thank you for the suggestion.
I have not much time currently, but if you create a PR I will merge it.

Not sure if it's better to add a parameter to the MapSpaYarp method or if we should add a setting to the SpaDevelopmentServerOptions.

@DanielStout5
Copy link
Author

My opinion would be that it'd be better to add it to MapSpaYarp, since it seems to me that ideally SpaDevelopmentServerOptions could stay in sync with the "real" version that's actually in aspnetcore.

As I mentioned in my other ticket, I've removed SpaYarp and have basically replicated most of what it does - here's how I am now configuring the endpoints:

                if (DebugUtils.IsDebug) // equivalent to #if DEBUG
                {
                    var prov = endpts.ServiceProvider;
                    var forward = prov.GetRequiredService<IHttpForwarder>();
                    var spaOpt = prov.GetRequiredService<IOptions<SpaDevelopmentServerOptions>>().Value;
                    var client = new HttpMessageInvoker(new SocketsHttpHandler()
                    {
                        UseProxy = false,
                        AllowAutoRedirect = false,
                        AutomaticDecompression = System.Net.DecompressionMethods.None,
                        UseCookies = false
                    });

                    var dest = new Uri(spaOpt.ServerUrl).GetComponents(UriComponents.SchemeAndServer, UriFormat.Unescaped);

                    endpts.Map("/dist/{*path}", async ctx =>
                    {
                        var error = await forward.SendAsync(ctx, dest, client);
                        log.LogInformation("Forwarder error: {err}", error);
                    });
                }

Thanks for creating this library - even if I'm not using it directly now, it was how I learned about Yarp and showed me how to solve this issue :)

@buchatsky
Copy link
Contributor

buchatsky commented Nov 19, 2021

I've made a pull request that introduces SpaDevelopmentServerOptions.PublicPath option which corresponds to devServer.publicPath option of Webpack Dev Server.
If .csproj file contains
<SpaPublicPath>/dist</SpaPublicPath>
only requests with the specified path are forwarded to Dev Server.
If .csproj file contains an empty
<SpaPublicPath></SpaPublicPath>
or this option is omited, forwarding works from the root, as before.
I didn't add any specific sample because MVC+SPA pattern is quite cumbersome and its structure is arguable, and it uses Webpack directly. But you can be sure that it works.
If 'PublicPath' name is not suitable it can be renamed to something else.

@berhir
Copy link
Owner

berhir commented Nov 26, 2021

@buchatsky thank you for the PR, I merged it.
I will make a few more tests and publish a new version to NuGet within the next few days.

@buchatsky
Copy link
Contributor

There may be some use cases when a single redirect path is not enough. For ex. when several SPAs are launched from different Razor views. So, semicolumn-delimited lists with wildcards would be more suitable

@litan1106
Copy link

@berhir @buchatsky does it make sense to allow custom yarp configuration file for full customization instead of the predefined routes? In the real world applications, we usually have more than one cluster and routes. ex: a signalr route, a spa route, and an api route)

example:

.AddReverseProxy()
      .LoadFromConfig(configuration.GetSection("ReverseProxy"));

@muntdan
Copy link

muntdan commented Jun 2, 2022

Hello for me using <SpaPublicPath> option doesnt work properly in regards to detecting if ng server is running.
If I put <SpaPublicPath>/spa</SpaPublicPath> and <SpaClientUrl>https://localhost:4300</SpaClientUrl> the IsSpaClientRunning doesnt detect succesfull the SPA as it is also lunched with /spa/ option for its routing to work:
ng serve --port 4300 --serve-path=/spa/
If I put <SpaPublicPath>/spa</SpaPublicPath> and <SpaClientUrl>https://localhost:4300/spa</SpaClientUrl> IsSpaClientRunning detects it but forwarding is being done with https://localhost:4300/spa/spa/ and doesnt work.

I belive this + _options.PublicPath should be added to IsSpaClientRunning
var response = await httpClient.GetAsync(_options.ClientUrl + _options.PublicPath, cancellationTokenSource.Token);

@berhir
Copy link
Owner

berhir commented Aug 7, 2022

@danmunteanuevo please see #17. a new version that fixes this issue will be published soon

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants