Dylan Beattie
Dylan Beattie

Reputation: 54160

Why does settings ServicePointManager.ServerCertificateValidationCallback = null not work?

I have the following snippet, that I'm calling from a set of integration tests:

private void Url_Contains_String_With_Certificate_Warning(string url, string expected) {
  // This line should restore default cert validation behaviour
  ServicePointManager.ServerCertificateValidationCallback = null;
  var wc = new WebClient();
  try {
    wc.DownloadString(url);
    Assert.Fail("Should have thrown a WebException by now");
  } catch (WebException x) {
    Assert.That(x.InnerException is AuthenticationException, "Expected an AuthenticationException inside a WebException due to invalid certificate");
    Assert.AreEqual("The remote certificate is invalid according to the validation procedure.", x.InnerException.Message);
  }
  // This line overrides cert validation behaviour to accept invalid certs
  ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); };
  var result = wc.DownloadString(url);
  Assert.That(result.Contains(expected), String.Format("Didn't find expected text '{0}' in HTML response", expected));
}

However, only the first test in any given test run will pass... once I've run this line:

ServicePointManager.ServerCertificateValidationCallback = delegate { return(true); };

I cannot get WebClient to throw a certificate error again in the same test run, even if I explicity assign this delegate to null. I've also tried explicitly returning false; I've tried adding a named delegate reference and then removing it instead of just assigning/reassigning, and even checking the SslPolicyErrors in the callback and returning policyErrors == SslPolicyErrors.None - nothing works.

(I'm explicitly verifying that certain URLs in our test environment return a certificate warning, and I also need to verify that if the user ignores the certificate warning they'll see a particular page, hence the slightly odd certificate handling)

Any ideas?

Upvotes: 1

Views: 3956

Answers (2)

dmihailescu
dmihailescu

Reputation: 1643

You should call -

ServicePointManager.ServerCertificateValidationCallback == delegate { return(true); };

before creating the request, in your case before calling

var wc = new WebClient();

Upvotes: 0

Joe
Joe

Reputation: 1669

set System.Net.ServicePointManager.MaxServicePointIdleTime to 0

without this the connection channel is staying open, hence no delegate call

http://blogs.msdn.com/b/jpsanders/archive/2009/05/20/understanding-maxservicepointidletime-and-defaultconnectionlimit.aspx

Upvotes: 2

Related Questions