Восстановление после ошибки NameResolutionFailure во время HTTPWebRequest - PullRequest
4 голосов
/ 27 апреля 2019

В нашей надстройке Outlook COM мы выполняем вызов API для нашего сервера с помощью метода .NET HTTPWebRequest.Один из наших клиентов сталкивается с System.Net.WebException с сообщением The remote name could not be resolved: 'mydomain.com' и WebExceptionStatus.NameResolutionFailure в качестве статуса.Все пользователи компании этого конкретного клиента используют outlook / надстройку из-за VPN, поэтому для выполнения запроса мы настраиваем прокси-сервер из IE.

Наши вызовы API работают в течение определенного периода времени.но затем он случайным образом отключается, а затем не пропускает будущие запросы.Как только пользователи закрывают и перезагружают Outlook, кажется, он снова работает нормально, без изменения какой-либо конфигурации сети или повторного подключения к Wi-Fi и т. Д.,Мы добавили механизм повторных попыток с 3 попытками, каждая с перерывом в спящем режиме, но это не решило проблему с перебоями.

Наш домен подключен к AWS Classic Load Balancer, поэтому mydomain.com фактически разрешает CNAMEзапись в статический домен AWS, указывая на ELB.Я не уверен, окажет ли это какое-либо влияние на запрос или его маршрутизацию.

Странно то, что у нас также есть компонент веб-браузера, который загружает веб-страницу в боковую панель из того же домена, что иВызовы API.Он отлично работает и загружает URL из того же домена.Пользователи также могут загрузить URL в своих браузерах без каких-либо проблем.Просто кажется, что HTTPWebRequest сталкивается с проблемой разрешения домена.Мы проверили, что это не просто слабый сигнал Wi-Fi.Так как они могут использовать IE, который имеет ту же конфигурацию прокси, для доступа к сайту просто отлично, я не думаю, что это так.

Мы в недоумении, как изящно восстановить и сделать запрос попытатьсяснова.Я рассмотрел предложения от этого ответа и этого другого ответа , мы попробуем их дальше.К сожалению, мы не можем заставить запросы использовать прямые IP-адреса, как предполагают некоторые другие ответы.Это также устраняет возможность редактировать файл hosts так, чтобы он указывал прямо на него.Причина в том, что мы не можем назначить статический IP-адрес классическому ELB.

Мы рассматриваем попытку настроить хост на прямое использование записи CNAME из AWS, но это приведет к ошибкам SSL, поскольку это нене имеет действующего сертификата для записи CNAME.Есть ли способ обойти это, маскируя его с помощью заголовка, аналогично подходу IP?

Не стесняйтесь спрашивать дополнительную информацию, я сделаю все возможное, чтобы предоставить ее.

Приветствуются любые предложения о том, что попробовать или устранить неполадки!

Обновление: Мы нацелены на .NET v4.5

Вот код

var result = string.Empty;
bool retrying = false;
int retries = 0;
HttpWebRequest webRequest = null;

try
{
    ServicePointManager.ServerCertificateValidationCallback =
        CertificateCheck;
    ServicePointManager.MaxServicePoints = 4;
    ServicePointManager.SecurityProtocol = SecurityProtocolType.Tls12;

retry:
    webRequest = (HttpWebRequest)WebRequest.Create(uriParam);
    webRequest.Timeout = 120000;
    webRequest.Method = "POST";
    webRequest.ContentType = "application/x-www-form-urlencoded";
    webRequest.Accept = acceptParam;
    webRequest.Headers.Add("Cookie", cookieParam);
    webRequest.UseDefaultCredentials = true;
    webRequest.Proxy = null;
    webRequest.KeepAlive = true; //default
    webRequest.ServicePoint.ConnectionLeaseTimeout = webRequest.Timeout;
    webRequest.ServicePoint.MaxIdleTime = webRequest.Timeout;
    webRequest.ContentLength = dataParam.Length;

    using (var reqStream = webRequest.GetRequestStream())
    {
        reqStream.Write(dataParam, 0, dataParam.Length);
        reqStream.Flush();
        reqStream.Close();
    }

    try
    {
        using (WebResponse webResponse = webRequest.GetResponse())
        {
            using (var responseStream = webResponse.GetResponseStream())
            {
                if (responseStream != null)
                {
                    using (var reader = new StreamReader(responseStream))
                    {
                        result = reader.ReadToEnd();
                    }
                }
            }
            webResponse.Close();
        }

    }
    catch (WebException)
    {
        if (retrying && retries == 3)
        {
            //don't retry any more
            return string.Empty;
        }

        retrying = true;
        retries++;
        webRequest.Abort();
        System.Threading.Thread.Sleep(2000);
        goto retry;
    }
}
catch (Exception ex)
{
    Log.Error(ex);
    result = string.Empty;
}
finally
{
    webRequest?.Abort();
}

return result;
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...