New feature request: Access to Owin pipeline #43

Closed
opened 2025-12-29 14:21:35 +01:00 by adam · 11 comments
Owner

Originally created by @Rmkrs on GitHub (Oct 13, 2017).

Hey Stef,

We are looking into using WireMock.net for UI tests for one of our products. To give it some context, we have a single page Aurelia Frontend application talking to a backend using WebAPI2.

We serve the frontend files (/index, etc) but we also have /api/xxx where our backend responds.
And /api/signalr, where the signalr connection lives.
All on the same url:port.

We created a POC to provide fake api data to the frontend using WireMock and that works.

We had to do a little bit of "trickery" to be able to still host our frontend files, by making a "StaticResourceResponseProvider" that allows us to server files from disk based on the URI.
So all uri's now go to the StaticResourceResponseProvider, except for /api/, using the regex "^(?!/api/.$).*".

Per UI test we have different Given/RespondWith setups we do based on what /api/xxx calls we expect and require.

If we had access to the Owin pipeline you use inside WireMock.net we could hook this up a bit nicer (and without fonts breaking, due to always being sent as string, instead of bytes with encoding, courtesy of the string Body property in ResponseMessage).

But why we "really" need access to the Owin pipeline is because we also want to hook up SignalR. We cannot use Response.Create().WithProxy as that breaks the SignalR connection. So ideally I would want to register that on the IAppBuilder, such as:

public void Configuration(IAppBuilder app)
{
app.UseCors(CorsOptions.AllowAll);
app.MapSignalR();
}

We were looking at ways to accomplish this in WireMock.net, but found no readily available paths. One of the (least intrusive) solutions could be if IOwinSelfHost was public and it could be injected as an argument on the Start methods in FluentMockServer. Right now the private constructor there accepts settings and depending on the pragma NETSTANDARD, either AspNetCoreSelfHost or OwinSelfHost is spawned.

I could imagine creating my own implementation of OwinSelfHost where I can setup any Owin components I would like to use.

Or maybe you have a different/better idea, I am open to suggestions.

Originally created by @Rmkrs on GitHub (Oct 13, 2017). Hey Stef, We are looking into using WireMock.net for UI tests for one of our products. To give it some context, we have a single page Aurelia Frontend application talking to a backend using WebAPI2. We serve the frontend files (/index, etc) but we also have /api/xxx where our backend responds. And /api/signalr, where the signalr connection lives. All on the same url:port. We created a POC to provide fake api data to the frontend using WireMock and that works. We had to do a little bit of "trickery" to be able to still host our frontend files, by making a "StaticResourceResponseProvider" that allows us to server files from disk based on the URI. So all uri's now go to the StaticResourceResponseProvider, except for /api/*, using the regex "^(?!/api/.*$).*". Per UI test we have different Given/RespondWith setups we do based on what /api/xxx calls we expect and require. If we had access to the Owin pipeline you use inside WireMock.net we could hook this up a bit nicer (and without fonts breaking, due to always being sent as string, instead of bytes with encoding, courtesy of the string Body property in ResponseMessage). But why we "really" need access to the Owin pipeline is because we also want to hook up SignalR. We cannot use Response.Create().WithProxy as that breaks the SignalR connection. So ideally I would want to register that on the IAppBuilder, such as: public void Configuration(IAppBuilder app) { app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); } We were looking at ways to accomplish this in WireMock.net, but found no readily available paths. One of the (least intrusive) solutions could be if IOwinSelfHost was public and it could be injected as an argument on the Start methods in FluentMockServer. Right now the private constructor there accepts settings and depending on the pragma NETSTANDARD, either AspNetCoreSelfHost or OwinSelfHost is spawned. I could imagine creating my own implementation of OwinSelfHost where I can setup any Owin components I would like to use. Or maybe you have a different/better idea, I am open to suggestions.
adam closed this issue 2025-12-29 14:21:35 +01:00
Author
Owner

@Rmkrs commented on GitHub (Oct 13, 2017):

I did a POC of how this could work by changing some code in WireMock.net and export a new nuget package, but "least intrusive" might not be a correct term.

I had to make WireMockMiddlewareOptions, FluentMockServerSettings and IOwinSelfHost public.
I also had to copy some of the code now being done in the private constructor of the FluentMockServer to the outside where I start the FluentMockServer, like so:

            var middlewareOptions = new WireMockMiddlewareOptions();
            var settings = new FluentMockServerSettings();
            int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort();
            var urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
            settings.Urls = urls;
            this.server = FluentMockServer.Start(settings, new OwinSelfHost(middlewareOptions, urls), middlewareOptions);

Before this, the code looked like this:

this.server = FluentMockServer.Start(new FluentMockServerSettings());

And I had to add 2 optional arguments to the Start method I was using:

public static FluentMockServer Start(FluentMockServerSettings settings, IOwinSelfHost owinSelfHost = null, WireMockMiddlewareOptions options = null)

