Skip to content

Commit

Permalink
Revert "Update NetwrokListenerUrlProtocol.swift"
Browse files Browse the repository at this point in the history
This reverts commit 7f82df1.
  • Loading branch information
ialimz committed Jun 16, 2024
1 parent 7f82df1 commit 0825c2d
Show file tree
Hide file tree
Showing 5 changed files with 193 additions and 5 deletions.
19 changes: 17 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,12 +20,17 @@ NetShears adds a Request interceptor mechanisms to be able to modify the HTTP/HT

NetShears has three main functionality :

1 - Request interceptor mechanisms to be able to modify the HTTP/HTTPS Request before being sent.
1 - Network request observer which can be used to observe every HTTP/HTTPS request using delegation.
```swift
Netshears.shared.startListener()
```

2 - Request interceptor mechanisms to be able to modify the HTTP/HTTPS Request before being sent.
```swift
Netshears.shared.startInterceptor()
```

2 - Show network traffics.
3 - Show network traffics.
```swift
Netshears.shared.startLogger()
```
Expand Down Expand Up @@ -131,6 +136,16 @@ NetShears.shared.ignore = .enabled(ignoreHandler: { request in
Note that requests will be ignored **just** in Traffic Monitoring View; so you can set another ```ignoreHandler``` and get different results.
By default ```NetShears.ignore``` is ```.disabled```.

# Request Observer

For observing requests you need to first call startListener then just simply adopt RequestBroadcast <RequestBroadcastDelegate> delegate.
```swift
NetShears.shared.startListener()

RequestBroadcast.shared.setDelegate(self)

```

## Installation

### [Swift Package Manager](https://github.com/apple/swift-package-manager)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,12 +14,14 @@ extension URLSessionConfiguration {
return []
}
var originalProtocolClasses = fakeProcotolClasses.filter {
return $0 != NetworkInterceptorUrlProtocol.self && $0 != NetworkLoggerUrlProtocol.self
return $0 != NetworkInterceptorUrlProtocol.self && $0 != NetworkLoggerUrlProtocol.self && $0 != NetwrokListenerUrlProtocol.self
}
if NetShears.shared.loggerEnable {
originalProtocolClasses.insert(NetworkLoggerUrlProtocol.self, at: 0)
}

if NetShears.shared.listenerEnable {
originalProtocolClasses.insert(NetwrokListenerUrlProtocol.self, at: 0)
}
if NetShears.shared.interceptorEnable {
originalProtocolClasses.insert(NetworkInterceptorUrlProtocol.self, at: 0)
}
Expand Down
15 changes: 14 additions & 1 deletion Sources/NetShears/NetShears.swift
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,7 @@ public final class NetShears: NSObject {

internal var loggerEnable = false
internal var interceptorEnable = false
internal var listenerEnable = false
internal var swizzled = false
let networkRequestInterceptor = NetworkRequestInterceptor()

Expand Down Expand Up @@ -65,6 +66,16 @@ public final class NetShears: NSObject {
self.networkRequestInterceptor.stopLogger()
checkSwizzling()
}

public func startListener() {
self.networkRequestInterceptor.startListener()
checkSwizzling()
}

public func stopListener() {
self.networkRequestInterceptor.stopListener()
checkSwizzling()
}

public func modify(modifier: Modifier) {
config.addModifier(modifier: modifier)
Expand Down Expand Up @@ -120,7 +131,9 @@ public final class NetShears: NSObject {
RequestStorage.shared.newRequestArrived(request)
}

RequestBroadcast.shared.newRequestArrived(request)
if listenerEnable {
RequestBroadcast.shared.newRequestArrived(request)
}
}

public func addGRPC(url: String,
Expand Down
10 changes: 10 additions & 0 deletions Sources/NetShears/NetworkRequestInterceptor.swift
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,16 @@ import Foundation
NetShears.shared.loggerEnable = false
URLProtocol.unregisterClass(NetworkLoggerUrlProtocol.self)
}

func startListener() {
NetShears.shared.listenerEnable = true
URLProtocol.registerClass(NetwrokListenerUrlProtocol.self)
}

func stopListener() {
NetShears.shared.listenerEnable = false
URLProtocol.unregisterClass(NetwrokListenerUrlProtocol.self)
}
}


148 changes: 148 additions & 0 deletions Sources/NetShears/URLProtocol/NetwrokListenerUrlProtocol.swift
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
//
// NetwrokListenerUrlProtocol.swift
// NetShears
//
// Created by Mehdi Mirzaie on 6/9/21.
//

import Foundation

class NetwrokListenerUrlProtocol: URLProtocol {

struct Constants {
static let RequestHandledKey = "NetworkListenerUrlProtocol"
}

var session: URLSession?
var sessionTask: URLSessionDataTask?
var currentRequest: NetShearsRequestModel?
lazy var requestObserver: RequestObserverProtocol = {
RequestObserver(options: [
RequestBroadcast.shared
])
}()

override init(request: URLRequest, cachedResponse: CachedURLResponse?, client: URLProtocolClient?) {
super.init(request: request, cachedResponse: cachedResponse, client: client)

if session == nil {
session = URLSession(configuration: .default, delegate: self, delegateQueue: nil)
}
}

override class func canInit(with request: URLRequest) -> Bool {

if NetwrokListenerUrlProtocol.property(forKey: Constants.RequestHandledKey, in: request) != nil {
return false
}
return true
}

override class func canonicalRequest(for request: URLRequest) -> URLRequest {
return request
}

override func startLoading() {
let newRequest = ((request as NSURLRequest).mutableCopy() as? NSMutableURLRequest)!
NetwrokListenerUrlProtocol.setProperty(true, forKey: Constants.RequestHandledKey, in: newRequest)
sessionTask = session?.dataTask(with: newRequest as URLRequest)
sessionTask?.resume()

currentRequest = NetShearsRequestModel(request: newRequest, session: session)
if let request = currentRequest {
requestObserver.newRequestArrived(request)
}
}

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
}
currentRequest?.isFinished = true

if let request = currentRequest {
requestObserver.newRequestArrived(request)
}
session?.invalidateAndCancel()
}

