Skip to content

Invalid state transition when reading an empty POST body. #149

Description

@sjoubert49

Describe the bug

The HTTP state machine does not correctly handle POST requests with an empty body (Content-Length: 0).

When such a request is received, the state remains stuck in HTTP_STATE_POST_RECV, even after calling httpRead() and never transitions to HTTP_POST_POST_SEND.

Expected behavior

For POST requests with an empty body, reading 0 bytes should be enough to transition from HTTP_POST_POST_RECV to HTTP_STATE_POST_SEND immediately.

Additional context

The issue is located in this section of the code: https://github.com/OpenPrinting/libcups/blob/master/cups/http.c#L1903

    } else if (http->data_remaining == 0 && http->data_encoding == HTTP_ENCODING_CHUNKED) {
        ...
    } else if (http->data_remaining <= 0) {
        // No more data to read...
        return (0);
    }

If data_encoding is HTTP_ENCODING_LENGTH then a remaining size of 0 means there is no data at all so the state shouldn't stay as RECV.

Temporary workaround

The issue can be bypassed by calling httpPeek() after finishing the read loop:

char buffer[254];
ssize_t bytes;

while ((bytes = httpRead(http, buffer, sizeof(buffer))) > 0) {
    // Body processing here
}

// Force the state machine to progress
httpPeek(http, buffer, sizeof(buffer));

While this is convenient as a workaround, this implies an additionnal caveat for the fix. If httpRead() correctly updates the state then calling

httpPeek(http, buffer, sizeof(buffer));
httpRead(http, buffer, sizeof(buffer));

would yield the expected result if the body contains data. But with an empty body, the state would first transition from POST_RECV to POST_SEND, then HTTP_STATE_STATUS in the call to httpRead() (all states except RECV transition to STATUS).

Metadata

Metadata

Assignees

Labels

Type

No type
No fields configured for issues without a type.

Projects

No projects

Relationships

None yet

Development

No branches or pull requests

Issue actions