2020-01-08 12:41:02 -08:00
|
|
|
//
|
|
|
|
|
// ServerConnection.swift
|
|
|
|
|
// AltStore
|
|
|
|
|
//
|
|
|
|
|
// Created by Riley Testut on 1/7/20.
|
|
|
|
|
// Copyright © 2020 Riley Testut. All rights reserved.
|
|
|
|
|
//
|
|
|
|
|
|
|
|
|
|
import Foundation
|
|
|
|
|
import Network
|
|
|
|
|
|
2020-09-03 16:39:08 -07:00
|
|
|
import AltStoreCore
|
|
|
|
|
|
2020-01-08 12:41:02 -08:00
|
|
|
class ServerConnection
|
|
|
|
|
{
|
|
|
|
|
var server: Server
|
2020-09-22 15:11:42 -07:00
|
|
|
var connection: Connection
|
2020-01-08 12:41:02 -08:00
|
|
|
|
2020-09-22 15:11:42 -07:00
|
|
|
init(server: Server, connection: Connection)
|
2020-01-08 12:41:02 -08:00
|
|
|
{
|
|
|
|
|
self.server = server
|
|
|
|
|
self.connection = connection
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func send<T: Encodable>(_ payload: T, prependSize: Bool = true, completionHandler: @escaping (Result<Void, Error>) -> Void)
|
|
|
|
|
{
|
|
|
|
|
do
|
|
|
|
|
{
|
|
|
|
|
let data: Data
|
|
|
|
|
|
|
|
|
|
if let payload = payload as? Data
|
|
|
|
|
{
|
|
|
|
|
data = payload
|
|
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
|
|
|
|
data = try JSONEncoder().encode(payload)
|
|
|
|
|
}
|
|
|
|
|
|
2020-09-22 15:11:42 -07:00
|
|
|
func process<T>(_ result: Result<T, ALTServerError>) -> Bool
|
2020-01-08 12:41:02 -08:00
|
|
|
{
|
2020-09-22 15:11:42 -07:00
|
|
|
switch result
|
2020-01-08 12:41:02 -08:00
|
|
|
{
|
2020-09-22 15:11:42 -07:00
|
|
|
case .success: return true
|
|
|
|
|
case .failure(let error):
|
|
|
|
|
completionHandler(.failure(error))
|
2020-01-08 12:41:02 -08:00
|
|
|
return false
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
if prependSize
|
|
|
|
|
{
|
|
|
|
|
let requestSize = Int32(data.count)
|
|
|
|
|
let requestSizeData = withUnsafeBytes(of: requestSize) { Data($0) }
|
|
|
|
|
|
2020-09-22 15:11:42 -07:00
|
|
|
self.connection.send(requestSizeData) { (result) in
|
|
|
|
|
guard process(result) else { return }
|
2020-01-08 12:41:02 -08:00
|
|
|
|
2020-09-22 15:11:42 -07:00
|
|
|
self.connection.send(data) { (result) in
|
|
|
|
|
guard process(result) else { return }
|
2020-01-08 12:41:02 -08:00
|
|
|
completionHandler(.success(()))
|
2020-09-22 15:11:42 -07:00
|
|
|
}
|
|
|
|
|
}
|
2020-01-08 12:41:02 -08:00
|
|
|
}
|
|
|
|
|
else
|
|
|
|
|
{
|
2020-09-22 15:11:42 -07:00
|
|
|
self.connection.send(data) { (result) in
|
|
|
|
|
guard process(result) else { return }
|
2020-01-08 12:41:02 -08:00
|
|
|
completionHandler(.success(()))
|
2020-09-22 15:11:42 -07:00
|
|
|
}
|
2020-01-08 12:41:02 -08:00
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
print("Invalid request.", error)
|
|
|
|
|
completionHandler(.failure(ALTServerError(.invalidRequest)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
func receiveResponse(completionHandler: @escaping (Result<ServerResponse, Error>) -> Void)
|
|
|
|
|
{
|
|
|
|
|
let size = MemoryLayout<Int32>.size
|
|
|
|
|
|
2020-09-22 15:11:42 -07:00
|
|
|
self.connection.receiveData(expectedSize: size) { (result) in
|
2020-01-08 12:41:02 -08:00
|
|
|
do
|
|
|
|
|
{
|
2020-09-22 15:11:42 -07:00
|
|
|
let data = try result.get()
|
2020-01-08 12:41:02 -08:00
|
|
|
|
|
|
|
|
let expectedBytes = Int(data.withUnsafeBytes { $0.load(as: Int32.self) })
|
2020-09-22 15:11:42 -07:00
|
|
|
self.connection.receiveData(expectedSize: expectedBytes) { (result) in
|
2020-01-08 12:41:02 -08:00
|
|
|
do
|
|
|
|
|
{
|
2020-09-22 15:11:42 -07:00
|
|
|
let data = try result.get()
|
2020-01-08 12:41:02 -08:00
|
|
|
|
2020-09-03 16:39:08 -07:00
|
|
|
let response = try AltStoreCore.JSONDecoder().decode(ServerResponse.self, from: data)
|
2020-01-08 12:41:02 -08:00
|
|
|
completionHandler(.success(response))
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
completionHandler(.failure(ALTServerError(error)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
catch
|
|
|
|
|
{
|
|
|
|
|
completionHandler(.failure(ALTServerError(error)))
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
}
|