用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写了。。
数据库连接字符串有很多种,如:
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());
看看提示的什么错
使用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作为默认浏览器,请参阅步骤(自我说明):
我想你还没有安装这些功能。见下图。
几天前我也遇到了这个问题。安装此功能后,我解决了它。如果您尚未安装此功能,则安装它。
安装过程:
- 去android工作室
- 工具
- Android的
- SDK Manager
- 外观和行为
- Android SDK
以上是关于用HttpWebRequest通过代理,访问https时出错??的主要内容,如果未能解决你的问题,请参考以下文章
HTTPWebRequest.GetResponse() 通过透明代理验证请求失败
为啥通过 .Net 代理的 HttpWebrequest 失败?