swift - Vapor HTTPClient 跟随重定向

标签 swift vapor

我不知道如何跟踪来自外部 URL 的重定向。我正在访问的 URL 出于某种原因给了我 301,即使我没有在 postman 中得到它。我想知道如何让 HTTPClient 遵循重定向,或者我是否为了获得 301 而做错了什么。

我读过 this PR ,但我认为它不再相关了。 HTTPClient documentation 也没有覆盖重定向。 在下面的示例中,我将 User-Agent 设置为与 Postman 相同,以尽可能模仿 Postman 的请求。

到目前为止我的代码:

import Vapor
import HTTP

protocol DataFetching {
  func getFromURL(_ url: URL, on worker: Worker) throws -> Future<HTTPResponse>
}

class DataFetcher: DataFetching {

  enum Error: Swift.Error {
    case unknown
  }

  func getFromURL(_ url: URL, on worker: Worker) throws -> Future<HTTPResponse> {

    guard let host = url.host else { throw Error.unknown }

    var headers = HTTPHeaders()
    headers.replaceOrAdd(name: .userAgent, value: "PostmanRuntime/7.4.0")
    headers.replaceOrAdd(name: .accept, value: "*/*")
    headers.replaceOrAdd(name: .cacheControl, value: "no-cache")
    headers.replaceOrAdd(name: .applyToRedirectRef, value: "true")
    headers.replaceOrAdd(name: .acceptEncoding, value: "gzip, deflate")

    let httpRequest = HTTPRequest(method: .GET, url: url, version: HTTPVersion(major: 1, minor: 1), headers: headers)

    return HTTPClient.connect(hostname: host, on: worker).flatMap { client in
      return client.send(httpRequest)
    }
  }
}

我错过了什么?

最佳答案

我最终改用了 URLSession。这是我的最终结果,对我来说效果很好:

enum DataFetcherErrors: Error {
  case didNotRecieveData
  case unknown
}

protocol DataFetching {
  func getFromURL(_ url: URL, on worker: Worker) throws -> Future<Data>
}

class DataFetcher: DataFetching {

  let urlSession: URLSession
  private var headers = [
    "Accept": "*/*",
    "User-Agent": "DataFetcher",
    "Cache-Control": "no-cache",
    "Accept-Encoding": "gzip, deflate"
  ]

  init(urlSession: URLSession = .shared) {
    self.urlSession = urlSession
  }

  func getFromURL(_ url: URL, on worker: Worker) throws -> Future<Data> {
    let promise = worker.eventLoop.newPromise(Data.self)

    request(url: url) { (data, response, error) in
      if let error = error {
        promise.fail(error: error)
      }

      guard let data = data else {
        promise.fail(error: DataFetcherErrors.didNotRecieveData)
        return
      }

      promise.succeed(result: data)
    }

    return promise.futureResult
  }
}

private extension DataFetcher {

  func request(url: URL, completionHandler: @escaping ((Data?, URLResponse?, Error?) -> Void)) {
    var request = URLRequest(url: url)
    request.httpMethod = "GET"

    headers.forEach { fieldName, value in
      request.setValue(value, forHTTPHeaderField: fieldName)
    }

    let task = urlSession.dataTask(with: request, completionHandler: completionHandler)
    task.resume()
  }
}

关于swift - Vapor HTTPClient 跟随重定向,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/54099982/

相关文章:

ios - firebase/存储/图像/ View

swift - 如何使用 Vapor 上传/下载图像?

swift - 在 vapor 3 中创建父子关系

swift - 将 NSDateComponents 传递给 UILocalNotification 的最佳实践?

ios - 如何检查 Firebase 权限是否被拒绝?

xcode - 带有 XCode 6 Beta 7 的 Swift 在注册通知方面有问题

ios - 导航栏下方添加 "static"搜索栏

swift - 如何将 int 变量分配给请求参数?

ios - 服务器端 swift Vapor - 重新定义模块错误

Swift Vapor 3 从另一个路由器内部调用路由器