2017-06-22 105 views
0

拨打的电话这是我开始我更新的iOS 11(15A5304i)和Xcode的9(9M137d)之后的最新测试版的问题。状态码400:NSHTTPURLResponse使用URLSession.shared.dataTask

当我恢复到以前的测试,它消失了。

进行任何GET HTTPS调用从服务器400响应网站的结果。

networkError(FoodAPI.NetworkError.responseStatusError(status: 400, message: "<NSHTTPURLResponse: 0x1c4239700> { URL: https://stackoverflow.com/ } { status code: 400, headers {\n Date = \"Thu, 22 Jun 2017 17:41:03 GMT\";\n} }")) 

这就是我正在做的通话

func callTask(_ request: URLRequest, completion: @escaping (ResultType<Data, NetworkError>) -> Void) { 
    let task = URLSession.shared.dataTask(with: request) { data, response, error in 

    guard let response = response as? HTTPURLResponse else { 
     completion(.failure(.responseInvalidFormat)) 
     return 
    } 

    if response.statusCode >= 400 { 
     let error = response.description 
     completion(.failure(.responseStatusError(status: response.statusCode, message: error))) 
     return 
    } 

    guard let data = data else { 
     completion(.failure(.responseNoDataError)) 
     return 
    } 

    completion(.success(data)) 
    } 
    task.resume() 
} 

,这是该请求是如何产生的:

private func generateRequest(urlString: String, 
           method: HttpMethod = .get, 
           contentType: ContentType = .json, 
           headers: [String: String] = ["":""], 
           body: [String: Any]? = nil) throws -> URLRequest { 


    guard let url = URL(string: urlString) else { 
     throw NetworkError.requestGenerationFail(url: urlString, httpMethod: method) 
    } 
    var request = URLRequest(url: url) 
    request.httpMethod = method.rawValue 
    request.setValue("***** by Reza: info: [email protected]", forHTTPHeaderField: "User-Agent") 

    request.allHTTPHeaderFields = headers 
    if contentType == .urlEncoded && headers["content-type"] ?? "" != ContentType.urlEncoded.rawValue { 
     request.addValue(ContentType.urlEncoded.rawValue, forHTTPHeaderField: "content-type") 
    } 

    if let body = body { 
     request.httpBody = try self.generateBody(body: body, contentType: contentType) 
    } 

    return request 
    } 

同样,这个工作正常在以前的iOS测试版11 ,但是新的HTTP响应会给Web服务器带来400响应,几乎没有数据。

值得一提的是,我第一次作出这是对https://api.yelp.com/托管Yelp的端点API的调用。此连接成功,没有任何问题。到其他主机(https://stackoverflow.comhttps://www.yelp.com)任何进一步的调用回来了400

当我运行使用旧的测试版在模拟器中的代码,它工作正常,当我部署到我的iPhone 6是采用了全新的iOS它400个来自服务器。

我没有对我自己的服务器进行测试,所以我可以查看日志,但是沿途的一些事情正在破坏并导致服务器返回一个错误的请求响应。这些相同的调用使用curl,邮差,浏览器和以前的iOS版本都可以很好地工作。

我希望谁也面临着同样的问题可以提供一些线索的人。

+0

您是否使用两个测试版比较了原始请求(例如查尔斯,或仅仅是倾销数据)?这可能会告诉你什么是问题(param enconding?etc) – nathan

+0

@nts所有的通信都是加密的,所以我在Charles上看到的两个beta都是不可读的。有趣的是,调用http端点成功。 –

+0

自定义加密或只是HTTPS? – nathan

回答

1

我必须确定问题。虽然原因仍然难以捉摸。

generateRequest函数中,我传递了[String:String]的字典,其中请求标头的默认值为["":""]

看来request.allHTTPHeaderFields = ["":""]会打破您的请求。

在之前的版本中,这并没有引起任何问题,但是这会导致对当前测试版的错误请求。

更新

我充满了苹果的一个错误,当我第一次遇到了这个问题,这是他们的回应:

的问题是,在CFNetwork的-856.4.7(种子1的一部分)我们犯了一个错误,并删除了空白的标题。在种子2(CFNetwork-861.1)中,我们将要移除的头部限制为4个“特殊”头(Content-Type,User-Agent,Accept-Language,Accept-Encoding)。所以,这就是为什么你看到行为的变化。

macOS El Capitan还发送“=”标头,该标头产生400个HTTP状态码。所以,这在种子2中表现正确。种子1是一个异常,并且是错误的。

请通过更新错误报告告诉我们问题是否已解决。

+0

空字典为[:] not [“”:“”]。后者意味着您要添加两个空字符串作为键值 – nathan