iOS拦截我应用的所有网络流量?

时间:2017-02-08 23:29:33

标签: ios networking proxy

我想为来自我的应用的所有网络电话添加代理。像

这样的东西
func intercept(request: URLRequest) {
  if isOk(request) {
    return // the request continues as normally
  } else if isIntercepted(request) {
    let res = HTTPURLResponse(url: url, statusCode: 200, httpVersion: "HTTP/2", headerFields: ["Content-Type": "application/json"])
    res.value = "{\"ok\":true}" // not that exactly work, but you get the idea
    request.end(res)
  } else {
    let res = HTTPURLResponse(url: url, statusCode: 401, httpVersion: "HTTP/2")
    res.value = "forbidden"
    request.end(res)
  }
}

我希望它适用于来自我的应用的所有来电。即我的代码和我正在使用的所有库和框架。可能吗?

我发现了有关阅读其他应用程序流量(不可能)的问题,并设置了从我的代码开始调用的代理人。我想进一步讨论1)会自动应用于所有流量的事情; 2)包括来自第三方的流量

1 个答案:

答案 0 :(得分:7)

这是URLProtocol班的工作。

来自Apple的文档:

  

NSURLProtocol对象处理特定于协议的URL的加载   数据。 NSURLProtocol类本身就是一个抽象类   提供使用特定URL处理URL的基础结构   方案。您可以为任何自定义协议或URL方案创建子类   您的应用支持。

您需要实现自己的URLProtocol子类并将其注册到应用程序以供其使用。此后,从应用程序初始化的所有连接都将使用该协议,您将能够处理/阻止您想要的任何请求。

func application(_ application: UIApplication, didFinishLaunchingWithOptions launchOptions: [UIApplicationLaunchOptionsKey: Any]?) -> Bool
{
    guard URLProtocol.registerClass(MyURLProtocol.self) else
    {
        abort()
    }

    return true
}

另外,如果你正在使用URLSession(你应该!),那么你还必须通过会话配置注册你的课程:

func getURLSessionConfiguration() -> URLSessionConfiguration
{
    let configuration = URLSessionConfiguration.default

    configuration.protocolClasses = [
        MyURLProtocol.self
    ]

    return configuration
}

let session = URLSession(configuration: getURLSessionConfiguration())

然后,您可以通过startLoading()子类的URLProtocol方法管理要阻止的内容:

override func startLoading()
{
    if !self.isOK()
    {
        let error = NSError(domain: "GuardURLProtocol", code: 10, userInfo: [NSLocalizedDescriptionKey: "Connection denied by guard"])
        self.client?.urlProtocol(self, didFailWithError: error)
    }
    else if let task = self.task
    {
        task.resume()
    }
}

您需要实施更多方法,并且应阅读documentation from Apple

但是作为一个小发明(和我自己的运动),I have written a generic blocker protocol,你应该检查一下它是如何工作的。在GuardURLProtocol.swift文件的底部有一个示例子类(BlockFPTURLSession),其中所有FTP请求都被模式阻止。

如果您使用我上面链接的类,并尝试打开FTP连接,您将看到以下错误:

2017-02-16 23:09:45.846 URLProtocol[83111:7456862] Error: Error Domain=GuardURLProtocol Code=10 "Connection denied by guard" UserInfo={NSLocalizedDescription=Connection denied by guard}

玩得开心!