Alamofire: Request Never Returns with Empty Body

Created on 6 Oct 2016  ·  2Comments  ·  Source: Alamofire/Alamofire

When making a request that only has header info and an empty body, the request never returns.

Here is a test case, that always times out:

    func testThatShowsSuccessHeadAlwaysTimesOut() {
        let asyncExpectation = expectation(description: "Wait for response")
        Alamofire.request("http://httpbin.org/status/200").responseJSON { response in
            switch response.result {
            case .success:
                asyncExpectation.fulfill()
            case .failure(_):
                XCTFail("The call returned a failure")
            }
        }
        waitForExpectations(timeout: 20)
    }

Using curl 'curl -I http://httpbin.org/status/200', the header reports 'Content-Length: 0'.

If I change to a status of 204 (no content), the test passes.

Alamofire Version: I am using head of master.

question response serializer

Most helpful comment

Hi @gerrypower,

@hardikdevios is right. You can't use a responseJSON serializer with that status API because it doesn't return any data. When you do, you'll always get an Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength as @hardikdevios has already pointed out.

The reason your test times out is because you don't have a asyncExpectation.fulfill() in your failure case. That causes both the XCTFail to fail as well as the timeout.

The reason the 204 status call works is that the responseJSON handler has logic to handle a 204 or 205 gracefully without failing. They are special HTTP status codes that do not return data so we have special logic in Alamofire to handle them in the default response handlers.

A better way to test this is the following:

func testThatShowsSuccessHeadDoesNotTimeOut() {
    let asyncExpectation = expectation(description: "Wait for response")

    Alamofire.request("http://httpbin.org/status/200").response { response in
        debugPrint(response)
        asyncExpectation.fulfill()
    }

    waitForExpectations(timeout: 20)
}

In summary, if you don't fulfill your expectation in ALL cases, you'll always time out. Also, you can't use the default response handlers without receiving an error with no data unless you get back a 204 or 205.

Cheers. 🍻

All 2 comments

In My Case it Returns and displayed error

▿ FAILURE: responseSerializationFailed(Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength)
▿ failure : AFError
- responseSerializationFailed : Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength

Which i case its perfect because it doesn't content any Body.

Hi @gerrypower,

@hardikdevios is right. You can't use a responseJSON serializer with that status API because it doesn't return any data. When you do, you'll always get an Alamofire.AFError.ResponseSerializationFailureReason.inputDataNilOrZeroLength as @hardikdevios has already pointed out.

The reason your test times out is because you don't have a asyncExpectation.fulfill() in your failure case. That causes both the XCTFail to fail as well as the timeout.

The reason the 204 status call works is that the responseJSON handler has logic to handle a 204 or 205 gracefully without failing. They are special HTTP status codes that do not return data so we have special logic in Alamofire to handle them in the default response handlers.

A better way to test this is the following:

func testThatShowsSuccessHeadDoesNotTimeOut() {
    let asyncExpectation = expectation(description: "Wait for response")

    Alamofire.request("http://httpbin.org/status/200").response { response in
        debugPrint(response)
        asyncExpectation.fulfill()
    }

    waitForExpectations(timeout: 20)
}

In summary, if you don't fulfill your expectation in ALL cases, you'll always time out. Also, you can't use the default response handlers without receiving an error with no data unless you get back a 204 or 205.

Cheers. 🍻

Was this page helpful?
0 / 5 - 0 ratings

Related issues

zhouhao27 picture zhouhao27  ·  3Comments

Tulleb picture Tulleb  ·  3Comments

yamifr07 picture yamifr07  ·  3Comments

sarbogast picture sarbogast  ·  3Comments

solomon23 picture solomon23  ·  3Comments