Как проверить, доступен ли локальный URL

Я развертываю контейнеры докеров на своем локальном компьютере. Чтобы убедиться, что они успешно развернуты, я захожу в свой браузер и набираю http://192.168.99.105:7474/browser. Я хотел бы сделать это программно, поэтому я следовал коду в этом вопросе Проверить, доступен ли URL - Помощь в оптимизации класса. Однако, когда я пытаюсь это сделать, я получаю System.Net.WebException {"The remote server returned an error: (504) Gateway Timeout."}.

Однако он отлично работает, и я получаю HttpStatusCode.OK, если URL-адрес https://en.wikipedia.org/wiki/YouTube

Это мой код:

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;
        }
    }

РЕДАКТИРОВАТЬ: мой файл docker-compose.yml

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


person jmc    schedule 17.10.2016    source источник
comment
у вас есть какие-то настройки прокси?   -  person lordkain    schedule 17.10.2016
comment
Как вы запускаете свой контейнер Docker? Пожалуйста, дайте команду или файл docker-compose. Является ли адрес 192 локальным сетевым адресом вашего хост-компьютера или это адрес виртуальной машины, на которой работает Docker?   -  person Nathaniel Waisbrot    schedule 17.10.2016
comment
@lordkain Нет, у меня нет, но я думаю, что это TCP, а не HTTP. Я попробовал тест на веб-сайте web-sniffer.net, и он дал мне Only ports 80,443,8080 allowed. Мой порт 7474.   -  person jmc    schedule 17.10.2016
comment
@NathanielWaisbrot — это адрес виртуальной машины.   -  person jmc    schedule 17.10.2016
comment
Вы запускаете этот код с виртуальной машины — хоста Docker или внутри другого контейнера?   -  person Elton Stoneman    schedule 17.10.2016
comment
@EltonStoneman Я не уверен, что вы имеете в виду под хостом Docker, но определенно я НЕ запускаю этот код внутри виртуальной машины или внутри другого контейнера. Итак, установка такова, что у меня есть ПК с Windows 10. На этом ПК размещена виртуальная машина   -  person jmc    schedule 17.10.2016
comment
Спасибо. Когда вы используете браузер для проверки контейнера, это из Windows или из виртуальной машины?   -  person Elton Stoneman    schedule 17.10.2016
comment
@EltonStoneman Это из Windows   -  person jmc    schedule 17.10.2016
comment
@NathanielWaisbrot Я добавил файл для создания докеров   -  person jmc    schedule 17.10.2016
comment
Удалил мой ответ, так как раскрытие порта на месте. Поскольку подключение через браузер работает, возможно, действительно какой-то прокси мешает.   -  person hecko84    schedule 17.10.2016
comment
@ hecko84 нет проблем. однако я могу подключиться к URL-адресу через TCP   -  person jmc    schedule 17.10.2016


Ответы (1)


Ваш код в порядке, хотя было бы лучше использовать новый пакет Microsoft.Net.Http NuGet, который полностью асинхронен и поддерживает .NET Core.

Единственная разница между тем, что делает ваш код, и тем, что делает браузер, — это метод HTTP в запросе. Браузер отправляет GET, но вы явно используете HEAD. Это самый эффективный способ, если вы хотите только проверить подключение, но сервер может не поддерживать запросы HEAD (я недостаточно хорошо знаю neo4j, чтобы быть уверенным).

Попробуйте вместо этого использовать в коде запрос GET — в этом примере используется новый асинхронный подход:

    [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;
        }
    }

Однако самый простой способ автоматизировать тест — использовать PowerShell, а не писать собственное приложение:

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

Или, если вы уверены, что HEAD поддерживается:

Invoke-WebRequest -Uri http://stackoverflow.com -Method Head -UseBasicParsing
person Elton Stoneman    schedule 17.10.2016
comment
будет ли это работать нормально, если я включу порт? например Assert.IsFalse(await UrlIsReachable("http://111.222.333.444:7474")); так как у меня 2 порта на 1 хосте - person jmc; 17.10.2016
comment
Да, вы можете включить порт в строку URL. - person Elton Stoneman; 17.10.2016