diff --git a/SignalUtilitiesKit/OWSLinkPreview.swift b/SignalUtilitiesKit/OWSLinkPreview.swift index 8f2d9977f..ac278707e 100644 --- a/SignalUtilitiesKit/OWSLinkPreview.swift +++ b/SignalUtilitiesKit/OWSLinkPreview.swift @@ -496,8 +496,8 @@ public class OWSLinkPreview: MTLModel { return Promise.value(cachedInfo) } return downloadLink(url: previewUrl) - .then(on: DispatchQueue.global()) { (data) -> Promise in - return parseLinkDataAndBuildDraft(linkData: data, linkUrlString: previewUrl) + .then(on: DispatchQueue.global()) { (data, response) -> Promise in + return parseLinkDataAndBuildDraft(linkData: data, response: response, linkUrlString: previewUrl) }.then(on: DispatchQueue.global()) { (linkPreviewDraft) -> Promise in guard linkPreviewDraft.isValid() else { throw LinkPreviewError.noPreview @@ -507,9 +507,14 @@ public class OWSLinkPreview: MTLModel { return Promise.value(linkPreviewDraft) } } + + // Twitter doesn't return OpenGraph tags to Signal + // `curl -A Signal "https://twitter.com/signalapp/status/1280166087577997312?s=20"` + // If this ever changes, we can switch back to our default User-Agent + private static let userAgentString = "WhatsApp" class func downloadLink(url urlString: String, - remainingRetries: UInt = 3) -> Promise { + remainingRetries: UInt = 3) -> Promise<(Data, URLResponse)> { Logger.verbose("url: \(urlString)") @@ -529,11 +534,13 @@ public class OWSLinkPreview: MTLModel { owsFailDebug("Could not configure url: \(urlString).") return Promise(error: LinkPreviewError.assertionFailure) } + + sessionManager.requestSerializer.setValue(self.userAgentString, forHTTPHeaderField: "User-Agent") - let (promise, resolver) = Promise.pending() + let (promise, resolver) = Promise<(Data, URLResponse)>.pending() sessionManager.get(urlString, parameters: [String: AnyObject](), - headers: [:], + headers: nil, progress: nil, success: { task, value in @@ -559,7 +566,7 @@ public class OWSLinkPreview: MTLModel { resolver.reject(LinkPreviewError.invalidContent) return } - resolver.fulfill(data) + resolver.fulfill((data, response)) }, failure: { _, error in Logger.verbose("Error: \(error)") @@ -576,8 +583,8 @@ public class OWSLinkPreview: MTLModel { return } OWSLinkPreview.downloadLink(url: urlString, remainingRetries: remainingRetries - 1) - .done(on: DispatchQueue.global()) { (data) in - resolver.fulfill(data) + .done(on: DispatchQueue.global()) { (data, response) in + resolver.fulfill((data, response)) }.catch(on: DispatchQueue.global()) { (error) in resolver.reject(error) }.retainUntilComplete() @@ -662,9 +669,10 @@ public class OWSLinkPreview: MTLModel { } class func parseLinkDataAndBuildDraft(linkData: Data, + response: URLResponse, linkUrlString: String) -> Promise { do { - let contents = try parse(linkData: linkData) + let contents = try parse(linkData: linkData, response: response) let title = contents.title guard let imageUrl = contents.imageUrl else { @@ -699,9 +707,9 @@ public class OWSLinkPreview: MTLModel { } } - class func parse(linkData: Data) throws -> OWSLinkPreviewContents { - guard let linkText = String(bytes: linkData, encoding: .utf8) else { - owsFailDebug("Could not parse link text.") + class func parse(linkData: Data, response: URLResponse) throws -> OWSLinkPreviewContents { + guard let linkText = String(data: linkData, urlResponse: response) else { + print("Could not parse link text.") throw LinkPreviewError.invalidInput }