4

What I want:

Specify server IP for NSMutableURLRequest to avoid localDNS query.

Common method:

Replace host field in URL and specify the HOST Header field for the HTTP request.

request = [[NSMutableURLRequest alloc] initWithURL:[NSURL URLWithString:@"https://1.1.1.1/path"]];
[request setValue:@"www.a.com" forHTTPHeaderField:@"host"];

Problem:

If my server serves several domains, then the server will return a default certificate for my request. SNI only works when it finds host in url.

So any suggestion if I wanna achieve What I want in Problem scene.

Ryan
  • 235
  • 3
  • 11
  • if you want to serve a page at HTTPS://12.34.56.78 then you need a certificate for 12.34.56.78 the host header simply needs to match what is in on the certificate – Michael B Apr 24 '16 at 04:47
  • @MichaelB-AzureMVP I wanna serve a page at https://www.a.com/path but I has to specify the IP (Assume I know it in advance) for www.a.com at the client side instead of DNS. How can I deal with this situation. – Ryan Apr 24 '16 at 06:23
  • Did you solved the problem? I have the same question, but i do not find a solution yet. Can you give me a favor? – zylenv Sep 19 '16 at 09:30

1 Answers1

0

Actually the Host header is used for determining the certificate. The server never sees the complete URL. IIRC, NSURLSession and friends don't normally override a user-specified Host header if the URL contains an IP address. However, it should be a capital "H" in "Host". Because that header is in the list of headers that you aren't supposed to touch, the capitalization may matter.

If fixing the capitalization doesn't work, there are a couple of other approaches you could consider:

  • Add the hostname in a different header field, then use a custom authentication handling delegate method to explicitly validate the cert against that cert's domain yourself, and if it validates and it is one of your certs and it is for one of your domains, allow the request to continue even if the cert's domain doesn't match the request's domain.
  • Include a rudimentary proxy in your app, and configure the session to always use it when connecting to that host by name. In the proxy, open up a normal TCP/IP NSStream to the correct IP address and pass data back and forth.
  • Write a custom HTTPS client that supports just enough functionality to handle whatever you're doing.
dgatwood
  • 10,129
  • 1
  • 28
  • 49