From fb071f8826b22eceb2fc648379fa2dadae9ba5c0 Mon Sep 17 00:00:00 2001 From: dankito Date: Fri, 31 Jul 2020 00:20:24 +0200 Subject: [PATCH] Implemented making URLs absolute --- .../BankIconFinder/FaviconFinder.swift | 14 +++-- .../BankIconFinder/UrlUtil.swift | 56 +++++++++++++++++++ 2 files changed, 65 insertions(+), 5 deletions(-) create mode 100644 ui/BankingiOSApp/BankingiOSApp/BankIconFinder/UrlUtil.swift diff --git a/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/FaviconFinder.swift b/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/FaviconFinder.swift index fcdf5b2b..8fedc212 100644 --- a/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/FaviconFinder.swift +++ b/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/FaviconFinder.swift @@ -7,6 +7,8 @@ class FaviconFinder { private let webClient = UrlSessionWebClient() // TODO: create interface and pass from SwiftBankIconFinder + private let urlUtil = UrlUtil() + func extractFavicons(url: String, callback: @escaping ([Favicon]) -> Void) { webClient.getAsync(url) { response in @@ -41,7 +43,7 @@ class FaviconFinder { let urlInstance = URL(string: url) let defaultFaviconUrl = "\(urlInstance?.scheme ?? "https")://\(urlInstance?.host ?? "")/favicon.ico" - if (containsIconWithUrl(extractedFavicons, defaultFaviconUrl) == false) { + if containsIconWithUrl(extractedFavicons, defaultFaviconUrl) == false { let response = webClient.head(defaultFaviconUrl) if (response.successful) { extractedFavicons.append(Favicon(url: defaultFaviconUrl, iconType: FaviconType.ShortcutIcon)) @@ -106,10 +108,10 @@ class FaviconFinder { private func mapMetaElementToFavicon(_ metaElement: Element, _ siteUrl: String) -> Favicon? { if let content = try? metaElement.attr("content") { if isOpenGraphImageDeclaration(metaElement) { - return Favicon(url: makeLinkAbsolute(url: content, siteUrl: siteUrl), iconType: FaviconType.OpenGraphImage) + return createFavicon(url: content, siteUrl: siteUrl, iconType: FaviconType.OpenGraphImage, sizesString: nil, type: nil) } else if isMsTileMetaElement(metaElement) { - return Favicon(url: makeLinkAbsolute(url: content, siteUrl: siteUrl), iconType: FaviconType.MsTileImage) + return createFavicon(url: content, siteUrl: siteUrl, iconType: FaviconType.MsTileImage, sizesString: nil, type: nil) } } @@ -131,7 +133,9 @@ class FaviconFinder { private func createFavicon(url: String?, siteUrl: String, iconType: FaviconType, sizesString: String?, type: String?) -> Favicon? { if let url = url { - let absoluteUrl = makeLinkAbsolute(url: url, siteUrl: siteUrl) + let urlWithoutQuery = URL(string: url)?.path ?? url // TODO: find a better solution to remove query / fragment + let absoluteUrl = makeLinkAbsolute(url: urlWithoutQuery, siteUrl: siteUrl) + let size = extractSizesFromString(sizesString) return Favicon(url: absoluteUrl, iconType: iconType, size: size, type: type) @@ -141,7 +145,7 @@ class FaviconFinder { } private func makeLinkAbsolute(url: String, siteUrl: String) -> String { - return url // TODO + return urlUtil.makeLinkAbsolute(url: url, siteUrl: siteUrl) } private func extractSizesFromString(_ sizesString: String?) -> Size? { diff --git a/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/UrlUtil.swift b/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/UrlUtil.swift new file mode 100644 index 00000000..6076fa16 --- /dev/null +++ b/ui/BankingiOSApp/BankingiOSApp/BankIconFinder/UrlUtil.swift @@ -0,0 +1,56 @@ +import SwiftUI + + +class UrlUtil { + + func makeLinkAbsolute(url: String, siteUrl: String) -> String { + var absoluteUrl = url + + if(url.starts(with: "//")) { + if(siteUrl.starts(with: "https:")) { + absoluteUrl = "https:" + url + } + else { + absoluteUrl = "http:" + url + } + } + else if(url.starts(with: "/")) { + if let url = tryToMakeUrlAbsolute(relativeUrl: url, siteUrl: siteUrl) { + absoluteUrl = url + } + } + else if(url.starts(with: "http") == false) { + if let url = tryToMakeUrlAbsolute(relativeUrl: url, siteUrl: siteUrl) { + absoluteUrl = url + } + } + + return absoluteUrl + } + + func tryToMakeUrlAbsolute(relativeUrl: String, siteUrl: String) -> String? { + if let relativeUri = URL.encoded(relativeUrl) { + // TODO: how to do this check in Swift? +// if(relativeUri.isAbsolute && relativeUri.scheme.starts(with: "http") == false) { +// return relativeUrl // it's an absolute uri but just doesn't start with http, e.g. mailto: for file: +// } + } + + if let uri = URL.encoded(siteUrl) { + return uri.appendingPathComponent(relativeUrl).absoluteString // i think this always works in Swift + } + + if let uri = URL.encoded(siteUrl) { + + let port = (uri.port ?? 0) > 0 ? ":" + String(uri.port!) : "" + let separator = relativeUrl.starts(with: "/") ? "" : "/" + + let manuallyCreatedUriString = "\(uri.scheme)://\(uri.host)\(port)\(separator)\(relativeUrl)" + + return URL.encoded(manuallyCreatedUriString)?.absoluteString + } + + return nil + } + +}