diff --git a/Sora/Utils/Extensions/JavaScriptCore+Extensions.swift b/Sora/Utils/Extensions/JavaScriptCore+Extensions.swift index 9bb54b4..18f4d39 100644 --- a/Sora/Utils/Extensions/JavaScriptCore+Extensions.swift +++ b/Sora/Utils/Extensions/JavaScriptCore+Extensions.swift @@ -75,7 +75,7 @@ extension JSContext { } func setupFetchV2() { - let fetchV2NativeFunction: @convention(block) (String, [String: String]?, String?, String?, JSValue, JSValue) -> Void = { urlString, headers, method, body, resolve, reject in + let fetchV2NativeFunction: @convention(block) (String, [String: String]?, String?, String?, ObjCBool,JSValue, JSValue) -> Void = { urlString, headers, method, body, redirect, resolve, reject in guard let url = URL(string: urlString) else { Logger.shared.log("Invalid URL", type: "Error") reject.call(withArguments: ["Invalid URL"]) @@ -104,8 +104,8 @@ extension JSContext { request.setValue(value, forHTTPHeaderField: key) } } - - let task = URLSession.custom.downloadTask(with: request) { tempFileURL, response, error in + Logger.shared.log("Redirect value is \(redirect.boolValue)",type:"Error") + let task = URLSession.fetchData(allowRedirects: redirect.boolValue).downloadTask(with: request) { tempFileURL, response, error in if let error = error { Logger.shared.log("Network error in fetchV2NativeFunction: \(error.localizedDescription)", type: "Error") reject.call(withArguments: [error.localizedDescription]) @@ -117,6 +117,12 @@ extension JSContext { reject.call(withArguments: ["No data"]) return } + // initialise return Object + var responseDict: [String: Any] = [ + "status": (response as? HTTPURLResponse)?.statusCode ?? 0, + "headers": (response as? HTTPURLResponse)?.allHeaderFields ?? [:], + "body": "" + ] do { let data = try Data(contentsOf: tempFileURL) @@ -128,16 +134,13 @@ extension JSContext { } if let text = String(data: data, encoding: .utf8) { - // Create a response object to return - let responseDict: [String: Any] = [ - "status": (response as? HTTPURLResponse)?.statusCode ?? 0, - "headers": (response as? HTTPURLResponse)?.allHeaderFields ?? [:], - "body": text - ] + + responseDict["body"] = text resolve.call(withArguments: [responseDict]) } else { + // rather than reject -> resolve with empty body as user can utilise reponse headers. Logger.shared.log("Unable to decode data to text", type: "Error") - reject.call(withArguments: ["Unable to decode data"]) + resolve.call(withArguments: [responseDict]) } } catch { @@ -152,7 +155,7 @@ extension JSContext { self.setObject(fetchV2NativeFunction, forKeyedSubscript: "fetchV2Native" as NSString) let fetchv2Definition = """ - function fetchv2(url, headers = {}, method = "GET", body = null) { + function fetchv2(url, headers = {}, method = "GET", body = null, redirect = true ) { var processedBody = null; @@ -163,7 +166,7 @@ extension JSContext { } return new Promise(function(resolve, reject) { - fetchV2Native(url, headers, method, processedBody, function(rawText) { + fetchV2Native(url, headers, method, processedBody, redirect, function(rawText) { const responseObj = { headers: rawText.headers, status: rawText.status, diff --git a/Sora/Utils/Extensions/URLSession.swift b/Sora/Utils/Extensions/URLSession.swift index 544b084..efa4fcb 100644 --- a/Sora/Utils/Extensions/URLSession.swift +++ b/Sora/Utils/Extensions/URLSession.swift @@ -6,7 +6,27 @@ // import Foundation - +// URL DELEGATE CLASS FOR FETCH API +class FetchDelegate: NSObject, URLSessionTaskDelegate +{ + private let allowRedirects: Bool + init(allowRedirects: Bool) { + self.allowRedirects = allowRedirects + } + // This handles the redirection and prevents it. + func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { + if(allowRedirects) + { + completionHandler(request) // Allow Redirect + } + else + { + completionHandler(nil) // Block Redirect + } + + } + +} extension URLSession { static let userAgents = [ "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/129.0.0.0 Safari/537.36", @@ -43,4 +63,13 @@ extension URLSession { configuration.httpAdditionalHeaders = ["User-Agent": randomUserAgent] return URLSession(configuration: configuration) }() + // return url session that redirects based on input + static func fetchData(allowRedirects:Bool) -> URLSession + { + let delegate = FetchDelegate(allowRedirects:allowRedirects) + let configuration = URLSessionConfiguration.default + configuration.httpAdditionalHeaders = ["User-Agent": randomUserAgent] + return URLSession(configuration: configuration, delegate: delegate, delegateQueue: nil) + } } +