First the server side: There is an internal reachable apache server with several virtual hosts. For http (sans 's'!) requests, I use the IP for the URL and add the hostname in the Host-Headerfield.
That works quite good.
But when I make an SSL connection I run into problems which seems to be releated by SNI.
I found this Overriding TLS Chain Validation Correctly and implemented it in my code.
So I updated the trust in
func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void)
but I still get a 400 from the server.
UPDATE:
URLSession
does support SNI but my problem is that I need to add an additional or change the hostname
in the SSLHandshake
.
So first a short description of the server:
The Server is an Apache-server that is only reachable via IP but it has multiple vhosts which are locally available via the hostname but when I connect to them from an external device like an iPhone I have to add the hostname of the vhost in the Host-Headerfield
.
So what I do is: I create an URLRequest with an IP-base URL and then add the HOST
Headerfield with hostname
if let url = URL("https://192.168.178.54:8890") {
var request = URLRequest(url: url)
request.addValue("foobar:8890", forHTTPHeaderField: "Host")
…
}
This works perfekt for non-secure http-Requests but as soon as https is used the server returns the "400 Bad request" and the http-ssl-error.log contains the following error:
[Tue Jul 11 09:35:51 2017] [error] Hostname 192.168.178.54 provided via SNI and hostname foobar provided via HTTP are different
This is because by default the SSLHandshake uses value provided in the URL and in my case this is the IP.
What I now try to figure out is how to provide a different hostname in the SSLHandshake or, alternatively, provide something like an own DNS resolver where I can still use a hostname-base URL, but iOS gets the routing straight.