mirror of
https://github.com/immich-app/immich.git
synced 2026-02-12 20:08:25 +03:00
* handle mtls on ios * update android impl * ui improvements * dead code * no need to store data separately * improve concurrency * dead code * add migration * remove unused dependency * trust user-installed certs * removed print statement * fix ios * improve android styling * outdated comments * update lock file * handle translation * fix prompt cancellation * fix video playback * Apply suggestion from @shenlong-tanwen Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> * Apply suggestion from @shenlong-tanwen Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com> * formatting --------- Co-authored-by: shenlong <139912620+shenlong-tanwen@users.noreply.github.com>
88 lines
3.0 KiB
Swift
88 lines
3.0 KiB
Swift
import Foundation
|
|
|
|
let CLIENT_CERT_LABEL = "app.alextran.immich.client_identity"
|
|
|
|
/// Manages a shared URLSession with SSL configuration support.
|
|
class URLSessionManager: NSObject {
|
|
static let shared = URLSessionManager()
|
|
|
|
let session: URLSession
|
|
private let configuration = {
|
|
let config = URLSessionConfiguration.default
|
|
|
|
let cacheDir = FileManager.default.urls(for: .cachesDirectory, in: .userDomainMask)
|
|
.first!
|
|
.appendingPathComponent("api", isDirectory: true)
|
|
try! FileManager.default.createDirectory(at: cacheDir, withIntermediateDirectories: true)
|
|
|
|
config.urlCache = URLCache(
|
|
memoryCapacity: 0,
|
|
diskCapacity: 1024 * 1024 * 1024,
|
|
directory: cacheDir
|
|
)
|
|
|
|
config.httpMaximumConnectionsPerHost = 64
|
|
config.timeoutIntervalForRequest = 60
|
|
config.timeoutIntervalForResource = 300
|
|
|
|
let version = Bundle.main.object(forInfoDictionaryKey: "CFBundleShortVersionString") as? String ?? "unknown"
|
|
config.httpAdditionalHeaders = ["User-Agent": "Immich_iOS_\(version)"]
|
|
|
|
return config
|
|
}()
|
|
|
|
private override init() {
|
|
session = URLSession(configuration: configuration, delegate: URLSessionManagerDelegate(), delegateQueue: nil)
|
|
super.init()
|
|
}
|
|
}
|
|
|
|
class URLSessionManagerDelegate: NSObject, URLSessionTaskDelegate {
|
|
func urlSession(
|
|
_ session: URLSession,
|
|
didReceive challenge: URLAuthenticationChallenge,
|
|
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
|
|
) {
|
|
handleChallenge(challenge, completionHandler: completionHandler)
|
|
}
|
|
|
|
func urlSession(
|
|
_ session: URLSession,
|
|
task: URLSessionTask,
|
|
didReceive challenge: URLAuthenticationChallenge,
|
|
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
|
|
) {
|
|
handleChallenge(challenge, completionHandler: completionHandler)
|
|
}
|
|
|
|
func handleChallenge(
|
|
_ challenge: URLAuthenticationChallenge,
|
|
completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
|
|
) {
|
|
switch challenge.protectionSpace.authenticationMethod {
|
|
case NSURLAuthenticationMethodClientCertificate: handleClientCertificate(completion: completionHandler)
|
|
default: completionHandler(.performDefaultHandling, nil)
|
|
}
|
|
}
|
|
|
|
private func handleClientCertificate(
|
|
completion: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void
|
|
) {
|
|
let query: [String: Any] = [
|
|
kSecClass as String: kSecClassIdentity,
|
|
kSecAttrLabel as String: CLIENT_CERT_LABEL,
|
|
kSecReturnRef as String: true,
|
|
]
|
|
|
|
var item: CFTypeRef?
|
|
let status = SecItemCopyMatching(query as CFDictionary, &item)
|
|
if status == errSecSuccess, let identity = item {
|
|
let credential = URLCredential(identity: identity as! SecIdentity,
|
|
certificates: nil,
|
|
persistence: .forSession)
|
|
return completion(.useCredential, credential)
|
|
}
|
|
completion(.performDefaultHandling, nil)
|
|
}
|
|
}
|