0

Im deploying docker containers on my local machine. They way I check that they are successfully deployed is by going to my browser and typing http://192.168.99.105:7474/browser. I would like to do this programmatically so I followed the code in this question Check if a url is reachable - Help in optimizing a Class. However when I try it, I get a System.Net.WebException {"The remote server returned an error: (504) Gateway Timeout."}.

It works fine though and I get a HttpStatusCode.OK if the url is https://en.wikipedia.org/wiki/YouTube

This is my code:

private bool UrlIsReachable(string url)
    {
        //https://en.wikipedia.org/wiki/YouTube
        HttpWebRequest request = WebRequest.Create("http://192.168.99.105:7474/browser") as HttpWebRequest;
        request.Timeout = 600000;//set to 10 minutes, includes time for downloading the image
        request.Method = "HEAD";

        try
        {
            using (HttpWebResponse response = request.GetResponse() as HttpWebResponse)
            {
                return response.StatusCode == HttpStatusCode.OK;
            }
        }
        catch (WebException)
        {
            return false;
        }
    }

EDIT: My docker-compose.yml file

version: '2'
services:
  company1:
    image: neo4j
    ports: 
         - "7474:7474"
         - "7687:7687"
    volumes:
         - $HOME/company1/data:/data
         - $HOME/company1/plugins:/plugins

  company2:
    image: neo4j
    ports: 
         - "7475:7474"
         - "7688:7687"
    volumes:
         - $HOME/company2/data:/data
         - $HOME/company2/plugins:/plugins
Community
  • 1
  • 1
jmc
  • 1,649
  • 6
  • 26
  • 47
  • do you have some kind of proxy settings ? – lordkain Oct 17 '16 at 13:03
  • How are you starting your Docker container? Please give the command or the docker-compose file. Is the 192 address the local network address of your host machine, or is that the address of a VM running Docker? – Nathaniel Waisbrot Oct 17 '16 at 13:04
  • @lordkain No I don't have, but I'm thinking that this is `TCP` and not `HTTP`. I tried a test on the website `web-sniffer.net` and it gave me `Only ports 80,443,8080 allowed.` My port is 7474. – jmc Oct 17 '16 at 13:07
  • @NathanielWaisbrot that is the address of the VM. – jmc Oct 17 '16 at 13:08
  • Are you running this code from the VM - the Docker host, or inside another container? – Elton Stoneman Oct 17 '16 at 13:13
  • @EltonStoneman I'm not sure what you mean by Docker host but definitely I'm NOT running this code inside the VM or inside another container. So the setup is, I have a Windows 10 PC. This PC hosts the VM – jmc Oct 17 '16 at 13:20
  • Thanks. When you use the browser to check the container, is that from Windows or from the VM? – Elton Stoneman Oct 17 '16 at 13:30
  • @EltonStoneman It is from Windows – jmc Oct 17 '16 at 13:31
  • @NathanielWaisbrot I have added the docker-compose file – jmc Oct 17 '16 at 13:32
  • Deleted my answer, as port exposing is in place. As connection via browser seems to work, probably really some proxy is interfering. – hecko84 Oct 17 '16 at 13:37
  • @hecko84 no problem. however, I can connect to the URL via TCP – jmc Oct 17 '16 at 13:39

1 Answers1

2

Your code is fine, although it would be better to use the new Microsoft.Net.Http NuGet package, which is all async and supports .NET Core.

The only difference between what your code does and what the browser does is the HTTP method in the request. The browser sends a GET but you're explicitly using HEAD. That's the most efficient way if you only want to test connectivity - but the server may not support HEAD requests (I don't know neo4j well enough to be certain).

Try using a GET request instead in your code - this sample uses the new async approach:

    [TestMethod]
    public async Task TestUrls()
    {
        Assert.IsTrue(await UrlIsReachable("http://stackoverflow.com"));
        Assert.IsFalse(await UrlIsReachable("http://111.222.333.444"));
    }

    private async Task<bool> UrlIsReachable(string url)
    {
        try
        {
            using (var client = new HttpClient())
            {
                var response = await client.GetAsync(url);
                return response.StatusCode == HttpStatusCode.OK;
            }
        }            
        catch 
        {
            return false;
        }
    }

The simplest way to automate the test is with PowerShell though, rather than writing a custom app:

Invoke-WebRequest -Uri http://stackoverflow.com -UseBasicParsing

Or if you're sure HEAD is supported:

Invoke-WebRequest -Uri http://stackoverflow.com -Method Head -UseBasicParsing
Elton Stoneman
  • 17,906
  • 5
  • 47
  • 44
  • will this work fine if I include the port? for instance `Assert.IsFalse(await UrlIsReachable("http://111.222.333.444:7474"));` since I have 2 ports in 1 host – jmc Oct 17 '16 at 14:21
  • Yep, you can include the port in the URL string. – Elton Stoneman Oct 17 '16 at 14:27