2010-01-29 2 views
22

У меня есть следующий фрагмент кода в классическом ASP, чтобы отправить команду и получения ответа через SSL:Ошибка 502 (Bad Gateway) при отправке запроса с HttpWebRequest через 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 

Тогда я использовал this code как ссылка на переописать запрос в 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. Есть идеи?

ответ

26

With the help of this У меня появилось более подробное описание проблемы: Прокси-сервер возвращал сообщение: «Пользовательский агент не распознан». Поэтому я установил его вручную. Кроме того, я изменил код для использования GlobalProxySelection.GetEmptyWebProxy(), как описано here. Окончательный рабочий код приведен ниже.

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

Возможно, что wsdl для веб-службы «спорит» с доменным именем и сертификатом SSL. IIS автоматически создаст WSDL веб-службы с использованием зарегистрированного имени домена IIS (по умолчанию это имя машины в локальном домене, не обязательно ваш веб-домен). Если домен сертификата не соответствует домену в адресе SOAP12, вы получите ошибки связи.

28

Прочитать тело объекта ответа об ошибке. Возможно, у него есть намек на то, что происходит.

код, чтобы сделать это следующим образом:

catch(WebException e) 
{ 
if (e.Status == WebExceptionStatus.ProtocolError) 
{ 
    WebResponse resp = e.Response; 
    using(StreamReader sr = new StreamReader(resp.GetResponseStream())) 
    { 
     Response.Write(sr.ReadToEnd()); 
    } 
} 
} 

Это должно показать полное содержание ответа ошибки.

+0

Отличный совет! Используя это, я узнал немного больше о проблеме и придумал решение. Благодарю. – Leonardo

1

UserAgent отсутствует

, например: request.UserAgent = "Mozilla/4.0 (совместимый; MSIE 7.0; Windows NT 5.1)";

0

Это происходило для меня, потому что прокси-сервер Java на удаленной машине запрашивал запросы времени, если приложение Java не ответило вовремя, сделав тайм-ауты .NET по умолчанию бесполезными. Следующий код перебирает все исключения и выписывает ответы, которые помогли мне определить, что на самом деле идет от прокси-сервера:

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&nbsp;/xxx/xxx/xxx</a></em>.<p> 
Reason: <strong>Error reading from remote server</strong></p></p> 
</body></html>