2010-01-29 17 views
22

Ich habe folgende Code-Schnipsel in klassischen ASP, einen Befehl zu senden und die Antwort über SSL abrufen:Fehler 502 (Bad Gateway), wenn das Senden einer Anfrage mit HttpWebRequest über 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 

Dann habe ich this code als Referenz die Anfrage in C# neu zu implementieren:

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

Das Problem ist, wenn GetRequestStream Aufruf ich erhalte eine WebException mit der Meldung "The remote server returned an error: (502) Bad Gateway."

Zuerst dachte ich, es hätte mit der Verifizierung des SSL-Zertifikats zu tun. Also hat ich diese Zeile:

ServicePointManager.CertificatePolicy = new AcceptAllCertificatePolicy(); 

Wo

public class AcceptAllCertificatePolicy : ICertificatePolicy 
{ 
    public bool CheckValidationResult(ServicePoint srvPoint, 
             System.Security.Cryptography.X509Certificate certificate, 
             WebRequest request, 
             int certificateProblem) 
    { 
     return true; 
    } 
} 

Und ich halte die gleichen 502 Fehler. Irgendwelche Ideen?

Antwort

26

With the help of this Ich habe eine ausführlichere Beschreibung des Problems: Der Proxy wurde die Nachricht zurück: "Der Benutzer-Agent wird nicht erkannt." Also stelle ich es manuell ein. Außerdem habe ich den Code geändert, um GlobalProxySelection.GetEmptyWebProxy() zu verwenden, wie here beschrieben. Der endgültige Arbeitscode ist unten enthalten.

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

Es ist möglich, dass die WSDL für den Webdienst mit dem Domänennamen und dem SSL-Zertifikat "streitet". IIS generiert die WSDL eines Webdienstes automatisch unter Verwendung des IIS-registrierten Domänennamens (standardmäßig der Computername der lokalen Domäne, nicht unbedingt Ihre Webdomäne). Wenn die Zertifikatsdomäne nicht mit der Domäne in der SOAP12-Adresse übereinstimmt, erhalten Sie Kommunikationsfehler.

28

Lesen Sie den Entitätshauptteil der Fehlerreaktion. Es könnte einen Hinweis darauf geben, was passiert.

Der Code zu tun, ist wie folgt:

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

, dass der volle Inhalt der Fehlerreaktion zeigen.

+0

Exzellente Beratung! Damit habe ich ein wenig mehr über das Problem herausgefunden und eine Lösung gefunden. Vielen Dank. – Leonardo

1

Useragent fehlt

zum Beispiel: request.UserAgent = "Mozilla/4.0 (compatible; MSIE 7.0; Windows NT 5.1)";

0

Dies passierte für mich, weil ein Java-Proxy auf dem Remote-Rechner Anforderungen verzögerte, wenn die Java-Anwendung nicht rechtzeitig reagierte und die .NET-Standardzeitlimits nutzlos machte. Der folgende Code durchläuft alle Ausnahmen und schreibt Antworten, die mir geholfen, festzustellen, dass es kommen würde tatsächlich von dem Proxy:

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

Der Antworttext vom Proxy sah etwa so aus:

<!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> 
Verwandte Themen