使用HttpWebRequest通过SSL发送请求时出现502错误(坏的网关)

27
我有以下经典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错误。有什么想法吗?

5个回答

36

阅读错误响应的实体主体。它可能会给出一些提示,说明正在发生什么。

执行此操作的代码如下:

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

这应该显示错误响应的全部内容。


非常好的建议!使用这个,我对问题有了更深入的了解,并想出了一个解决方案。谢谢。 - Leonardo

27

这里 我得到了更详细的问题描述:代理返回消息:“未识别的用户代理” 。因此,我手动设置了它。另外,我改变了代码使用GlobalProxySelection.GetEmptyWebProxy() ,如这里所述。最终工作的代码如下。

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

2

我遇到了这个问题,因为远程机器上的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>

这揭示了大量的服务器信息,以前我无法获取。 - TvdH

2

缺少UserAgent

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


1

Web服务的wsdl可能与域名和SSL证书发生“争执”。 IIS将使用IIS注册的域名自动生成Web服务的WSDL(默认为本地域上的计算机名称,不一定是您的Web域)。如果证书域与SOAP12地址中的域不匹配,则会收到通信错误。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接