Files
GLEGram-iOS/Swiftgram/SGRequests/Sources/File.swift
T
Leeksov 4647310322 GLEGram 12.5 — Initial public release
Based on Swiftgram 12.5 (Telegram iOS 12.5).
All GLEGram features ported and organized in GLEGram/ folder.

Features: Ghost Mode, Saved Deleted Messages, Content Protection Bypass,
Font Replacement, Fake Profile, Chat Export, Plugin System, and more.

See CHANGELOG_12.5.md for full details.
2026-04-06 09:48:12 +03:00

111 lines
3.6 KiB
Swift

import Foundation
import SwiftSignalKit
public func requestsDownload(url: URL) -> Signal<(Data, URLResponse?), Error?> {
return Signal { subscriber in
let completed = Atomic<Bool>(value: false)
let downloadTask = URLSession.shared.downloadTask(with: url, completionHandler: { location, response, error in
let _ = completed.swap(true)
if let location = location, let data = try? Data(contentsOf: location) {
subscriber.putNext((data, response))
subscriber.putCompletion()
} else {
subscriber.putError(error)
}
})
downloadTask.resume()
return ActionDisposable {
if !completed.with({ $0 }) {
downloadTask.cancel()
}
}
}
}
public func requestsGet(url: URL) -> Signal<(Data, URLResponse?), Error?> {
return Signal { subscriber in
let completed = Atomic<Bool>(value: false)
let urlTask = URLSession.shared.dataTask(with: url, completionHandler: { data, response, error in
let _ = completed.swap(true)
if let strongData = data {
subscriber.putNext((strongData, response))
subscriber.putCompletion()
} else {
subscriber.putError(error)
}
})
urlTask.resume()
return ActionDisposable {
if !completed.with({ $0 }) {
urlTask.cancel()
}
}
}
}
public func requestsCustom(request: URLRequest) -> Signal<(Data, URLResponse?), Error?> {
return Signal { subscriber in
let completed = Atomic<Bool>(value: false)
let urlTask = URLSession.shared.dataTask(with: request, completionHandler: { data, response, error in
_ = completed.swap(true)
if let strongData = data {
subscriber.putNext((strongData, response))
subscriber.putCompletion()
} else {
subscriber.putError(error)
}
})
urlTask.resume()
return ActionDisposable {
if !completed.with({ $0 }) {
urlTask.cancel()
}
}
}
}
/// Same as requestsCustom but with SSL certificate pinning. Use for supporters API.
/// - Parameters:
/// - request: The URL request
/// - host: Expected host (e.g. "glegram.site")
/// - pinnedHashes: Base64 SHA256 hashes of server cert(s). Empty = no pinning (fallback to default).
public func requestsCustomWithPinning(
request: URLRequest,
host: String,
pinnedHashes: [String]
) -> Signal<(Data, URLResponse?), Error?> {
guard !pinnedHashes.isEmpty else {
return requestsCustom(request: request)
}
return Signal { subscriber in
let completed = Atomic<Bool>(value: false)
let delegate = SSLPinningDelegate(host: host, pinnedHashes: pinnedHashes)
let config = URLSessionConfiguration.default
let session = URLSession(configuration: config, delegate: delegate, delegateQueue: nil)
let urlTask = session.dataTask(with: request, completionHandler: { data, response, error in
_ = completed.swap(true)
session.finishTasksAndInvalidate()
if let strongData = data {
subscriber.putNext((strongData, response))
subscriber.putCompletion()
} else {
subscriber.putError(error)
}
})
urlTask.resume()
return ActionDisposable {
if !completed.with({ $0 }) {
urlTask.cancel()
}
}
}
}