用HttpWebRequest通过代理,访问https时出错??

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了用HttpWebRequest通过代理,访问https时出错??相关的知识,希望对你有一定的参考价值。

公司里用着proxy,访问http页面时能成功;但访问https页面会报错,异常如下:
WebException status : ConnectFailure
WebException message : The underlying connection was closed: Unable to connect to the remote server.

代码大致是这样的
if (url.StartsWith("h_ttps://", StringComparison.OrdinalIgnoreCase))

ServicePointManager.ServerCertificateValidationCallback = new RemoteCertificateValidationCallback(CheckValidationResult);

m_httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
//m_httpWebRequest.ProtocolVersion = HttpVersion.Version10;

Logger.LogDebug("Proxy = " + m_httpWebRequest.Proxy.GetProxy(new Uri(url)));

else

m_httpWebRequest = (HttpWebRequest)HttpWebRequest.Create(url);
//m_httpWebRequest.Proxy = null;

现在能确定,应该是proxy的问题;同样的程序,在家里尝试时,访问https也是正常的。
公司的proxy设置就是ie浏览器里普通设置的那种,一个地址+一个端口,并对所有协议使用相同的proxy。

谁能帮我解答一下。。。
还有怎么获得HttpWebRequest失败时的详细信息,现在我只能看到连接失败,不知道具体原因是什么。。。
不知道为啥,百度老提示有些词不能发。。。。
1.h_tt什么的,不是拼写错误。。。
2.proxy设置,我没写,用的默认的,症状如我所述。
尝试了新建一个代理对象,效果也一样。

刚才还把这个问题发错了分类,
谁要能解决了,受累在那个同名的帖子也回答一下,把那200分也给你。。。
======
试着开启了.net的Network Tracing,得到了一些log,
我是用google的网址实验的,貌似是proxy返回了一个空内容的成功应答,
然后httpWebRequest就把自己的socket给关掉了,
然后再获得response时因为是对已关闭的socket操作,就抛出异常了。。。。
谁能帮着解决一下。。。。我不太明白这块。。。
======
代理的地址设置什么的,没问题;用浏览器都能正常访问。
怀疑是HttpWebRequest有bug了,试了.net 2.0和4.0,都不行。。。
已经放弃C#,改用java写了。。

参考技术A 4.数据库连接字符串:
数据库连接字符串有很多种,如:
Data Server=.\SQLEXPRESS;Initial Catalog=Northwind;User ID=sa;Password=sapassSql
Data Server=服务器名\SQLEXPRESS;Initial Catalog=Northwind;User ID=sa;Password= sapassSql
Data Server=localhost\SQLEXPRESS;Initial Catalog=Northwind;User ID=sa;Password= sapassSql
Data Server=.;Initial Catalog=Northwind;User ID=sa;Password= sapassSql
Data Server=服务器名;Initial Catalog=Northwind;User ID=sa;Password= sapassSql
具体的选择是和SQLServer2005的版本有关系,如果是SQLServer 2005 Express版本,则必须要有“\SQLEXPRESS”,因此如果字符串是定义为一个变量的时候应该写成Server=. \\SQLEXPRESS。
参考技术B 打断点查看RemoteCertificateValidationCallback委托引用的方法的返回值

你是否正确的设置了网关地址和端口,还有认证的用户名密码呢?追问

在这个RemoteCertificateValidationCallback之前,程序就已经抛异常了。。

追答

catch(HttpException ex)

throw new Exception(ex.GethtmlErrorMessage());


看看提示的什么错

参考技术C 试试异步访问?本回答被提问者采纳

使用HttpWebRequest时,为什么我在某些链接上出现“(304)Not Modified”错误?

我尝试使用HttpWebRequest访问某些链接的任何想法我得到“远程服务器返回错误:(304)未修改。”在代码中?

我正在使用的代码来自Jeff's post here(页面似乎已经消失,请参阅archive copy at the Wayback Machine)。

注意代码的概念是一个简单的代理服务器,因此我将浏览器指向这个本地运行的代码片段,它获取我的浏览器请求,然后通过创建新的HttpWebRequest代理它,如您所见代码。它适用于大多数网站/链接,但对于一些人来说,这个错误出现了。您将在代码中看到一个关键位,它似乎将http标头设置从浏览器请求复制到它的请求到网站,并在标头属性中复制。不确定问题是否与它如何模仿请求的这个方面有关,然后结果会发生什么?

case "If-Modified-Since":
   request.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]);
   break;

我从http://en.wikipedia.org/wiki/Main_Page那里得到了问题

PS。更新在这里

仍然无法解决这个问题。基本上我可以识别1个有问题的链接,它似乎工作正常,第二次得到错误,第3次OK,第4次得到错误,第5次OK等等。好像有一些状态没有被清除或代码中有些东西。我尝试使用“使用”类型语句等来清理代码。

这是代码。如果有人能够通过这个代理代码每次第二次浏览到像http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css这样的链接(从第二次开始,而不是第一次),我会得到错误,我很乐意听到。