And of course pass these into the private constuctor and use them there:

private FluentMockServer(FluentMockServerSettings settings, IOwinSelfHost owinSelfHost = null, WireMockMiddlewareOptions options = null)
        {
            if (options != null)
            {
                _options = options;
            }

            if (settings.Urls != null)
            {
                Urls = settings.Urls;
            }
            else
            {
                int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort();
                Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" };
            }

            if (owinSelfHost == null)
            {
#if NETSTANDARD
                _httpServer = new AspNetCoreSelfHost(_options, Urls);
#else
                _httpServer = new OwinSelfHost(_options, Urls);
#endif
            }
            else
            {
                this._httpServer = owinSelfHost;
            }

The OwinSelfHost that I created in my solution is a copy of your version, but I made some changes to the StartServer method to initialize SignalR. This is just quick and dirty, my "real" OwinSelfHost would probably be more configurable, instead of having a hardcoded URI in there:

        private void StartServers()
        {
            System.Console.WriteLine("WireMock.Net server using .net 4.5.x or .net 4.6.x");

            Action<IAppBuilder> startup = app =>
            {
                app.UseCors(CorsOptions.AllowAll);
                app.MapSignalR();
                app.Use<WireMockMiddleware>(_options);
            };

            var servers = new List<IDisposable>();
            servers.Add(WebApp.Start($"{Urls[0]}api/", startup));
            foreach (var url in Urls)
            {
                servers.Add(WebApp.Start(url, startup));
            }

            IsStarted = true;

            while (!_cts.IsCancellationRequested)
            {
                Thread.Sleep(30000);
            }

            IsStarted = false;

            foreach (var server in servers)
            {
                server.Dispose();
            }
        }

Not super happy about the resulting code changes... But at least I did get SignalR integrated into the solution I had and I could verify that that part would work in theory.

@Rmkrs commented on GitHub (Oct 13, 2017): I did a POC of how this could work by changing some code in WireMock.net and export a new nuget package, but "least intrusive" might not be a correct term. I had to make WireMockMiddlewareOptions, FluentMockServerSettings and IOwinSelfHost public. I also had to copy some of the code now being done in the private constructor of the FluentMockServer to the outside where I start the FluentMockServer, like so: ``` var middlewareOptions = new WireMockMiddlewareOptions(); var settings = new FluentMockServerSettings(); int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort(); var urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" }; settings.Urls = urls; this.server = FluentMockServer.Start(settings, new OwinSelfHost(middlewareOptions, urls), middlewareOptions); ``` Before this, the code looked like this: `this.server = FluentMockServer.Start(new FluentMockServerSettings());` And I had to add 2 optional arguments to the Start method I was using: `public static FluentMockServer Start(FluentMockServerSettings settings, IOwinSelfHost owinSelfHost = null, WireMockMiddlewareOptions options = null)` And of course pass these into the private constuctor and use them there: ``` private FluentMockServer(FluentMockServerSettings settings, IOwinSelfHost owinSelfHost = null, WireMockMiddlewareOptions options = null) { if (options != null) { _options = options; } if (settings.Urls != null) { Urls = settings.Urls; } else { int port = settings.Port > 0 ? settings.Port.Value : PortUtil.FindFreeTcpPort(); Urls = new[] { (settings.UseSSL == true ? "https" : "http") + "://localhost:" + port + "/" }; } if (owinSelfHost == null) { #if NETSTANDARD _httpServer = new AspNetCoreSelfHost(_options, Urls); #else _httpServer = new OwinSelfHost(_options, Urls); #endif } else { this._httpServer = owinSelfHost; } ``` The OwinSelfHost that I created in my solution is a copy of your version, but I made some changes to the StartServer method to initialize SignalR. This is just quick and dirty, my "real" OwinSelfHost would probably be more configurable, instead of having a hardcoded URI in there: ``` private void StartServers() { System.Console.WriteLine("WireMock.Net server using .net 4.5.x or .net 4.6.x"); Action<IAppBuilder> startup = app => { app.UseCors(CorsOptions.AllowAll); app.MapSignalR(); app.Use<WireMockMiddleware>(_options); }; var servers = new List<IDisposable>(); servers.Add(WebApp.Start($"{Urls[0]}api/", startup)); foreach (var url in Urls) { servers.Add(WebApp.Start(url, startup)); } IsStarted = true; while (!_cts.IsCancellationRequested) { Thread.Sleep(30000); } IsStarted = false; foreach (var server in servers) { server.Dispose(); } } ``` Not super happy about the resulting code changes... But at least I did get SignalR integrated into the solution I had and I could verify that that part would work in theory.
Author
Owner

@StefH commented on GitHub (Oct 13, 2017):

1] and without fonts breaking, due to always being sent as string, instead of bytes with encoding, courtesy of the string Body property in ResponseMessage). --- This looks like a bug or a new feature

