Implemented making URLs absolute

This commit is contained in:
dankito 2020-07-31 00:20:24 +02:00
parent b898f9d17e
commit fb071f8826
2 changed files with 65 additions and 5 deletions

View File

@ -7,6 +7,8 @@ class FaviconFinder {
private let webClient = UrlSessionWebClient() // TODO: create interface and pass from SwiftBankIconFinder private let webClient = UrlSessionWebClient() // TODO: create interface and pass from SwiftBankIconFinder
private let urlUtil = UrlUtil()
func extractFavicons(url: String, callback: @escaping ([Favicon]) -> Void) { func extractFavicons(url: String, callback: @escaping ([Favicon]) -> Void) {
webClient.getAsync(url) { response in webClient.getAsync(url) { response in
@ -41,7 +43,7 @@ class FaviconFinder {
let urlInstance = URL(string: url) let urlInstance = URL(string: url)
let defaultFaviconUrl = "\(urlInstance?.scheme ?? "https")://\(urlInstance?.host ?? "")/favicon.ico" let defaultFaviconUrl = "\(urlInstance?.scheme ?? "https")://\(urlInstance?.host ?? "")/favicon.ico"
if (containsIconWithUrl(extractedFavicons, defaultFaviconUrl) == false) { if containsIconWithUrl(extractedFavicons, defaultFaviconUrl) == false {
let response = webClient.head(defaultFaviconUrl) let response = webClient.head(defaultFaviconUrl)
if (response.successful) { if (response.successful) {
extractedFavicons.append(Favicon(url: defaultFaviconUrl, iconType: FaviconType.ShortcutIcon)) extractedFavicons.append(Favicon(url: defaultFaviconUrl, iconType: FaviconType.ShortcutIcon))
@ -106,10 +108,10 @@ class FaviconFinder {
private func mapMetaElementToFavicon(_ metaElement: Element, _ siteUrl: String) -> Favicon? { private func mapMetaElementToFavicon(_ metaElement: Element, _ siteUrl: String) -> Favicon? {
if let content = try? metaElement.attr("content") { if let content = try? metaElement.attr("content") {
if isOpenGraphImageDeclaration(metaElement) { 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) { 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? { private func createFavicon(url: String?, siteUrl: String, iconType: FaviconType, sizesString: String?, type: String?) -> Favicon? {
if let url = url { 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) let size = extractSizesFromString(sizesString)
return Favicon(url: absoluteUrl, iconType: iconType, size: size, type: type) return Favicon(url: absoluteUrl, iconType: iconType, size: size, type: type)
@ -141,7 +145,7 @@ class FaviconFinder {
} }
private func makeLinkAbsolute(url: String, siteUrl: String) -> String { private func makeLinkAbsolute(url: String, siteUrl: String) -> String {
return url // TODO return urlUtil.makeLinkAbsolute(url: url, siteUrl: siteUrl)
} }
private func extractSizesFromString(_ sizesString: String?) -> Size? { private func extractSizesFromString(_ sizesString: String?) -> Size? {

View File

@ -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
}
}