class Program
{
    static void Main(string[] args)
    {
        Proxy p = new Proxy(8080);

        Thread proxythread = new Thread(new ThreadStart(p.Start));
        proxythread.Start();

        Console.WriteLine("Proxy Started. Press Any Key To Stop...");
        Console.ReadKey();

        p.Stop();
     }
}

public class Proxy
{
    private HttpListener _listener;
    private int _port;

    public Proxy(int port)
    {
        int defaultport = 8080;

        // Setup Thread Pool
        System.Threading.ThreadPool.SetMaxThreads(50, 1000);
        System.Threading.ThreadPool.SetMinThreads(50, 50);

        // Sanitize Port Number
        if (port < 1024 || port > 65535)
            port = defaultport;

        // Create HttpListener Prefix
        string prefix = string.Format("http://*:{0}/", port);
        _port = port;

        // Create HttpListener
        _listener = new HttpListener();
        _listener.Prefixes.Add(prefix);
    }

    public void Start()
    {
        _listener.Start();

        while (true)
        {
            HttpListenerContext request = null;

            try
            {
                request = _listener.GetContext();

                // Statistics (by Greg)
                int availThreads = -1;
                int compPortThreads = -1;
                ThreadPool.GetAvailableThreads(out availThreads, out compPortThreads);
                log("INFO", request.Request.Url.ToString(), "START - [" + availThreads + "]");

                ThreadPool.QueueUserWorkItem(ProcessRequest, request);
            }
            catch (HttpListenerException ex)
            {
                log("ERROR", "NA", "INFO: HttpListenerException - " + ex.Message);
                break;
            }
            catch (InvalidOperationException ex)
            {
                log("ERROR", "NA", "INFO: InvalidOperationException - " + ex.Message);
                break;
            }
        }
    }

    public void Stop()
    {
        _listener.Stop();
    }

    private void log(string sev, string uri, string message)
    {
        Console.Out.WriteLine(Process.GetCurrentProcess().Id + " - " + sev + " (" + uri + "): " + message);
    }