2] I will take a look at your poc code. And check if this can be build in a more easier way.

@StefH commented on GitHub (Oct 13, 2017): 1] and without fonts breaking, due to always being sent as string, instead of bytes with encoding, courtesy of the string Body property in ResponseMessage). --- This looks like a bug or a new feature 2] I will take a look at your poc code. And check if this can be build in a more easier way.
Author
Owner

@Rmkrs commented on GitHub (Oct 13, 2017):

Thanks, I appreciate that. If you need any input from me, please don't hesitate.
Have a nice weekend.

@Rmkrs commented on GitHub (Oct 13, 2017): Thanks, I appreciate that. If you need any input from me, please don't hesitate. Have a nice weekend.
Author
Owner

@StefH commented on GitHub (Oct 14, 2017):

1] This issue has been fixed in the code by 07f03997c0
Do you want a new NuGet for this?

2] I still have to look into this.

3] Does the mocking work with SignalR, I'm surprised that mocking works? Can you maybe provide a POC client or unit-test to test this ?

@StefH commented on GitHub (Oct 14, 2017): 1] This issue has been fixed in the code by https://github.com/WireMock-Net/WireMock.Net/commit/07f03997c0046a2f7ddceaeac03318a38166fde5 Do you want a new NuGet for this? 2] I still have to look into this. 3] Does the mocking work with SignalR, I'm surprised that mocking works? Can you maybe provide a POC client or unit-test to test this ?
Author
Owner

@Rmkrs commented on GitHub (Oct 14, 2017):

Nice fix. I do not require a nuget package for this right now. I can wait with that for item 2.

For 3, I am not really "faking" SignalR itself, but rather create a real signalr hub with the same name as the original. Here I can expose the same methods that I have on the real one, but the data these methods will expose will be fake. So instead of faking the mechanism itself, I just expose fake data with it if that makes sense,

I actually fell today and had to get to the ER (hence my late reply) so I am typing (very slowly) with one hand and cannot easily create a POC right now, but once I heal up a bit I will see what I can do.

@Rmkrs commented on GitHub (Oct 14, 2017): Nice fix. I do not require a nuget package for this right now. I can wait with that for item 2. For 3, I am not really "faking" SignalR itself, but rather create a real signalr hub with the same name as the original. Here I can expose the same methods that I have on the real one, but the data these methods will expose will be fake. So instead of faking the mechanism itself, I just expose fake data with it if that makes sense, I actually fell today and had to get to the ER (hence my late reply) so I am typing (very slowly) with one hand and cannot easily create a POC right now, but once I heal up a bit I will see what I can do.
Author
Owner

@StefH commented on GitHub (Oct 17, 2017):

That really unfortunately, get well soon!

@StefH commented on GitHub (Oct 17, 2017): That really unfortunately, get well soon!
Author
Owner

@StefH commented on GitHub (Oct 17, 2017):

Hello @Rmkrs

I did add some code which should make it possible to do additional pre and post setup based on the IAppBuilder.

See this code 37244d5c2f (diff-e13c7e694283c3ed3636ff01623747c4R64) at a new branch.

Would this be a solution to your problem ?

@StefH commented on GitHub (Oct 17, 2017): Hello @Rmkrs I did add some code which should make it possible to do additional pre and post setup based on the `IAppBuilder`. See this code https://github.com/WireMock-Net/WireMock.Net/commit/37244d5c2fe47a808c908147f91c3d08edb0637b#diff-e13c7e694283c3ed3636ff01623747c4R64 at a new branch. Would this be a solution to your problem ?
Author
Owner

@Rmkrs commented on GitHub (Oct 18, 2017):

@StefH, that would definately solve the challenges we are having with the SignalR wireup.

@Rmkrs commented on GitHub (Oct 18, 2017): @StefH, that would definately solve the challenges we are having with the SignalR wireup.
Author
Owner

@StefH commented on GitHub (Oct 18, 2017):

@Rmkrs I've merged that code into the main branch so you can use it from there.

@StefH commented on GitHub (Oct 18, 2017): @Rmkrs I've merged that code into the main branch so you can use it from there.
Author
Owner

@StefH commented on GitHub (Oct 30, 2017):

New NuGet is added which includes this functionality.

I'm closing this issue for now, if you need more details, please open a new one.

@StefH commented on GitHub (Oct 30, 2017): New NuGet is added which includes this functionality. I'm closing this issue for now, if you need more details, please open a new one.
Author
Owner

@StefH commented on GitHub (Jan 10, 2018):

@Rmkrs
Just a question:
Did you succeed in running WireMock as a webjob in Azure?

@StefH commented on GitHub (Jan 10, 2018): @Rmkrs Just a question: Did you succeed in running WireMock as a webjob in Azure?
Sign in to join this conversation.
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: starred/WireMock.Net-wiremock#43