Integrate RSS feed proxy

pull/81/head
Niels Andriesse 5 years ago
parent c1c04b7ef2
commit e95f91558b

@ -28,8 +28,10 @@ public final class LokiRSSFeedPoller : NSObject {
private func poll() { private func poll() {
let feed = self.feed let feed = self.feed
let url = URL(string: feed.server)! let url = feed.server
FeedParser(URL: url).parseAsync { wrapper in let _ = LokiRSSFeedProxy.fetchContent(for: url).done { xml in
guard let data = xml.data(using: String.Encoding.utf8) else { return print("[Loki] Failed to parse RSS feed for: \(feed.server).") }
FeedParser(data: data).parseAsync { wrapper in
guard case .rss(let x) = wrapper, let items = x.items else { return print("[Loki] Failed to parse RSS feed for: \(feed.server).") } guard case .rss(let x) = wrapper, let items = x.items else { return print("[Loki] Failed to parse RSS feed for: \(feed.server).") }
items.reversed().forEach { item in items.reversed().forEach { item in
guard let title = item.title, let description = item.description, let date = item.pubDate else { return } guard let title = item.title, let description = item.description, let date = item.pubDate else { return }
@ -67,4 +69,5 @@ public final class LokiRSSFeedPoller : NSObject {
} }
} }
} }
}
} }

@ -87,23 +87,42 @@ internal class LokiFileServerProxy : LokiHTTPClient {
task.resume() task.resume()
return promise return promise
}.map { rawResponse in }.map { rawResponse in
guard let data = rawResponse as? Data, !data.isEmpty, let cipherText = Data(base64Encoded: data) else { guard let data = rawResponse as? Data, !data.isEmpty else {
print("[Loki] Received a non-string encoded response.") print("[Loki] Received an empty response.")
return rawResponse return rawResponse
} }
var uncheckedStatusCode: Int? = nil
let uncheckedCipherText: Data?
if let json = try? JSONSerialization.jsonObject(with: data, options: []) as? JSON, let base64EncodedData = json["data"] as? String {
if let meta = json["meta"] as? JSON { uncheckedStatusCode = meta["code"] as? Int }
uncheckedCipherText = Data(base64Encoded: base64EncodedData)
} else {
uncheckedCipherText = data
}
guard let cipherText = uncheckedCipherText else {
print("[Loki] Received an invalid response.")
throw Error.proxyResponseParsingFailed
}
let response = try DiffieHellman.decrypt(cipherText, using: symmetricKey) let response = try DiffieHellman.decrypt(cipherText, using: symmetricKey)
let uncheckedJSON = try? JSONSerialization.jsonObject(with: response, options: .allowFragments) as? JSON let uncheckedJSON = try? JSONSerialization.jsonObject(with: response, options: .allowFragments) as? JSON
guard let json = uncheckedJSON, let httpStatusCode = json["status"] as? Int else { throw HTTPError.networkError(code: -1, response: nil, underlyingError: Error.proxyResponseParsingFailed) } guard let json = uncheckedJSON else { throw HTTPError.networkError(code: -1, response: nil, underlyingError: Error.proxyResponseParsingFailed) }
let isSuccess = (200..<300).contains(httpStatusCode) if uncheckedStatusCode == nil {
uncheckedStatusCode = json["status"] as? Int
}
guard let statusCode = uncheckedStatusCode else {
print("[Loki] Received an invalid response.")
throw Error.proxyResponseParsingFailed
}
let isSuccess = (200..<300).contains(statusCode)
var body: Any? = nil var body: Any? = nil
if let bodyAsString = json["body"] as? String { if let bodyAsString = json["body"] as? String {
body = bodyAsString body = bodyAsString
if let bodyAsJSON = try? JSONSerialization.jsonObject(with: bodyAsString.data(using: .utf8)!, options: .allowFragments) as? [String: Any] { if let bodyAsJSON = try? JSONSerialization.jsonObject(with: bodyAsString.data(using: .utf8)!, options: .allowFragments) as? JSON {
body = bodyAsJSON body = bodyAsJSON
} }
} }
guard isSuccess else { throw HTTPError.networkError(code: httpStatusCode, response: body, underlyingError: Error.fileServerHTTPError(code: httpStatusCode, message: body)) } guard isSuccess else { throw HTTPError.networkError(code: statusCode, response: body, underlyingError: Error.fileServerHTTPError(code: statusCode, message: body)) }
return body return body ?? response
}.recover { error -> Promise<Any> in }.recover { error -> Promise<Any> in
print("[Loki] File server proxy request failed with error: \(error.localizedDescription).") print("[Loki] File server proxy request failed with error: \(error.localizedDescription).")
throw HTTPError.from(error: error) ?? error throw HTTPError.from(error: error) ?? error

@ -1,26 +1,26 @@
import PromiseKit import PromiseKit
internal enum LokiRSSFeedProxy { public enum LokiRSSFeedProxy {
internal enum Error : LocalizedError { public enum Error : LocalizedError {
case proxyResponseParsingFailed case proxyResponseParsingFailed
internal var errorDescription: String? { public var errorDescription: String? {
switch self { switch self {
case .proxyResponseParsingFailed: return "Couldn't parse proxy response." case .proxyResponseParsingFailed: return "Couldn't parse proxy response."
} }
} }
} }
internal static func fetchContent(for url: String) -> Promise<String> { public static func fetchContent(for url: String) -> Promise<String> {
let server = LokiStorageAPI.server let server = LokiStorageAPI.server
let endpoints = [ "messenger-updates/feed" : "loki/v1/rss/messenger", "loki.network/feed" : "loki/v1/rss/loki" ] let endpoints = [ "messenger-updates/feed" : "loki/v1/rss/messenger", "loki.network/feed" : "loki/v1/rss/loki" ]
let endpoint = endpoints.first { url.lowercased().contains($0.key) }!.value let endpoint = endpoints.first { url.lowercased().contains($0.key) }!.value
let url = URL(string: server + "/" + endpoint)! let url = URL(string: server + "/" + endpoint)!
let request = TSRequest(url: url) let request = TSRequest(url: url)
return LokiFileServerProxy(for: server).perform(request).map { response -> String in return LokiFileServerProxy(for: server).perform(request).map { response -> String in
guard let json = response as? JSON, let data = json["data"] as? String else { throw Error.proxyResponseParsingFailed } guard let data = response as? Data, let json = try? JSONSerialization.jsonObject(with: data, options: []) as? JSON, let xml = json["data"] as? String else { throw Error.proxyResponseParsingFailed }
return data return xml
} }
} }
} }

@ -78,7 +78,7 @@ internal class LokiSnodeProxy : LokiHTTPClient {
var body: Any? = nil var body: Any? = nil
if let bodyAsString = json["body"] as? String { if let bodyAsString = json["body"] as? String {
body = bodyAsString body = bodyAsString
if let bodyAsJSON = try? JSONSerialization.jsonObject(with: bodyAsString.data(using: .utf8)!, options: .allowFragments) as? [String: Any] { if let bodyAsJSON = try? JSONSerialization.jsonObject(with: bodyAsString.data(using: .utf8)!, options: .allowFragments) as? JSON {
body = bodyAsJSON body = bodyAsJSON
} }
} }

Loading…
Cancel
Save