    private void ProcessRequest(object _listenerContext)
    {
        #region local variables
        HttpWebRequest psRequest;                   // Request to send to remote web server
        HttpWebResponse psResponse;                 // Response from remote web server         
        List<byte> requestBody = new List<byte>();  // Byte array to hold the request's body
        List<byte> responseBody = new List<byte>(); // Byte array to hold the response's body
        byte[] buffer;
        string uri = "";
        #endregion

        var listenerContext = (HttpListenerContext)_listenerContext;
        uri = listenerContext.Request.Url.ToString().Replace(string.Format(":{0}", _port), "");

        // Create Interent Request 
        HttpWebRequest internetRequest = (HttpWebRequest)WebRequest.Create(uri);
        #region Build Request Up
        internetRequest.Method = listenerContext.Request.HttpMethod;
        internetRequest.ProtocolVersion = listenerContext.Request.ProtocolVersion;
        internetRequest.UserAgent = listenerContext.Request.UserAgent;
        foreach (string key in listenerContext.Request.Headers.AllKeys)
        {
            try
            {
                switch (key)
                {
                    case "Proxy-Connection":
                    case "Connection":
                        internetRequest.KeepAlive = (listenerContext.Request.Headers[key].ToLower() == "keep-alive") ? true : false;
                        break;

                    case "Content-Length":
                        internetRequest.ContentLength = listenerContext.Request.ContentLength64;
                        break;

                    case "Content-Type":
                        internetRequest.ContentType = listenerContext.Request.ContentType;
                        break;

                    case "Accept":
                        internetRequest.Accept = listenerContext.Request.Headers[key];
                        break;

                    case "Host":
                        break;

                    case "Referer":
                        internetRequest.Referer = listenerContext.Request.Headers[key];
                        break;

                    case "If-Modified-Since":
                        internetRequest.IfModifiedSince = DateTime.Parse(listenerContext.Request.Headers[key]);
                        break;

                    default:
                        internetRequest.Headers.Add(key, listenerContext.Request.Headers[key]);
                        break;
                }
            }
            catch (Exception ex)
            {
                Console.WriteLine("Error settup up psRequest object. Error = " + ex.Message + "
" + ex.StackTrace);
            }
        }
        #endregion

        #region Copy content into request
        buffer = new byte[1024];
        using (Stream instream = listenerContext.Request.InputStream)
        {
            int incount = instream.Read(buffer, 0, buffer.Length);
            while (incount > 0)
            {
                internetRequest.GetRequestStream().Write(buffer, 0, incount);
                incount = instream.Read(buffer, 0, buffer.Length);
            }
        }
        #endregion

        // Get Internet Response
        HttpWebResponse internetResponse = null;
        try
        {
            using (internetResponse = (HttpWebResponse)internetRequest.GetResponse())
            {
                #region Configure Local Response Header Keys
                foreach (string key in internetResponse.Headers.Keys)
                {
                    try
                    {
                        switch (key)
                        {
                            case "Transfer-Encoding":
                                listenerContext.Response.SendChunked = (internetResponse.Headers[key].ToLower() == "chunked") ? true : false;
                                break;

                            case "Content-Length":
                                listenerContext.Response.ContentLength64 = internetResponse.ContentLength;
                                break;

                            case "Content-Type":
                                listenerContext.Response.ContentType = internetResponse.Headers[key];
                                break;

                            case "Keep-Alive":
                                listenerContext.Response.KeepAlive = true;
                                break;

                            default:
                                listenerContext.Response.Headers.Add(key, internetResponse.Headers[key]);
                                break;
                        }
                    }
                    catch (Exception ex)
                    {
                        log("ERROR", uri, "Error settup up listenerContext.Response objects. Error = " + ex.Message + "
" + ex.StackTrace);
                    }
                }
                #endregion

                try
                {
                    // Transfer the body data from Internet Response to Internal Response
                    buffer = new byte[1024];
                    using (Stream inputStream = internetResponse.GetResponseStream())
                    {
                        int outcount = inputStream.Read(buffer, 0, buffer.Length);
                        while (outcount > 0)
                        {
                            listenerContext.Response.OutputStream.Write(buffer, 0, outcount);
                            outcount = inputStream.Read(buffer, 0, buffer.Length);
                        }
                    }
                }
                catch (Exception ex)
                {
                    log("ERROR", uri, "Could not obtain response from URI: " + ex.Message);
                }
                finally
                {
                    listenerContext.Response.OutputStream.Close();
                }
            }
        }
        catch (Exception ex)
        {
            //if (ex is InvalidOperationException ||
            //    ex is ProtocolViolationException ||
            //    ex is WebException)
            //{
            //    log(uri, "Could not successfully get response: " + ex.GetType() + " - " + ex.Message);
            //    listenerContext.Response.Close();
            //    return;
            //}
            //else { throw; }

            log("ERROR", uri, "Could not successfully get response: " + ex.GetType() + " - " + ex.Message);
            listenerContext.Response.Close();
        }
    }
}

这是我看到的一个例子 - 第一次打击是好的,第二次有错误...

Proxy Started. Press Any Key To Stop...
2080 - INFO (http://newsimg.bbc.co.uk:8080/css/screen/1_0_16/nol/v4/story.css): START - [50]
2080 - INFO (http://newsimg.bbc.co.uk:8080/css/screen/1_0_16/nol/v4/story.css): START - [50]
2080 - ERROR (http://newsimg.bbc.co.uk/css/screen/1_0_16/nol/v4/story.css): Could not successfully get response: System.Net.WebException - The remote server returned an error: (304) Not Modified.
答案

首先,这不是错误。 3xx表示重定向。真正的错误是4xx(客户端错误)和5xx(服务器错误)。

如果客户获得304 Not Modified,那么客户有责任从自己的缓存中显示有问题的资源。通常,代理不应该担心这一点。这只是信使。

另一答案

这是预期的行为。

当您发出HTTP请求时,服务器通常会返回代码200 OK。如果设置If-Modified-Since,服务器可能会返回304 Not modified(并且响应将不包含内容)。这应该是您未修改页面的提示。

authors of the class have foolishly decided 304应被视为错误并抛出异常。现在你必须通过每次尝试使用If-Modified-Since时捕获异常来清理它们。

另一答案

只按F5并不总是有效。

为什么?

因为您的ISP也在为您缓存Web数据。

解决方案:强制刷新。

通过在Firefox或Chrome中按CTRL + F5强制刷新浏览器以清除ISP缓存,而不是仅按F5

然后,您可以在浏览器F12开发人员工具网络选项卡中看到200响应而不是304响应。

另一个技巧是在请求页面的URL字符串末尾添加问号?

http://localhost:52199/Customers/Create?

问号将确保浏览器刷新请求而不缓存任何先前的请求。

此外,在Visual Studio中,您可以在隐身模式下将默认浏览器设置为Chrome,以避免在开发过程中出现缓存问题,方法是在隐身模式下添加Chrome作为默认浏览器,请参阅步骤(自我说明):

Go to browsers list Select browse with... Click Add... Point to the chrome.exe on your platform, add argument "Incognito" Choose the browser you just added and set as default, then click browse

另一答案

我想你还没有安装这些功能。见下图。

几天前我也遇到了这个问题。安装此功能后,我解决了它。如果您尚未安装此功能,则安装它。

安装过程:

  1. 去android工作室
  2. 工具
  3. Android的
  4. SDK Manager
  5. 外观和行为
  6. Android SDK

以上是关于用HttpWebRequest通过代理,访问https时出错??的主要内容,如果未能解决你的问题,请参考以下文章

HTTPWebRequest.GetResponse() 通过透明代理验证请求失败

为啥通过 .Net 代理的 HttpWebrequest 失败?

c# HttpWebRequest 使用代理访问网页,在vs中release调试的时候可以,直接运行出错

通过apiservice反向代理访问service

HttpWebRequest类

如何通过httpwebrequest访问使用证书登录的网站