I want to use Alamofire to communicate with my server over a https connection with a self signed certificate. My environment runs on localhost. I've tried to connect, but the response all the time looks like this:
Success: false Response String: nil
I've done it with the following code:
import Foundation import UIKit import Alamofire class MessageView: UITableViewController { let defaultManager: Alamofire.Manager = { let serverTrustPolicies: [String: ServerTrustPolicy] = [ "localhost": .DisableEvaluation ] let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders return Alamofire.Manager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) }() override func viewDidLoad() { super.viewDidLoad() defaultManager .request(.GET, "https://localhost:3443/message") .responseJSON { _, _, result in print("Success: \(result.isSuccess)") print("Response String: \(result.value)") } } }
I've created the server side certificates with this line of bash:
openssl req -x509 -nodes -days 999 -newkey rsa:2048 -keyout server.key -out server.crt
I don't know what am I doing wrong. Help would be great.
### Update ###
Here is the cURL request. In my opinion, there is no problem, or am I wrong?
curl -X GET https://localhost:3443/message -k -v * Trying ::1... * Connected to localhost (::1) port 3443 (#0) * TLS 1.2 connection using TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA384 * Server certificate: teawithfruit > GET /message HTTP/1.1 > Host: localhost:3443 > User-Agent: curl/7.43.0 > Accept: */* > < HTTP/1.1 200 OK < Content-Type: application/json; charset=utf-8 < Content-Length: 1073 < Date: Tue, 15 Sep 2015 06:20:45 GMT < Connection: keep-alive < * Connection #0 to host localhost left intact [{"_id":"55f3ed2d81a334558241e2f4","email":"[email protected]","password":"abc","name":"teawithfruit","language":"en","__v":0,"timestamp":1442049325159,"messages":[{"_id":"55f40553e568236589772c61","user":"55f3ed2d81a334558241e2f4","language":"en","message":"hello world","__v":0,"timestamp":1442055507301,"id":"55f40553e568236589772c61"},{"_id":"55f48b2b02e7b059b54e99f6","user":"55f3ed2d81a334558241e2f4","language":"en","message":"hello world","__v":0,"timestamp":1442089771312,"id":"55f48b2b02e7b059b54e99f6"}],"id":"55f3ed2d81a334558241e2f4"}]
### Update 2 ###
Sorry for the late answer. Here are the two debugPrints:
Request debugPrint:
$ curl -i \ -H "Accept-Language: en-US;q=1.0" \ -H "Accept-Encoding: gzip;q=1.0,compress;q=0.5" \ -H "User-Agent: Message/com.teawithfruit.Message (1; OS Version 9.0 (Build 13A340))" \ "https://localhost:3443/message"
Result debugPrint:
FAILURE: Error Domain=NSURLErrorDomain Code=-999 "cancelled" UserInfo={NSErrorFailingURLKey=https://localhost:3443/message, NSLocalizedDescription=cancelled, NSErrorFailingURLStringKey=https://localhost:3443/message}
### Update 3 ###
Here is the complete error with maybe an ATS problem?
nil $ curl -i \ -H "Accept-Language: en-US;q=1.0" \ -H "Accept-Encoding: gzip;q=1.0,compress;q=0.5" \ -H "User-Agent: Message/com.teawithfruit.Message (1; OS Version 9.0 (Build 13A340))" \ "https://localhost:3443/message" 2015-10-17 15:10:48.346 Message[25531:1001269] NSURLSession/NSURLConnection HTTP load failed (kCFStreamErrorDomainSSL, -9802) FAILURE: Error Domain=NSURLErrorDomain Code=-1200 "An SSL error has occurred and a secure connection to the server cannot be made." UserInfo={NSURLErrorFailingURLPeerTrustErrorKey=<SecTrustRef: 0x7fdc3044b740>, NSLocalizedRecoverySuggestion=Would you like to connect to the server anyway?, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, NSErrorPeerCertificateChainKey=<CFArray 0x7fdc2a7ca300 [0x10f7037b0]>{type = immutable, count = 1, values = ( 0 : <cert(0x7fdc31d31670) s: teawithfruit i: teawithfruit> )}, NSUnderlyingError=0x7fdc30064bd0 {Error Domain=kCFErrorDomainCFNetwork Code=-1200 "(null)" UserInfo={_kCFStreamPropertySSLClientCertificateState=0, kCFStreamPropertySSLPeerTrust=<SecTrustRef: 0x7fdc3044b740>, _kCFNetworkCFStreamSSLErrorOriginalValue=-9802, _kCFStreamErrorDomainKey=3, _kCFStreamErrorCodeKey=-9802, kCFStreamPropertySSLPeerCertificates=<CFArray 0x7fdc2a7ca300 [0x10f7037b0]>{type = immutable, count = 1, values = ( 0 : <cert(0x7fdc31d31670) s: teawithfruit i: teawithfruit> )}}}, NSLocalizedDescription=An SSL error has occurred and a secure connection to the server cannot be made., NSErrorFailingURLKey=https://localhost:3443/message, NSErrorFailingURLStringKey=https://localhost:3443/message, NSErrorClientCertificateStateKey=0} Success: false Response String: nil
You need to add the port
domain when you create your ServerTrustPolicy
dictionary.
let defaultManager: Alamofire.Manager = { let serverTrustPolicies: [String: ServerTrustPolicy] = [ "localhost:3443": .DisableEvaluation ] let configuration = NSURLSessionConfiguration.defaultSessionConfiguration() configuration.HTTPAdditionalHeaders = Alamofire.Manager.defaultHTTPHeaders return Alamofire.Manager( configuration: configuration, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) }()
For swift 4:
private static var Manager : Alamofire.SessionManager = { // Create the server trust policies let serverTrustPolicies: [String: ServerTrustPolicy] = [ "your domain goes here": .disableEvaluation ] // Create custom manager let configuration = URLSessionConfiguration.default configuration.httpAdditionalHeaders = Alamofire.SessionManager.defaultHTTPHeaders let man = Alamofire.SessionManager( configuration: URLSessionConfiguration.default, serverTrustPolicyManager: ServerTrustPolicyManager(policies: serverTrustPolicies) ) return man }()
Then you call it like this:
Manager.upload(body.data(using: .utf8)!, to: url, method: .post, headers: headers)
Credits to Cnoon
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With