我正在使用.net 4.61并在https://www.tvone.tv上使用VB执行httpwebrequest,并且每次都无法连接到服务器。除.tv之外的任何其他域上的任何其他查找都可以正常工作。我得http://ustream.tv只工作一次,但只有一次而且再也没有。
这是一个.net问题还是.net的dns问题?
IE,Edge,Firefox和Chrome都可以从我用来编译的计算机上加载网页。所以,我知道这不是一个网络问题。
我是否需要使用httpwebrequests加载.tv域的特定方式?
答案 0 :(得分:1)
您提到的其中一个网站在URI中有Https:
架构
这意味着使用了安全协议。经检查,该站点使用TLS 1.2安全协议。因此,您必须使用ServicePointManager
启用它,设置为:ServicePointManager.SecurityProtocol
= SecurityProtocolType.Tls12
。
此外,大多数情况下,网站使用Cookie(或 使用Cookie,因为外部资源需要它们。例如,Google工具)。
您必须提供接受,存储和交换它们的方法
这是完成实例化CookieContainer Object并使用其HttpWebRequest将其传递给.CookieContainer()
Property
https://www.tvone.tv
)。它是不接受Https:
之外的其他模式的其中一个。如果您更改它,它会将您的请求重定向回它(通过Tls 1.2证书交换强制安全性)。但它(至少是主页)不使用cookies
由于我认为它有点有趣,我发布了用于测试的代码。如果在“页眉”设置中设置了.AllowAutoRedirect = False
,则可以按照重定向查看其功能。
主机URI:https://tvone.tv/
IP地址:45.79.161.20
响应状态:OK Http协议:Http / 1.1
Cookies n°:0安全协议:Tls 1.2
使用
Https:
架构尝试此操作 主机URI:http://www.ustream.tv/
IP地址:199.66.238.212
响应状态:OK Http协议:Http / 1.1
Cookies n°:2安全协议:N / A
主机URI:http://www.fyi.tv/
IP地址:151.101.14.168
响应状态:OK Http协议:Http / 1.1
Cookies n°:1安全协议:N / A
这是用于测试的代码
(它是我的图书馆的编辑/翻译版本,因此如果你使用它,你不必担心踩到任何人的脚趾。)
主函数HTTP_GetWebPageAsync()
可以这样调用:
(返回的对象返回时其属性填充了上面结果中显示的数据,加上响应的整个Html页面(在Public Property PayLoad
中)。)
Public HttpReqObject As HttpReqObj = New HttpReqObj
Dim MaxWaitTimeOut As Integer = 30 'Seconds
HttpReqObject.SiteURL = "https://tvone.tv/"
HttpReqObject = Await HTTP_GetWebPageAsync(HttpReqObject, MaxWaitTimeOut)
Imports System.IO
Imports System.Net
Imports System.Net.Security
Imports System.Reflection
Imports System.Security
Imports System.Security.Authentication
Imports System.Security.Cryptography.X509Certificates
Imports System.Text
Private Const COR_E_INVALIDOPERATION As Int32 = &H80131509
Public Class HttpReqObj
Public Property SiteURL As String
Public Property StatusCode As HttpStatusCode
Public Property PayLoad As String
Public Property Cookies As CookieContainer
Public Property HostAddress As IPAddress()
Public Property HttpProtocol As String
Public Property SslProtocol As SslProtocols
End Class
Public Async Function HTTP_GetWebPageAsync(HttpSite As HttpReqObj, ReqTimeOut As Integer) As Task(Of HttpReqObj)
Dim _HttpRequest As HttpWebRequest
Dim _Cookiejar As New CookieContainer()
Dim _StatusCode As HttpStatusCode
Dim _RedirectURL As String = String.Empty
Dim _Referer As String = String.Empty
Dim _Payload As String = String.Empty
Dim _MaxAwaitableTimeout As Integer = ReqTimeOut
Dim _MaxHops As Integer = 40
ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3 Or
SecurityProtocolType.Tls11 Or
SecurityProtocolType.Tls12
ServicePointManager.ServerCertificateValidationCallback = AddressOf TlsValidationCallback
Try
_HttpRequest = WebRequest.CreateHttp(HttpSite.SiteURL)
HttpSite.HostAddress = Await Dns.GetHostAddressesAsync(_HttpRequest.Host)
HTTP_RequestHeadersInit(_HttpRequest, _Cookiejar, "")
_HttpRequest.Method = WebRequestMethods.Http.Get
Using httpResponse As HttpWebResponse = CType(Await _HttpRequest.GetResponseAsync(),
HttpWebResponse)
_StatusCode = httpResponse.StatusCode
_Payload = If(_StatusCode = HttpStatusCode.OK, ProcessResponse(httpResponse, HttpSite), String.Empty)
_RedirectURL = URIFromResponseLocation(httpResponse).ToString()
HttpSite.HttpProtocol = "Http/" + _HttpRequest.ProtocolVersion.ToString()
End Using
'On Page Redirection, follow redirections [_MaxHops] hops and [_MaxAwaitableTimeout] time
If (_RedirectURL <> HttpSite.SiteURL) Or (_StatusCode = HttpStatusCode.Moved) OrElse
(_StatusCode = HttpStatusCode.Found) OrElse
(_StatusCode = HttpStatusCode.RedirectMethod) Then
If (_RedirectURL <> HttpSite.SiteURL) Then
Dim _SW As Stopwatch = New Stopwatch()
_SW.Start()
_Referer = HttpSite.SiteURL
HttpSite.SiteURL = _RedirectURL
_HttpRequest = WebRequest.CreateHttp(HttpSite.SiteURL)
_HttpRequest.Method = WebRequestMethods.Http.Get
HTTP_RequestHeadersInit(_HttpRequest, _Cookiejar, _Referer)
Dim _hops As Integer = 1
Do
Using httpResponse As HttpWebResponse = CType(Await _HttpRequest.GetResponseAsync(),
HttpWebResponse)
_Payload = ProcessResponse(httpResponse, HttpSite)
_StatusCode = httpResponse.StatusCode
_RedirectURL = URIFromResponseLocation(httpResponse).ToString()
End Using
If _RedirectURL <> HttpSite.SiteURL Then
If (_StatusCode = HttpStatusCode.Moved) OrElse
(_StatusCode = HttpStatusCode.Found) OrElse
(_StatusCode = HttpStatusCode.RedirectMethod) Then
HttpSite.SiteURL = _RedirectURL
_HttpRequest = WebRequest.CreateHttp(HttpSite.SiteURL)
HTTP_RequestHeadersInit(_HttpRequest, _Cookiejar, _Referer)
_hops += 1
End If
End If
If _SW.Elapsed.Seconds > _MaxAwaitableTimeout Then
_StatusCode = HttpStatusCode.RequestTimeout
Exit Do
End If
Loop While (_StatusCode <> HttpStatusCode.OK) AndAlso (_hops < _MaxHops)
_SW.Stop()
End If
End If
Catch exW As WebException
_StatusCode = If(exW.Response IsNot Nothing, CType(exW.Response, HttpWebResponse).StatusCode,
CType(exW.Status, HttpStatusCode))
_Payload = String.Empty
Catch exS As System.Exception
If exS.HResult = COR_E_INVALIDOPERATION Then
'_StatusCode = If(InternetConnection() > 0, CType(WebExceptionStatus.NameResolutionFailure, HttpStatusCode),
' CType(WebExceptionStatus.ConnectFailure, HttpStatusCode))
_StatusCode = CType(WebExceptionStatus.ConnectFailure, HttpStatusCode)
Else
_StatusCode = CType(WebExceptionStatus.RequestCanceled, HttpStatusCode)
End If
_Payload = String.Empty
Finally
ServicePointManager.ServerCertificateValidationCallback = Nothing
End Try
HttpSite.Cookies = _Cookiejar
HttpSite.PayLoad = _Payload
HttpSite.StatusCode = _StatusCode
Return HttpSite
End Function
Private Function TlsValidationCallback(sender As Object, CACert As X509Certificate, CAChain As X509Chain, ssl_PolicyErrors As SslPolicyErrors) As Boolean
If ssl_PolicyErrors = SslPolicyErrors.None Then
Return True
End If
Dim _Certificate As New X509Certificate2(CACert)
'Dim _CACert As New X509Certificate2("./ca.cert") 'Add your certificate here
'CAChain.ChainPolicy.ExtraStore.Add(_CACert)
CAChain.Build(_Certificate)
For Each CACStatus As X509ChainStatus In CAChain.ChainStatus
If (CACStatus.Status <> X509ChainStatusFlags.NoError) And
(CACStatus.Status <> X509ChainStatusFlags.UntrustedRoot) Then
Return False
End If
Next
Return True
End Function
Private Function ExtractSslProtocol(stream As Stream) As SslProtocols
Dim bindingFlags__1 As BindingFlags = BindingFlags.Instance Or BindingFlags.Public Or BindingFlags.NonPublic Or BindingFlags.Static
Dim _objConnection = stream.[GetType]().GetField("m_Connection", bindingFlags__1).GetValue(stream)
Dim _objTlsStream = _objConnection.[GetType]().GetProperty("NetworkStream", bindingFlags__1).GetValue(_objConnection)
Dim _objSslState = _objTlsStream.[GetType]().GetField("m_Worker", bindingFlags__1).GetValue(_objTlsStream)
Return CType(_objSslState.[GetType]().GetProperty("SslProtocol", bindingFlags__1).GetValue(_objSslState), SslProtocols)
End Function
Private Sub HTTP_RequestHeadersInit(ByRef HttpReq As HttpWebRequest, CookieJar As CookieContainer, Referer As String)
HttpReq.ServicePoint.MaxIdleTime = 30000
HttpReq.ServicePoint.Expect100Continue = False
HttpReq.Timeout = 30000
HttpReq.CookieContainer = CookieJar
HttpReq.KeepAlive = True
HttpReq.AllowAutoRedirect = False
HttpReq.AutomaticDecompression = DecompressionMethods.GZip Or DecompressionMethods.Deflate
HttpReq.Referer = Referer
HttpReq.UserAgent = "Mozilla/5.0 (Windows NT 10.0; Win64; x64; rv:57.0) Gecko/20100101 Firefox/57.0"
HttpReq.Accept = "ext/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8"
HttpReq.Headers.Add(HttpRequestHeader.AcceptLanguage, "en-US;q=0.8,en;q=0.5")
HttpReq.Headers.Add(HttpRequestHeader.AcceptEncoding, "gzip, deflate;q=0.8")
HttpReq.Headers.Add(HttpRequestHeader.CacheControl, "max-age=0")
End Sub
Private Function ProcessResponse(Response As HttpWebResponse, HttpSite As HttpReqObj) As String
Dim _html As String
Dim _encoding As Encoding
Try
_encoding = If(Response.CharacterSet.Length > 0,
Encoding.GetEncoding(Response.CharacterSet),
Encoding.GetEncoding("utf-8"))
Using _stream As Stream = Response.GetResponseStream()
HttpSite.SslProtocol = ExtractSslProtocol(_stream)
Using _memStream As New MemoryStream()
If Response.ContentEncoding.ToLower().Contains("gzip") Then
Using _gzipStream As New Compression.GZipStream(_stream,
Compression.CompressionMode.Decompress)
_gzipStream.CopyTo(_memStream)
End Using
ElseIf Response.ContentEncoding.ToLower().Contains("deflate") Then
Using _deflStream As New Compression.DeflateStream(_stream,
Compression.CompressionMode.Decompress)
_deflStream.CopyTo(_memStream)
End Using
Else
_stream.CopyTo(_memStream)
End If
_memStream.Position = 0
Using _reader As New StreamReader(_memStream, _encoding)
_html = _reader.ReadToEnd().Trim()
End Using
End Using
End Using
Catch _Ex As Exception
Return String.Empty
End Try
Return _html
End Function
Private Function URIFromResponseLocation(RefResponse As HttpWebResponse) As System.Uri
Dim _uri As System.Uri
Dim _location As String = RefResponse.Headers("Location")
Try
If Uri.IsWellFormedUriString(_location, UriKind.Absolute) Then
_uri = New Uri(_location, UriKind.Absolute)
Else
Dim _host_uri As String = RefResponse.ResponseUri.GetComponents(UriComponents.SchemeAndServer,
UriFormat.Unescaped) + _location
If Uri.IsWellFormedUriString(_host_uri, UriKind.Absolute) Then
_uri = New Uri(_host_uri)
Else
_uri = New Uri(RefResponse.ResponseUri.GetComponents(UriComponents.Scheme,
UriFormat.Unescaped) +
RefResponse.ResponseUri.Host + _location)
End If
End If
Catch _Ex As Exception
_uri = New Uri(_location, UriKind.Relative)
End Try
Return _uri
End Function