private func body(from request: URLRequest) -> Data? {
/// 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.getHttpBodyStreamData()
}

deinit {
session = nil
sessionTask = nil
currentRequest = nil
}
}

extension NetwrokListenerUrlProtocol: URLSessionDataDelegate {
func urlSession(_ session: URLSession, dataTask: URLSessionDataTask, didReceive data: Data) {
client?.urlProtocol(self, didLoad: data)
if currentRequest?.dataResponse == nil{
currentRequest?.dataResponse = data
}
else{
currentRequest?.dataResponse?.append(data)
}
}

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

func urlSession(_ session: URLSession, task: URLSessionTask, didCompleteWithError error: Error?) {
if let error = error {
currentRequest?.errorClientDescription = error.localizedDescription
client?.urlProtocol(self, didFailWithError: error)
} else {
client?.urlProtocolDidFinishLoading(self)
}
}

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

func urlSession(_ session: URLSession, didBecomeInvalidWithError error: Error?) {
guard let error = error else { return }
currentRequest?.errorClientDescription = error.localizedDescription
client?.urlProtocol(self, didFailWithError: error)
}

func urlSession(_ session: URLSession, didReceive challenge: URLAuthenticationChallenge, completionHandler: @escaping (URLSession.AuthChallengeDisposition, URLCredential?) -> Void) {
let protectionSpace = challenge.protectionSpace
let sender = challenge.sender

if protectionSpace.authenticationMethod == NSURLAuthenticationMethodServerTrust {
if let serverTrust = protectionSpace.serverTrust {
let credential = URLCredential(trust: serverTrust)
sender?.use(credential, for: challenge)
completionHandler(.useCredential, credential)
return
}
}
}

func urlSessionDidFinishEvents(forBackgroundURLSession session: URLSession) {
client?.urlProtocolDidFinishLoading(self)
}

func urlSession(_ session: URLSession, task: URLSessionTask, didSendBodyData bytesSent: Int64, totalBytesSent: Int64, totalBytesExpectedToSend: Int64) {
if let url = task.currentRequest?.url {
NetShears.shared.taskProgressDelegate?.task(url, didRecieveProgress: task.progress)
}
}
}


0 comments on commit 0825c2d

Please sign in to comment.