Ошибка 502 (плохой шлюз) при отправке запроса с помощью HttpWebRequest по протоколу SSL
-
23-09-2019 - |
Вопрос
У меня есть следующий фрагмент в классическом ASP, чтобы отправить команду и получить ответ по протоколу SSL:
Dim xmlHTTP
Set xmlHTTP = Server.CreateObject("Msxml2.ServerXMLHTTP.3.0")
xmlHTTP.open "POST", "https://www.example.com", False
xmlHTTP.setRequestHeader "Content-Type","application/x-www-form-urlencoded"
xmlHTTP.setRequestHeader "Content-Length", Len(postData)
xmlHTTP.Send postData
If xmlHTTP.status = 200 And Len(message) > 0 And Not Err Then
Print xmlHTTP.responseText
End If
Затем я использовал этот код в качестве ссылки на переопределение запроса в c#:
private static string SendRequest(string url, string postdata)
{
WebRequest rqst = HttpWebRequest.Create(url);
// We have a proxy on the domain, so authentication is required.
WebProxy proxy = new WebProxy("myproxy.mydomain.com", 8080);
proxy.Credentials = new NetworkCredential("username", "password", "mydomain");
rqst.Proxy = proxy;
rqst.Method = "POST";
if (!String.IsNullOrEmpty(postdata))
{
rqst.ContentType = "application/x-www-form-urlencoded";
byte[] byteData = Encoding.UTF8.GetBytes(postdata);
rqst.ContentLength = byteData.Length;
using (Stream postStream = rqst.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
postStream.Close();
}
}
((HttpWebRequest)rqst).KeepAlive = false;
StreamReader rsps = new StreamReader(rqst.GetResponse().GetResponseStream());
string strRsps = rsps.ReadToEnd();
return strRsps;
}
Проблема в том, что при вызове GetRequestStream я продолжаю получать WebException с сообщением "The remote server returned an error: (502) Bad Gateway."
Сначала я подумал, что это связано с проверкой SSL-сертификата.Итак, я добавил эту строку:
ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy();
Где
public class AcceptAllCertificatePolicy : ICertificatePolicy
{
public bool CheckValidationResult(ServicePoint srvPoint,
System.Security.Cryptography.X509Certificate certificate,
WebRequest request,
int certificateProblem)
{
return true;
}
}
И я продолжаю получать ту же ошибку 502.Есть какие-нибудь идеи?
Решение 2
С помощью этого Я получил более подробное описание проблемы:Прокси-сервер возвращал сообщение:"Пользовательский агент не распознан." Поэтому я установил это вручную.Кроме того, я изменил код, чтобы использовать Глобальный проксимальный выбор.Получить доступ к WebProxy(), как описано здесь.Окончательный рабочий код приведен ниже.
private static string SendRequest(string url, string postdata)
{
if (String.IsNullOrEmpty(postdata))
return null;
HttpWebRequest rqst = (HttpWebRequest)HttpWebRequest.Create(url);
// No proxy details are required in the code.
rqst.Proxy = GlobalProxySelection.GetEmptyWebProxy();
rqst.Method = "POST";
rqst.ContentType = "application/x-www-form-urlencoded";
// In order to solve the problem with the proxy not recognising the user
// agent, a default value is provided here.
rqst.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";
byte[] byteData = Encoding.UTF8.GetBytes(postdata);
rqst.ContentLength = byteData.Length;
using (Stream postStream = rqst.GetRequestStream())
{
postStream.Write(byteData, 0, byteData.Length);
postStream.Close();
}
StreamReader rsps = new StreamReader(rqst.GetResponse().GetResponseStream());
string strRsps = rsps.ReadToEnd();
return strRsps;
}
Другие советы
Прочитайте текст объекта ответа об ошибке.В нем может быть намек на то, что происходит.
Код для этого выглядит следующим образом:
catch(WebException e)
{
if (e.Status == WebExceptionStatus.ProtocolError)
{
WebResponse resp = e.Response;
using(StreamReader sr = new StreamReader(resp.GetResponseStream()))
{
Response.Write(sr.ReadToEnd());
}
}
}
Это должно показать полное содержимое ответа об ошибке.
Возможно, что wsdl для веб-службы "спорит" с доменным именем и SSL-сертификатом.IIS автоматически сгенерирует WSDL веб-службы, используя зарегистрированное в IIS доменное имя (которое по умолчанию является именем компьютера в локальном домене, не обязательно в вашем веб-домене).Если домен сертификата не совпадает с доменом в адресе SOAP12, вы получите сообщения об ошибках связи.
Пользовательский агент отсутствует
например :запрос.UserAgent = "Mozilla/4.0 (совместимый;MSIE 7.0;Windows NT 5.1)";
У меня это происходило из-за того, что прокси-сервер Java на удаленном компьютере отключал запросы, если Java-приложение не отвечало вовремя, делая .Тайм-ауты по умолчанию в СЕТИ бесполезными.Следующий код перебирает все исключения и выписывает ответы, которые помогли мне определить, что это действительно исходило от прокси:
static void WriteUnderlyingResponse(Exception exception)
{
do
{
if (exception.GetType() == typeof(WebException))
{
var webException = (WebException)exception;
using (var writer = new StreamReader(webException.Response.GetResponseStream()))
Console.WriteLine(writer.ReadToEnd());
}
exception = exception?.InnerException;
}
while (exception != null);
}
Тело ответа от прокси-сервера выглядело примерно так:
<!DOCTYPE HTML PUBLIC "-//IETF//DTD HTML 2.0//EN">
<html><head>
<title>502 Proxy Error</title>
</head><body>
<h1>Proxy Error</h1>
<p>The proxy server received an invalid
response from an upstream server.<br />
The proxy server could not handle the request <em><a href="/xxx/xxx/xxx">POST /xxx/xxx/xxx</a></em>.<p>
Reason: <strong>Error reading from remote server</strong></p></p>
</body></html>