Padalingam
Padalingam

Reputation: 149

URlRequest.httpBody is nil inside startLoading() Method of URLProtocol in swift 3.0

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

Answers (1)

dgatwood
dgatwood

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

Related Questions