From 884b063065592b74c52a264674d68ed02d90443c Mon Sep 17 00:00:00 2001 From: Ali Moazenzadeh Date: Tue, 23 Nov 2021 10:11:35 +0330 Subject: [PATCH 1/6] Add observation protocol --- Sources/NetShears/Models/RequestModel.swift | 2 +- Sources/NetShears/NetShears.swift | 10 ++++- .../Observable/RequestBroadcast.swift | 38 +++++++++++++++++++ .../Observable/RequestObservable.swift | 26 +++++++++++++ .../NetShears/Observable/RequestStorage.swift | 18 +++++++++ .../NetworkLoggerUrlProtocol.swift | 10 ++++- Sources/NetShears/Utils/ThreadSafe.swift | 26 +++++++++++++ 7 files changed, 126 insertions(+), 4 deletions(-) create mode 100644 Sources/NetShears/Observable/RequestBroadcast.swift create mode 100644 Sources/NetShears/Observable/RequestObservable.swift create mode 100644 Sources/NetShears/Observable/RequestStorage.swift create mode 100644 Sources/NetShears/Utils/ThreadSafe.swift diff --git a/Sources/NetShears/Models/RequestModel.swift b/Sources/NetShears/Models/RequestModel.swift index b93fea6..0facbe2 100644 --- a/Sources/NetShears/Models/RequestModel.swift +++ b/Sources/NetShears/Models/RequestModel.swift @@ -7,7 +7,7 @@ import Foundation import UIKit -final class NetShearsRequestModel: Codable { +public final class NetShearsRequestModel: Codable { let id: String let url: String let host: String? diff --git a/Sources/NetShears/NetShears.swift b/Sources/NetShears/NetShears.swift index 9de4e93..ce70b40 100644 --- a/Sources/NetShears/NetShears.swift +++ b/Sources/NetShears/NetShears.swift @@ -11,10 +11,18 @@ public final class NetShears: NSObject { public static let shared = NetShears() let networkRequestInterceptor = NetworkRequestInterceptor() + lazy var config: NetworkInterceptorConfig = { var savedModifiers = [RequestEvaluatorModifier]().retrieveFromDisk() return NetworkInterceptorConfig(modifiers: savedModifiers) }() + + lazy var requestObserver: RequestObserverProtocol = { + RequestObserver(options: [ + RequestStorage.shared, + RequestBroadcast.shared + ]) + }() public func startRecording(){ @@ -56,6 +64,6 @@ public final class NetShears: NSObject { HPACKHeadersRequest: [String: String]?, HPACKHeadersResponse: [String: String]?){ let request = NetShearsRequestModel(url: url, host: host, requestObject: requestObject, responseObject: responseObject, success: success, statusCode: statusCode, duration: duration, HPACKHeadersRequest: HPACKHeadersRequest, HPACKHeadersResponse: HPACKHeadersResponse) - Storage.shared.saveRequest(request: request) + requestObserver.newRequestArrived(request) } } diff --git a/Sources/NetShears/Observable/RequestBroadcast.swift b/Sources/NetShears/Observable/RequestBroadcast.swift new file mode 100644 index 0000000..58af0a8 --- /dev/null +++ b/Sources/NetShears/Observable/RequestBroadcast.swift @@ -0,0 +1,38 @@ +// +// RequestBroadcast.swift +// +// +// Created by Ali Moazenzadeh on 11/17/21. +// + +import Foundation + +public protocol RequestBroadcastDelegate: AnyObject { + func newRequestArrived(_ request: NetShearsRequestModel) +} + +public final class RequestBroadcast: RequestObserverProtocol { + static let shared = RequestBroadcast() + + var delegate = ThreadSafe(nil) + + private init() {} + + func setDelegate(_ newDelegate: RequestBroadcastDelegate) { + delegate.atomically { delegate in + delegate = newDelegate + } + } + + func removeDelegate() { + delegate.atomically { delegate in + delegate = nil + } + } + + func newRequestArrived(_ request: NetShearsRequestModel) { + delegate.atomically { delegate in + delegate?.newRequestArrived(request) + } + } +} diff --git a/Sources/NetShears/Observable/RequestObservable.swift b/Sources/NetShears/Observable/RequestObservable.swift new file mode 100644 index 0000000..0aa15f7 --- /dev/null +++ b/Sources/NetShears/Observable/RequestObservable.swift @@ -0,0 +1,26 @@ +// +// RequestObservable.swift +// +// +// Created by Ali Moazenzadeh on 11/17/21. +// + +import Foundation + +protocol RequestObserverProtocol { + func newRequestArrived(_ request: NetShearsRequestModel) +} + +final class RequestObserver: RequestObserverProtocol { + let options: [RequestObserverProtocol] + + init(options: [RequestObserverProtocol]) { + self.options = options + } + + func newRequestArrived(_ request: NetShearsRequestModel) { + options.forEach { + $0.newRequestArrived(request) + } + } +} diff --git a/Sources/NetShears/Observable/RequestStorage.swift b/Sources/NetShears/Observable/RequestStorage.swift new file mode 100644 index 0000000..015030c --- /dev/null +++ b/Sources/NetShears/Observable/RequestStorage.swift @@ -0,0 +1,18 @@ +// +// RequestStorage.swift +// +// +// Created by Ali Moazenzadeh on 11/17/21. +// + +import Foundation + +final class RequestStorage: RequestObserverProtocol { + static let shared = RequestStorage() + + private init() {} + + func newRequestArrived(_ request: NetShearsRequestModel) { + Storage.shared.saveRequest(request: request) + } +} diff --git a/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift b/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift index 8c352e8..f16ffb1 100644 --- a/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift +++ b/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift @@ -16,6 +16,12 @@ public class NetworkLoggerUrlProtocol: URLProtocol { var session: URLSession? var sessionTask: URLSessionDataTask? var currentRequest: NetShearsRequestModel? + lazy var requestObserver: RequestObserverProtocol = { + RequestObserver(options: [ + RequestStorage.shared, + RequestBroadcast.shared + ]) + }() override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) { super.init(request: request, cachedResponse: cachedResponse, client: client) @@ -44,7 +50,7 @@ public class NetworkLoggerUrlProtocol: URLProtocol { sessionTask?.resume() currentRequest = NetShearsRequestModel(request: newRequest, session: session) - Storage.shared.saveRequest(request: currentRequest) + requestObserver.newRequestArrived(request) } override public func stopLoading() { @@ -54,7 +60,7 @@ public class NetworkLoggerUrlProtocol: URLProtocol { currentRequest?.duration = fabs(startDate.timeIntervalSinceNow) * 1000 //Find elapsed time and convert to milliseconds } - Storage.shared.saveRequest(request: currentRequest) + requestObserver.newRequestArrived(currentRequest) session?.invalidateAndCancel() } diff --git a/Sources/NetShears/Utils/ThreadSafe.swift b/Sources/NetShears/Utils/ThreadSafe.swift new file mode 100644 index 0000000..12c0853 --- /dev/null +++ b/Sources/NetShears/Utils/ThreadSafe.swift @@ -0,0 +1,26 @@ +// +// ThreadSafe.swift +// +// +// Created by Ali Moazenzadeh on 11/17/21. +// + +import Foundation + +final class ThreadSafe { + private var _value: A + private let queue = DispatchQueue(label: "ThreadSafe") + init(_ value: A) { + self._value = value + } + + var value: A { + return queue.sync { _value } + } + + func atomically(_ transform: (inout A) -> Void) { + queue.sync { + transform(&self._value) + } + } +} From 7373e42f4a5abef42f8397885c51edb4942d93f1 Mon Sep 17 00:00:00 2001 From: Ali Moazenzadeh Date: Tue, 23 Nov 2021 10:25:40 +0330 Subject: [PATCH 2/6] Remove unwanted public keywords --- Sources/NetShears/Colors.swift | 26 ++++++------ .../Extension/URLRequest+Extension.swift | 2 +- Sources/NetShears/NetworkInterceptor.swift | 11 +++-- .../NetShears/NetworkInterceptorConfig.swift | 18 ++++----- .../NetShears/NetworkRequestInterceptor.swift | 12 +++--- .../NetShears/Protocols/PersistHelper.swift | 2 +- .../RequestEvaluatorModifierEndpoint.swift | 18 ++++----- .../RequestEvaluatorModifierHeader.swift | 14 +++---- Sources/NetShears/Storage.swift | 6 +-- .../NetworkInterceptorUrlProtocol.swift | 26 ++++++------ .../NetworkLoggerUrlProtocol.swift | 40 ++++++++++--------- Tests/NetShearsTests/XCTestManifests.swift | 2 +- 12 files changed, 90 insertions(+), 87 deletions(-) diff --git a/Sources/NetShears/Colors.swift b/Sources/NetShears/Colors.swift index f64f94b..162f01f 100644 --- a/Sources/NetShears/Colors.swift +++ b/Sources/NetShears/Colors.swift @@ -9,25 +9,25 @@ import UIKit struct Colors { struct UI{ - static public let wordsInEvidence = UIColor(hexString: "#dadfe1") - static public let wordFocus = UIColor(hexString: "#f7ca18") + static let wordsInEvidence = UIColor(hexString: "#dadfe1") + static let wordFocus = UIColor(hexString: "#f7ca18") } struct Gray{ - static public let darkestGray = UIColor(hexString: "#666666") - static public let darkerGray = UIColor(hexString: "#888888") - static public let darkGray = UIColor(hexString: "#999999") - static public let midGray = UIColor(hexString: "#BBBBBB") - static public let lightGray = UIColor(hexString: "#CCCCCC") - static public let lighestGray = UIColor(hexString: "#E7E7E7") + static let darkestGray = UIColor(hexString: "#666666") + static let darkerGray = UIColor(hexString: "#888888") + static let darkGray = UIColor(hexString: "#999999") + static let midGray = UIColor(hexString: "#BBBBBB") + static let lightGray = UIColor(hexString: "#CCCCCC") + static let lighestGray = UIColor(hexString: "#E7E7E7") } struct HTTPCode{ - static public let Success = UIColor(hexString: "#297E4C") //2xx - static public let Redirect = UIColor(hexString: "#3D4140") //3xx - static public let ClientError = UIColor(hexString: "#D97853") //4xx - static public let ServerError = UIColor(hexString: "#D32C58") //5xx - static public let Generic = UIColor(hexString: "#999999") //Others + static let Success = UIColor(hexString: "#297E4C") //2xx + static let Redirect = UIColor(hexString: "#3D4140") //3xx + static let ClientError = UIColor(hexString: "#D97853") //4xx + static let ServerError = UIColor(hexString: "#D32C58") //5xx + static let Generic = UIColor(hexString: "#999999") //Others } } diff --git a/Sources/NetShears/Extension/URLRequest+Extension.swift b/Sources/NetShears/Extension/URLRequest+Extension.swift index 6c48572..7598359 100644 --- a/Sources/NetShears/Extension/URLRequest+Extension.swift +++ b/Sources/NetShears/Extension/URLRequest+Extension.swift @@ -8,7 +8,7 @@ import Foundation extension URLRequest { - public func getHttpBodyStreamData() -> Data? { + func getHttpBodyStreamData() -> Data? { guard let httpBodyStream = self.httpBodyStream else { return nil } diff --git a/Sources/NetShears/NetworkInterceptor.swift b/Sources/NetShears/NetworkInterceptor.swift index 46560a6..4dcc288 100644 --- a/Sources/NetShears/NetworkInterceptor.swift +++ b/Sources/NetShears/NetworkInterceptor.swift @@ -8,20 +8,20 @@ import Foundation -@objc public class NetworkInterceptor: NSObject { +@objc class NetworkInterceptor: NSObject { - @objc public static let shared = NetworkInterceptor() + @objc static let shared = NetworkInterceptor() let networkRequestInterceptor = NetworkRequestInterceptor() - public func startRecording(){ + func startRecording(){ self.networkRequestInterceptor.startRecording() } - public func stopRecording(){ + func stopRecording(){ self.networkRequestInterceptor.stopRecording() } - public func shouldRequestModify(urlRequest: URLRequest) -> Bool { + func shouldRequestModify(urlRequest: URLRequest) -> Bool { for modifer in NetShears.shared.config.modifiers { if modifer.isActionAllowed(urlRequest: urlRequest) { return true @@ -29,6 +29,5 @@ import Foundation } return false } - } diff --git a/Sources/NetShears/NetworkInterceptorConfig.swift b/Sources/NetShears/NetworkInterceptorConfig.swift index 33d23f5..dc4368b 100644 --- a/Sources/NetShears/NetworkInterceptorConfig.swift +++ b/Sources/NetShears/NetworkInterceptorConfig.swift @@ -7,27 +7,27 @@ import Foundation -public struct RedirectedRequestModel: Codable, Equatable { - public let originalUrl: String - public let redirectUrl: String +struct RedirectedRequestModel: Codable, Equatable { + let originalUrl: String + let redirectUrl: String - public init (originalUrl: String, redirectUrl: String) { + init (originalUrl: String, redirectUrl: String) { self.originalUrl = originalUrl self.redirectUrl = redirectUrl } } -public struct HeaderModifyModel: Codable, Equatable { - public let key: String - public let value: String +struct HeaderModifyModel: Codable, Equatable { + let key: String + let value: String - public init (key: String, value: String) { + init (key: String, value: String) { self.key = key self.value = value } } -public final class NetworkInterceptorConfig { +final class NetworkInterceptorConfig { var modifiers: [RequestEvaluatorModifier] = [] { didSet { modifiers.store() diff --git a/Sources/NetShears/NetworkRequestInterceptor.swift b/Sources/NetShears/NetworkRequestInterceptor.swift index 19a1cc4..3c0ba07 100644 --- a/Sources/NetShears/NetworkRequestInterceptor.swift +++ b/Sources/NetShears/NetworkRequestInterceptor.swift @@ -7,25 +7,25 @@ import Foundation -@objc public class NetworkRequestInterceptor: NSObject{ - +@objc class NetworkRequestInterceptor: NSObject{ + func swizzleProtocolClasses(){ let instance = URLSessionConfiguration.default let uRLSessionConfigurationClass: AnyClass = object_getClass(instance)! - + let method1: Method = class_getInstanceMethod(uRLSessionConfigurationClass, #selector(getter: uRLSessionConfigurationClass.protocolClasses))! let method2: Method = class_getInstanceMethod(URLSessionConfiguration.self, #selector(URLSessionConfiguration.fakeProcotolClasses))! - + method_exchangeImplementations(method1, method2) } - public func startRecording() { + func startRecording() { URLProtocol.registerClass(NetworkInterceptorUrlProtocol.self) URLProtocol.registerClass(NetworkLoggerUrlProtocol.self) swizzleProtocolClasses() } - public func stopRecording() { + func stopRecording() { URLProtocol.unregisterClass(NetworkInterceptorUrlProtocol.self) URLProtocol.unregisterClass(NetworkLoggerUrlProtocol.self) swizzleProtocolClasses() diff --git a/Sources/NetShears/Protocols/PersistHelper.swift b/Sources/NetShears/Protocols/PersistHelper.swift index 1485d24..57182d6 100644 --- a/Sources/NetShears/Protocols/PersistHelper.swift +++ b/Sources/NetShears/Protocols/PersistHelper.swift @@ -7,7 +7,7 @@ import Foundation -public class PersistHelper { +class PersistHelper { fileprivate init() { } diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift index 3cf4db2..a217caa 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift @@ -7,26 +7,26 @@ import Foundation -public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable, Codable { +struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable, Codable { - public var redirectedRequest: RedirectedRequestModel - - public static var storeFileName: String { + var redirectedRequest: RedirectedRequestModel + + static var storeFileName: String { "Modifier.txt" } - public init(redirectedRequest: RedirectedRequestModel) { + init(redirectedRequest: RedirectedRequestModel) { self.redirectedRequest = redirectedRequest } - public func modify(request: inout URLRequest) { - + func modify(request: inout URLRequest) { + if isRequestRedirectable(urlRequest: request) { request.modifyURLRequestEndpoint(redirectUrl: redirectedRequest) } } - public func isActionAllowed(urlRequest: URLRequest) -> Bool { + func isActionAllowed(urlRequest: URLRequest) -> Bool { return isRequestRedirectable(urlRequest: urlRequest) } @@ -34,7 +34,7 @@ public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equata guard let urlString = urlRequest.url?.absoluteString else { return false } - + if urlString.contains(redirectedRequest.originalUrl) { return true } diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift index 38575ba..53dc70e 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift @@ -7,23 +7,23 @@ import Foundation -public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable, Codable { +struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable, Codable { - public var header: HeaderModifyModel - - public static var storeFileName: String { + var header: HeaderModifyModel + + static var storeFileName: String { "Header.txt" } - public init(header: HeaderModifyModel) { + init(header: HeaderModifyModel) { self.header = header } - public func modify(request: inout URLRequest) { + func modify(request: inout URLRequest) { request.modifyURLRequestHeader(header: header) } - public func isActionAllowed(urlRequest: URLRequest) -> Bool { + func isActionAllowed(urlRequest: URLRequest) -> Bool { return true } } diff --git a/Sources/NetShears/Storage.swift b/Sources/NetShears/Storage.swift index 4b243b8..7b12e0e 100644 --- a/Sources/NetShears/Storage.swift +++ b/Sources/NetShears/Storage.swift @@ -10,7 +10,7 @@ import Foundation final class Storage: NSObject { - public static let shared: Storage = Storage() + static let shared: Storage = Storage() var requests: [NetShearsRequestModel] = [] @@ -21,9 +21,9 @@ final class Storage: NSObject { if let index = requests.firstIndex(where: { (req) -> Bool in return request?.id == req.id ? true : false - }){ + }) { requests[index] = request! - }else{ + } else { requests.insert(request!, at: 0) } NotificationCenter.default.post(name: NSNotification.Name.NewRequestNotification, object: nil) diff --git a/Sources/NetShears/URLProtocol/NetworkInterceptorUrlProtocol.swift b/Sources/NetShears/URLProtocol/NetworkInterceptorUrlProtocol.swift index ba40ac8..4628fa2 100644 --- a/Sources/NetShears/URLProtocol/NetworkInterceptorUrlProtocol.swift +++ b/Sources/NetShears/URLProtocol/NetworkInterceptorUrlProtocol.swift @@ -7,9 +7,9 @@ import Foundation -public class NetworkInterceptorUrlProtocol: URLProtocol { +class NetworkInterceptorUrlProtocol: URLProtocol { static var blacklistedHosts = [String]() - + struct Constants { static let RequestHandledKey = "NetworkInterceptorUrlProtocol" } @@ -25,9 +25,9 @@ public class NetworkInterceptorUrlProtocol: URLProtocol { } } - override public class func canInit(with request: URLRequest) -> Bool { + override class func canInit(with request: URLRequest) -> Bool { guard NetworkInterceptor.shared.shouldRequestModify(urlRequest: request) else { return false } - + if NetworkInterceptorUrlProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil { return false } @@ -40,7 +40,7 @@ public class NetworkInterceptorUrlProtocol: URLProtocol { return mutableRequest.copy() as! URLRequest } - override public func startLoading() { + override func startLoading() { var newRequest = request for modifier in NetShears.shared.config.modifiers where modifier.isActionAllowed(urlRequest: request) { modifier.modify(request: &newRequest) @@ -51,7 +51,7 @@ public class NetworkInterceptorUrlProtocol: URLProtocol { sessionTask?.resume() } - override public func stopLoading() { + override func stopLoading() { sessionTask?.cancel() session?.invalidateAndCancel() } @@ -63,17 +63,17 @@ public class NetworkInterceptorUrlProtocol: URLProtocol { } extension NetworkInterceptorUrlProtocol: URLSessionDataDelegate { - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { client?.urlProtocol(self, didLoad: data) } - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { let policy = URLCache.StoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .notAllowed client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: policy) completionHandler(.allow) } - public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { client?.urlProtocol(self, didFailWithError: error) } else { @@ -81,17 +81,17 @@ extension NetworkInterceptorUrlProtocol: URLSessionDataDelegate { } } - public func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { + func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { client?.urlProtocol(self, wasRedirectedTo: request, redirectResponse: response) completionHandler(request) } - public func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { + func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { guard let error = error else { return } client?.urlProtocol(self, didFailWithError: error) } - public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let protectionSpace = challenge.protectionSpace let sender = challenge.sender @@ -105,7 +105,7 @@ extension NetworkInterceptorUrlProtocol: URLSessionDataDelegate { } } - public func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { + func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { client?.urlProtocolDidFinishLoading(self) } } diff --git a/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift b/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift index f16ffb1..f374f5d 100644 --- a/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift +++ b/Sources/NetShears/URLProtocol/NetworkLoggerUrlProtocol.swift @@ -7,8 +7,8 @@ import Foundation -public class NetworkLoggerUrlProtocol: URLProtocol { - +class NetworkLoggerUrlProtocol: URLProtocol { + struct Constants { static let RequestHandledKey = "NetworkLoggerUrlProtocol" } @@ -31,36 +31,40 @@ public class NetworkLoggerUrlProtocol: URLProtocol { } } - override public class func canInit(with request: URLRequest) -> Bool { - + override class func canInit(with request: URLRequest) -> Bool { + if NetworkLoggerUrlProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil { return false } return true } - override public class func canonicalRequest(for request: URLRequest) -> URLRequest { + override class func canonicalRequest(for request: URLRequest) -> URLRequest { return request } - override public func startLoading() { + override func startLoading() { let newRequest = ((request as NSURLRequest).mutableCopy() as? NSMutableURLRequest)! NetworkLoggerUrlProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest) sessionTask = session?.dataTask(with: newRequest as URLRequest) sessionTask?.resume() currentRequest = NetShearsRequestModel(request: newRequest, session: session) - requestObserver.newRequestArrived(request) + if let request = currentRequest { + requestObserver.newRequestArrived(request) + } } - override public func stopLoading() { + override func stopLoading() { sessionTask?.cancel() currentRequest?.httpBody = body(from: request) if let startDate = currentRequest?.date{ currentRequest?.duration = fabs(startDate.timeIntervalSinceNow) * 1000 //Find elapsed time and convert to milliseconds } - - requestObserver.newRequestArrived(currentRequest) + + if let request = currentRequest { + requestObserver.newRequestArrived(request) + } session?.invalidateAndCancel() } @@ -68,7 +72,7 @@ public class NetworkLoggerUrlProtocol: URLProtocol { /// The receiver will have either an HTTP body or an HTTP body stream only one may be set for a request. /// A HTTP body stream is preserved when copying an NSURLRequest object, /// but is lost when a request is archived using the NSCoding protocol. -// return request.httpBody ?? request.httpBodyStream?.readfully() + // return request.httpBody ?? request.httpBodyStream?.readfully() return nil } @@ -80,7 +84,7 @@ public class NetworkLoggerUrlProtocol: URLProtocol { } extension NetworkLoggerUrlProtocol: URLSessionDataDelegate { - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) { client?.urlProtocol(self, didLoad: data) if currentRequest?.dataResponse == nil{ currentRequest?.dataResponse = data @@ -90,14 +94,14 @@ extension NetworkLoggerUrlProtocol: URLSessionDataDelegate { } } - public func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { + func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive response: URLResponse, completionHandler: @escaping (URLSession.ResponseDisposition) -> Void) { let policy = URLCache.StoragePolicy(rawValue: request.cachePolicy.rawValue) ?? .notAllowed client?.urlProtocol(self, didReceive: response, cacheStoragePolicy: policy) currentRequest?.initResponse(response: response) completionHandler(.allow) } - public func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { + func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) { if let error = error { currentRequest?.errorClientDescription = error.localizedDescription client?.urlProtocol(self, didFailWithError: error) @@ -106,18 +110,18 @@ extension NetworkLoggerUrlProtocol: URLSessionDataDelegate { } } - public func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { + func urlSession(_ session: URLSession, task: URLSessionTask, willPerformHTTPRedirection response: HTTPURLResponse, newRequest request: URLRequest, completionHandler: @escaping (URLRequest?) -> Void) { client?.urlProtocol(self, wasRedirectedTo: request, redirectResponse: response) completionHandler(request) } - public func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { + func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) { guard let error = error else { return } currentRequest?.errorClientDescription = error.localizedDescription client?.urlProtocol(self, didFailWithError: error) } - public func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { + func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) { let protectionSpace = challenge.protectionSpace let sender = challenge.sender @@ -131,7 +135,7 @@ extension NetworkLoggerUrlProtocol: URLSessionDataDelegate { } } - public func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { + func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) { client?.urlProtocolDidFinishLoading(self) } } diff --git a/Tests/NetShearsTests/XCTestManifests.swift b/Tests/NetShearsTests/XCTestManifests.swift index 3c11082..a00fb9a 100644 --- a/Tests/NetShearsTests/XCTestManifests.swift +++ b/Tests/NetShearsTests/XCTestManifests.swift @@ -1,7 +1,7 @@ import XCTest #if !canImport(ObjectiveC) -public func allTests() -> [XCTestCaseEntry] { +func allTests() -> [XCTestCaseEntry] { return [ testCase(NetShearsTests.allTests), ] From 6c5bf902f4901b7f00470ab6ed74c9983e271339 Mon Sep 17 00:00:00 2001 From: Ali Moazenzadeh Date: Tue, 23 Nov 2021 10:46:22 +0330 Subject: [PATCH 3/6] Make RequestBroadcast methods public --- Sources/NetShears/Observable/RequestBroadcast.swift | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/Sources/NetShears/Observable/RequestBroadcast.swift b/Sources/NetShears/Observable/RequestBroadcast.swift index 58af0a8..81b42a4 100644 --- a/Sources/NetShears/Observable/RequestBroadcast.swift +++ b/Sources/NetShears/Observable/RequestBroadcast.swift @@ -12,19 +12,19 @@ public protocol RequestBroadcastDelegate: AnyObject { } public final class RequestBroadcast: RequestObserverProtocol { - static let shared = RequestBroadcast() + static public let shared = RequestBroadcast() var delegate = ThreadSafe(nil) private init() {} - func setDelegate(_ newDelegate: RequestBroadcastDelegate) { + public func setDelegate(_ newDelegate: RequestBroadcastDelegate) { delegate.atomically { delegate in delegate = newDelegate } } - func removeDelegate() { + public func removeDelegate() { delegate.atomically { delegate in delegate = nil } From 3eb4995d0761384169a7737a82f2a2fac8188b25 Mon Sep 17 00:00:00 2001 From: Ali Moazenzadeh Date: Tue, 23 Nov 2021 10:53:31 +0330 Subject: [PATCH 4/6] Make needed apis public --- Sources/NetShears/NetworkInterceptorConfig.swift | 4 ++-- .../RequestModifier/RequestEvaluatorModifierEndpoint.swift | 2 +- .../RequestModifier/RequestEvaluatorModifierHeader.swift | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/Sources/NetShears/NetworkInterceptorConfig.swift b/Sources/NetShears/NetworkInterceptorConfig.swift index dc4368b..29ede26 100644 --- a/Sources/NetShears/NetworkInterceptorConfig.swift +++ b/Sources/NetShears/NetworkInterceptorConfig.swift @@ -7,7 +7,7 @@ import Foundation -struct RedirectedRequestModel: Codable, Equatable { +public struct RedirectedRequestModel: Codable, Equatable { let originalUrl: String let redirectUrl: String @@ -17,7 +17,7 @@ struct RedirectedRequestModel: Codable, Equatable { } } -struct HeaderModifyModel: Codable, Equatable { +public struct HeaderModifyModel: Codable, Equatable { let key: String let value: String diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift index a217caa..8c9191d 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift @@ -7,7 +7,7 @@ import Foundation -struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable, Codable { +public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable, Codable { var redirectedRequest: RedirectedRequestModel diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift index 53dc70e..9169b5d 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift @@ -7,7 +7,7 @@ import Foundation -struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable, Codable { +public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable, Codable { var header: HeaderModifyModel From 2e559d360608730af3be14cdad970447c0ac6068 Mon Sep 17 00:00:00 2001 From: Ali Moazenzadeh Date: Tue, 23 Nov 2021 10:55:42 +0330 Subject: [PATCH 5/6] Fix build errors --- .../RequestModifier/RequestEvaluatorModifierEndpoint.swift | 6 +++--- .../RequestModifier/RequestEvaluatorModifierHeader.swift | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift index 8c9191d..3f23669 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift @@ -11,7 +11,7 @@ public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equata var redirectedRequest: RedirectedRequestModel - static var storeFileName: String { + public static var storeFileName: String { "Modifier.txt" } @@ -19,14 +19,14 @@ public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equata self.redirectedRequest = redirectedRequest } - func modify(request: inout URLRequest) { + public func modify(request: inout URLRequest) { if isRequestRedirectable(urlRequest: request) { request.modifyURLRequestEndpoint(redirectUrl: redirectedRequest) } } - func isActionAllowed(urlRequest: URLRequest) -> Bool { + public func isActionAllowed(urlRequest: URLRequest) -> Bool { return isRequestRedirectable(urlRequest: urlRequest) } diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift index 9169b5d..492113a 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift @@ -11,7 +11,7 @@ public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatabl var header: HeaderModifyModel - static var storeFileName: String { + public static var storeFileName: String { "Header.txt" } @@ -19,11 +19,11 @@ public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatabl self.header = header } - func modify(request: inout URLRequest) { + public func modify(request: inout URLRequest) { request.modifyURLRequestHeader(header: header) } - func isActionAllowed(urlRequest: URLRequest) -> Bool { + public func isActionAllowed(urlRequest: URLRequest) -> Bool { return true } } From 8c0cd5f54200b8a1c1c411c6c82f3b65b610e68d Mon Sep 17 00:00:00 2001 From: Ali Moazenzadeh Date: Tue, 23 Nov 2021 11:01:43 +0330 Subject: [PATCH 6/6] Make some apis public --- Sources/NetShears/NetworkInterceptorConfig.swift | 12 ++++++------ .../RequestEvaluatorModifierEndpoint.swift | 4 ++-- .../RequestEvaluatorModifierHeader.swift | 4 ++-- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/Sources/NetShears/NetworkInterceptorConfig.swift b/Sources/NetShears/NetworkInterceptorConfig.swift index 29ede26..01f492c 100644 --- a/Sources/NetShears/NetworkInterceptorConfig.swift +++ b/Sources/NetShears/NetworkInterceptorConfig.swift @@ -8,20 +8,20 @@ import Foundation public struct RedirectedRequestModel: Codable, Equatable { - let originalUrl: String - let redirectUrl: String + public let originalUrl: String + public let redirectUrl: String - init (originalUrl: String, redirectUrl: String) { + public init(originalUrl: String, redirectUrl: String) { self.originalUrl = originalUrl self.redirectUrl = redirectUrl } } public struct HeaderModifyModel: Codable, Equatable { - let key: String - let value: String + public let key: String + public let value: String - init (key: String, value: String) { + public init(key: String, value: String) { self.key = key self.value = value } diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift index 3f23669..f6616c4 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierEndpoint.swift @@ -9,13 +9,13 @@ import Foundation public struct RequestEvaluatorModifierEndpoint: RequestEvaluatorModifier, Equatable, Codable { - var redirectedRequest: RedirectedRequestModel + public var redirectedRequest: RedirectedRequestModel public static var storeFileName: String { "Modifier.txt" } - init(redirectedRequest: RedirectedRequestModel) { + public init(redirectedRequest: RedirectedRequestModel) { self.redirectedRequest = redirectedRequest } diff --git a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift index 492113a..a5f3239 100644 --- a/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift +++ b/Sources/NetShears/RequestModifier/RequestEvaluatorModifierHeader.swift @@ -9,13 +9,13 @@ import Foundation public struct RequestEvaluatorModifierHeader: RequestEvaluatorModifier, Equatable, Codable { - var header: HeaderModifyModel + public var header: HeaderModifyModel public static var storeFileName: String { "Header.txt" } - init(header: HeaderModifyModel) { + public init(header: HeaderModifyModel) { self.header = header }