mono https WebRequest System.Net.WebException(已禁用证书检查)

时间:2016-07-04 11:18:01

标签: linux f# mono

我正在尝试使用Linux下的mono和F#对https网页执行简单的Web请求。

我昨天设法通过禁用ServerCertificateValidationCallback完成的证书验证来获得解决方案,但现在它突然停止工作了。

我的脚本的相关部分看起来像这样

#r "../../packages/FSharp.Data/lib/net40/FSharp.Data.dll"
#r "System.Xml.Linq.dll"
open FSharp.Data
open System
open System.IO
open System.Net
open System.Net.Security
open System.Threading
open System.Security.Cryptography.X509Certificates

// disabling certificate validation
ServicePointManager.ServerCertificateValidationCallback <-
    new RemoteCertificateValidationCallback(fun _ _ _ _ -> true)

type Either<'a,'b> = Left of 'a
                   | Right of 'b

let web_reader (url: string) =
    try
        Thread.Sleep 500
        let wr = WebRequest.CreateHttp url
        wr.UserAgent <- "test.bot" //I've also tried "safari" without luck
        let stream = wr.GetResponse().GetResponseStream()
        Right( (new StreamReader(stream)).ReadToEnd() )
    with exp -> Left (sprintf "ERROR IN 'web_reader' FOR URL %s\n\n%A" url exp)

web_reader "https://www.jobfinder.dk/"

并调用应用于https网址的web_reader函数会导致以下异常

System.Net.WebException: Error: SendFailure (Error writing headers) ---> System.Net.WebException: Error writing headers ---> System.IO.IOException: The authentication or decryption has failed. ---> Mono.Security.Protocol.Tls.TlsException: The authentication or decryption has failed.
  at Mono.Security.Protocol.Tls.RecordProtocol.EndReceiveRecord (IAsyncResult asyncResult) <0x41d866e0 + 0x0010b> in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.SafeEndReceiveRecord (IAsyncResult ar, Boolean ignoreEmpty) <0x41d86620 + 0x0002b> in <filename unknown>:0 
  at Mono.Security.Protocol.Tls.SslClientStream.NegotiateAsyncWorker (IAsyncResult result) <0x41d838e0 + 0x00227> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  at System.Net.WebConnection.EndWrite (System.Net.HttpWebRequest request, Boolean throwOnError, IAsyncResult result) <0x41d87f00 + 0x00207> in <filename unknown>:0 
  at System.Net.WebConnectionStream+<SetHeadersAsync>c__AnonStorey1.<>m__0 (IAsyncResult r) <0x41d87800 + 0x0013b> in <filename unknown>:0 
  --- End of inner exception stack trace ---
  --- End of inner exception stack trace ---
  at System.Net.HttpWebRequest.EndGetResponse (IAsyncResult asyncResult) <0x41d74070 + 0x0019f> in <filename unknown>:0 
  at System.Net.HttpWebRequest.GetResponse () <0x41d6ee90 + 0x00053> in <filename unknown>:0 
  at FSI_0001.web_reader (System.String url) <0x41d8a4a0 + 0x00073> in <filename unknown>:0

我真的没有弄错。我错过了什么?

我正在使用:

  • F#4.0
  • mono 4.4.1
  • Debian Jessie

我一直非常小心,不要对该网址执行太多请求,我甚至在Thread.Sleep添加了一些延迟。我仍然可以ping服务器并访问给定的网站,所以我怀疑他们阻止了我的IP或类似的东西。第一次尝试时会抛出异常。

修改

我刚用.Net测试了Visual Studio中的代码,似乎请求永远停滞不前。所以我进行了调试和调查,最终找到了解决方案The request was aborted: Could not create SSL/TLS secure channel

在我的脚本中添加以下内容:

ServicePointManager.Expect100Continue <- true;
ServicePointManager.SecurityProtocol <- SecurityProtocolType.Tls12

然后它适用于.Net。

我还将我的单声道版本从4.2.1更新到4.4.1,它似乎也支持Tls12,但是我仍然无法使用单声道。

0 个答案:

没有答案