aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFinn Behrens <me@kloenk.dev>2021-09-29 10:26:02 +0200
committerFinn Behrens <me@kloenk.dev>2021-09-29 10:26:02 +0200
commitbcef3014398f4a941ec87c15344905a10b9a6130 (patch)
treeb1f8833a55ff4b842747023ac85f42333ab28dc2
parent5ded103c98e35dbfe450099b3be7f53f177e221a (diff)
downloadMatrixCore-bcef3014398f4a941ec87c15344905a10b9a6130.tar.gz
MatrixCore-bcef3014398f4a941ec87c15344905a10b9a6130.tar.xz
MatrixCore-bcef3014398f4a941ec87c15344905a10b9a6130.zip
MatrixRequest and Response protocol
Signed-off-by: Finn Behrens <me@kloenk.dev>
-rw-r--r--Sources/MatrixClient/API/HomeServer.swift (renamed from Sources/MatrixClient/HomeServer.swift)39
-rw-r--r--Sources/MatrixClient/API/Request.swift67
-rw-r--r--Sources/MatrixClient/MatrixClient.swift4
3 files changed, 105 insertions, 5 deletions
diff --git a/Sources/MatrixClient/HomeServer.swift b/Sources/MatrixClient/API/HomeServer.swift
index 64b44b0..db8a853 100644
--- a/Sources/MatrixClient/HomeServer.swift
+++ b/Sources/MatrixClient/API/HomeServer.swift
@@ -21,9 +21,29 @@ public struct MatrixHomeserver: Codable {
self.url = components
}
+
+ public func path(_ path: String) -> URLComponents {
+ var components = url
+ components.path = path
+ return components;
+ }
+}
+
+public struct MatrixServerInfoRequest: MatrixRequest {
+ public typealias Response = MatrixServerInfo
+
+ public typealias URLParameters = ()
+
+ public func path(with parameters: ()) -> String {
+ return "/_matrix/client/versions"
+ }
+
+ public static var httpMethod = "GET"
+
+ public static var requiresAuth = false
}
-public struct MatrixServerInfo: Codable {
+public struct MatrixServerInfo: MatrixResponse {
/// The supported versions.
public var versions: [String]
@@ -37,7 +57,21 @@ public struct MatrixServerInfo: Codable {
}
}
-public struct MatrixWellKnown {
+public struct MatrixWellKnownRequest: MatrixRequest {
+ public typealias Response = MatrixWellKnown
+
+ public typealias URLParameters = ()
+
+ public func path(with parameters: ()) -> String {
+ return "/.well-known/matrix/client"
+ }
+
+ public static var httpMethod = "GET"
+
+ public static var requiresAuth = false
+}
+
+public struct MatrixWellKnown: MatrixResponse {
/// Used by clients to discover homeserver information.
public var homeserver: ServerInformation?
@@ -67,7 +101,6 @@ public struct MatrixWellKnown {
}
}
-// TODO: encode for extraInfos
extension MatrixWellKnown: Codable {
private enum KnownCodingKeys: String, CodingKey, CaseIterable {
case homeserver = "m.homeserver"
diff --git a/Sources/MatrixClient/API/Request.swift b/Sources/MatrixClient/API/Request.swift
new file mode 100644
index 0000000..1f2cc0d
--- /dev/null
+++ b/Sources/MatrixClient/API/Request.swift
@@ -0,0 +1,67 @@
+//
+// File.swift
+// File
+//
+// Created by Finn Behrens on 29.09.21.
+//
+
+import Foundation
+
+public protocol MatrixRequest: Codable {
+ associatedtype Response: MatrixResponse
+
+ associatedtype URLParameters
+ func path(with parameters: URLParameters) -> String
+
+ static var httpMethod: String { get }
+ static var requiresAuth: Bool { get }
+ // TODO: rate limited property?
+}
+
+public extension MatrixRequest {
+ func request(on homeserver: MatrixHomeserver, withToken token: String? = nil, with parameters: URLParameters) throws -> URLRequest {
+ let components = homeserver.path(self.path(with: parameters))
+ // components.queryItems = self.queryParameters
+
+ var urlRequest = URLRequest(url: components.url!)
+
+ if Self.requiresAuth {
+ guard let token = token else {
+ throw MatrixError.Forbidden
+ }
+ urlRequest.addValue("Bearer \(token)", forHTTPHeaderField: "Authorization")
+ }
+
+ urlRequest.httpMethod = Self.httpMethod
+ if ["POST", "PUT", "PATCH"].contains(Self.httpMethod) {
+ urlRequest.httpBody = try? JSONEncoder().encode(self)
+ }
+
+ return urlRequest
+ }
+
+ func repsonse(on homeserver: MatrixHomeserver, withToken token: String? = nil, with parameters: URLParameters, withUrlSession urlSession: URLSession = URLSession.shared) async throws -> Response {
+ let request = try request(on: homeserver, withToken: token, with: parameters)
+
+ let (data, urlResponse) = try await urlSession.data(for: request)
+
+ guard let response = urlResponse as? HTTPURLResponse else {
+ throw MatrixError.Unknown
+ }
+ guard response.statusCode == 200 else {
+ throw try MatrixServerError(json: data, code: response.statusCode)
+ }
+
+ return try Response(fromMatrixRequestData: data)
+ }
+}
+
+public protocol MatrixResponse: Codable {
+}
+
+public extension MatrixResponse {
+ init(fromMatrixRequestData data: Data) throws {
+ let decoder = JSONDecoder()
+ self = try decoder.decode(Self.self, from: data)
+ }
+}
diff --git a/Sources/MatrixClient/MatrixClient.swift b/Sources/MatrixClient/MatrixClient.swift
index 9e0a493..32bcd8b 100644
--- a/Sources/MatrixClient/MatrixClient.swift
+++ b/Sources/MatrixClient/MatrixClient.swift
@@ -33,7 +33,7 @@ public struct MatrixClient {
/// Requires auth: No.
/// ```
public func getVersions() async throws -> MatrixServerInfo {
- return try await request("/_matrix/client/versions", withAuthorization: false, forType: MatrixServerInfo.self)
+ return try await MatrixServerInfoRequest().repsonse(on: homeserver, with: (), withUrlSession: urlSession)
}
/// Gets discovery information about the domain. The file may include additional keys, which MUST follow the Java package naming convention,
@@ -46,7 +46,7 @@ public struct MatrixClient {
/// Requires auth: No.
///```
public func getWellKnown() async throws -> MatrixWellKnown {
- return try await request("/.well-known/matrix/client", withAuthorization: false, forType: MatrixWellKnown.self)
+ return try await MatrixWellKnownRequest().repsonse(on: homeserver, with: (), withUrlSession: urlSession)
}
/// Gets the homeserver's supported login types to authenticate users. Clients should pick one of these and supply it as the type when logging in.