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

Unable to access server from a browser when EmbedIO is created in a Xamarin application #554

Open
anantashrit opened this issue Apr 4, 2022 · 10 comments

Comments

@anantashrit
Copy link

Write a Xamarin app using visual studio with only one target i.e., UWP
Use WebView in Xamarin app to load angular UI. Angular UI would be interacting with EmbedIO server.
Write the below server code -
private WebServer CreateServer(string htmlPath)
{
var server = new WebServer(o => o
.WithUrlPrefix("http://*:PortNumber/")
.WithMode(HttpListenerMode.EmbedIO))
.WithLocalSessionManager()
.WithWebApi("/api", m => m.WithController())
.WithStaticFolder("/", htmlPath, true, m => m
.WithContentCaching(true));
return server;
}
Write a small controller and use the APIs in the angular UI. Ensure that angular UI is able to communicate with the controller in runtime.
Now when the xamarin app is running open a browser and try to load "http://localhost:PortNumber/". This is giving below error in firefox - The connection has timed out

But when I add a console application as a target and run the same code above. From a browser I will be able to load the angular UI and that UI will communicate with the server as well.

So is this behaviour by design that server wont be accessible when part of a xamarin app ? Or there is any API to control this ?

@michael-hawker
Copy link

UWP apps have a stricter sandbox than a console application. Have you enabled the Internet (Client & Server) capability in your package.appxmanifest file of your UWP head? Not sure if you'd also need Private Networks (Client & Server) to give access to your localbox to access it, I know UWP's can't access localhost, but I believe they should be able to serve to it since you're trying to access from outside the app.

It'll be good to test a release build on a different machine/environment though too if it does work, as VS/debug does open up some ports and things by default.

@anantashrit
Copy link
Author

UWP apps have a stricter sandbox than a console application. Have you enabled the Internet (Client & Server) capability in your package.appxmanifest file of your UWP head? Not sure if you'd also need Private Networks (Client & Server) to give access to your localbox to access it, I know UWP's can't access localhost, but I believe they should be able to serve to it since you're trying to access from outside the app.

It'll be good to test a release build on a different machine/environment though too if it does work, as VS/debug does open up some ports and things by default.

Hi. Thank you for your response and suggestion. I tried adding the capabilities that you have mentioned. But still I am not able to access the server from a browser. Same error.

I am yet to try out the release build on a different machine. I will try that out tomorrow and let you know. Thank you once again

@anantashrit anantashrit reopened this Apr 5, 2022
@rdeago
Copy link
Collaborator

rdeago commented Apr 5, 2022

Hello @anantashrit, I can confirm that there's no particular limitation in EmbedIO regarding UWP apps... except, of course, for the limitations that are intrinsic to UWP itself.

Thanks a lot @michael-hawker for your answer! It's always a joy to see members of our community help one another, especially on topics like UWP about which I admittedly know 3% less than nothing.

@anantashrit
Copy link
Author

@michael-hawker Nope. Doesn't work even after deploying a release build.

@opcodewriter
Copy link

opcodewriter commented Jun 26, 2022

Doesn't work for me either in UWP. Works perfectly on Android. with the same code put in a .NET Standard library:

 using (var server = new WebServer(HttpListenerMode.EmbedIO, "http://*:8585"))

I can see the logging in Output when debugging the app (I log the state using the StateChanged event):

WebServer New State - Loading
WebServer New State - Listening

Also made sure:

  • Both Internet (Client & Server) and Private Networks (Client & Server) checked in app manifest like @michael-hawker mentioned
  • Checked if the app is loopback exempted (using Fiddler's built-in tool)

@opcodewriter
Copy link

opcodewriter commented Jun 26, 2022

Anyone can help?

Is there a way to get and log more info from EmbedIO HTTP server, like errors, which address it actually listens to, etc.?

@rdeago
Copy link
Collaborator

rdeago commented Jun 27, 2022

@opcodewriter AFAIK errors are logged, either as 500 responses, or (for example if an exception occurs while sending a 500 response) simply as exceptions.

As for the actual address(es) being listened to, there's no way to get them from Microsoft's HttpListener, so nobody ever cared to make them accessible and/or logged in EmbedIO's internal listener.

I must add, unfortunately, that the classes involved, namely EndPointListener and EndPointManager, are not exactly the cleanest code I've ever seen ("a horrible, life-draining mess" would more accurately reflect my point of view, but hey, that's just me after wasting some days on them.) Besides, their presence is pointless to start with, as they try to emulate a feature of the HTTP.SYS driver that just doesn't make sense when implemented in a single application; therefore, they're bound to disappear in version 4 anyway.

I'll gladly take logging bound addresses as an enhancement request for version 4.

EDIT: When listening to e.g. http://*.<port_number>, EmbedIO's listener listens on 0.0.0.0; we can know the actual endpoint only when a request arrives, not when we're "just" listening. For debugging purposes, you may try using both prefixes http://127.0.0.1:<port> and http://<your_LAN_address>:<port> instead of using the * or + wildcard. This limitation comes from using .NET's TcpListener so, unless someone comes up with a better idea, I'm afraid we're stuck with it.

@michael-hawker
Copy link

I misunderstood the original scenario, I thought the app was just trying to host the server for a browser to access. If you're trying to host the web server in the process and then access within the UWP app, any UWP app won't allow access to localhost. I don't think there's an easy way around this, though @dpaulino may know more from how Nightingale works though.

@dpaulino
Copy link

In release mode, there's no easy way around it. UWP apps can't normally access local host. But if you were able to add a desktop extension to your UWP app, then you could run a tool via command line that will grant your UWP app access to local host. This is how my UWP REST client app works around the issue, and it works well for my users.

Here's the doc for Nightingale that explains how to manually grant access for local host. This command is what nightingale's desktop extension runs at startup using a win32 process. https://github.com/jenius-apps/nightingale-rest-api-client/blob/master/docs/localhost.md

@thanoue
Copy link

thanoue commented Dec 21, 2022

In my case, I create a server on Xamarin forms. when I run the UWP application, I use POSTMAN to make a request from another PC, it works perfectly, but when I use the POSTMAN from the same PC with running UWP application, It doesn't work. I don't know where the issue coming from. Please let me know how to fix it. Thanks

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

6 participants