Simple Android HTTP Listener Not Working

I'm trying to setup a simple HTTP listener on localhost in an Android (Xamarin.Forms) app. I have a WebView in the app pointed to its address. It would be something like: http//localhost:46467/authorize/?code=4/...

Below is the code I'm using. The function RedirectUri returns a properly formatted uri like the one I refer to above. The listener gets setup, and the routine is properly awaiting on the context. But the webview cannot find the host. I then try to point the Android browser app at the same address, and it displays "Bad Request (Invalid host)". This is pretty straight forward, and I had a similar version working in a simple Windows console program. What am I doing wrong here?

    public async Task<AuthorizationCodeResponseUrl> ListenForFeedbackAsync(string authorizationUrl="")
    {
        using (var listener = new HttpListener())
        {
            Debug.WriteLine("Listening...");
            listener.Prefixes.Add(RedirectUri);
            try
            {
                Debug.WriteLine("Staring listener...");

                // Wait to get the authorization code response.
                listener.AuthenticationSchemes = AuthenticationSchemes.None;
                listener.IgnoreWriteExceptions = true;
                listener.Start();

                if (listener.IsListening)
                {
                    Debug.WriteLine("Awaiting on context...");
                    HttpListenerContext context = await listener.GetContextAsync().ConfigureAwait(false);
                    NameValueCollection coll = context.Request.QueryString;

                    Debug.WriteLine("Writing response...");
                    // Write a "close" response.
                    using (var writer = new StreamWriter(context.Response.OutputStream))
                    {
                        writer.WriteLine(ClosePageResponse);
                        writer.Flush();
                    }
                    context.Response.OutputStream.Close();

                    Debug.WriteLine("Returning...");
                    await _mainPage.HideWebView().ConfigureAwait(false);

                    // Create a new response URL with a dictionary that contains all the response query parameters.
                    return new AuthorizationCodeResponseUrl(coll.AllKeys.ToDictionary(k => k, k => coll[k]));
                }
                else
                {
                    Debug.WriteLine("Http listener fail.");
                    return null;
                }
            }
            catch (Exception e)
            {
                string msg = e.Message;
                Debug.WriteLine(msg);
                throw;
            }
            finally
            {
                listener.Close();

            }
        }
    }

Posts

  • ChadMello.8181ChadMello.8181 USMember ✭✭

    So, I found a solution, but it still does not answer why I cannot use localhost... I use a routine like this to replace localhost with an ip address:

        private static string GetLocalIpAddress()
        {
            Debug.WriteLine("Getting IP...");
            var listener = new TcpListener(IPAddress.Loopback, 0);
            try
            {
                listener.Start();
                string address = ((IPEndPoint)listener.LocalEndpoint).Address.ToString();
                Debug.WriteLine("Address: " + address);
                return address;
            }
            finally
            {
                listener.Stop();
            }
        }
    
  • KayVeeKayVee INMember

    Hey!
    I working on something similar!
    httplistener() is deprecated. Do you know any alternative to start a server ?

  • ChadMello.8181ChadMello.8181 USMember ✭✭

    This all works on Android. Have not tried on iOS yet. The GetLocalIPAddress routine creates the loopback url and returns it. Use that url to then create a listener, using the ListenForFeedbackAsync routine above. I have not tried to setup a public listener, but I assume it's basically the same thing. My problem is that I simply did not realize that "localhost" does not work on Android - at least not any device I had configured out of the box.

Sign In or Register to comment.