Skip to content

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

@sjoubert49

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

No one assigned

    Labels

    No labels
    No labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions