Reputation: 149
I have my custom URLProtocol
, which is having some custom response generation. Now i have a requirement, where in i need send some information to server via httpBody (Can be json/String as data) before getting the actual response
My problem is, when i create urlRequest with httpBody, then fire the service by using URLSession
with some session configuration(That custom URLProtocol
is included here)
This will call first canInit -> canonical -> startLoading -> stopLoading, inside these all methods the request.httpBody is nil.
override func startLoading() {
let request = self.request
var response: HTTPURLResponse?
let hasResponse: Bool = true
if request.httpMethod == "GET" || request.httpMethod == "POST" {
guard let url = request.url else {
return
}
let client = self.client
let statusCode = 200
if url.absoluteString.contains("/good") {
print(self.request.httpBody) //here its nil
}
response = hasResponse ? HTTPURLResponse(url: request.url!, statusCode: statusCode, httpVersion: "HTTP/1.1", headerFields: cannedHeaders) : nil
client?.urlProtocol(self, didLoad: responseData)
client?.urlProtocol(self, didReceive: response!, cacheStoragePolicy: URLCache.StoragePolicy.notAllowed)
client?.urlProtocolDidFinishLoading(self)
}
}
func testCompressRequest() {
let expect = expectation(description: "testCompressRequest")
let urlRequest = URLRequest(url: URL(string:serverPath+"/good")!)
urlRequest.httpBody = "someMethodBodyasString".data(using: .utf8)
urlRequest.httpMethod = "POST"
urlRequest.allHTTPHeaderFields = ["Accept-Encoding": "gzip, deflate", "Content-Encoding":"gzip, deflate", "Content-Type":"application/json", "Accept":"application/json", "Content-Length":String(describing: urlRequest.httpBody?.count)]
let task = URLSession(configuration: sessionConfig).dataTask(with: urlRequest) { (data, response, error) in
expect.fulfill()
}
task.resume()
waitForExpectations(timeout: 10, handler: nil)
}
Upvotes: 3
Views: 1526
Reputation: 10407
By the time a protocol sees the request object, the body data object has already been standardized into a body stream object. Open the body stream and read the data from there instead.
Upvotes: 4