Created a C library for dealing with multipart form handling. It's very minimal but is going to be useful when I need to deal with embedded systems occasionally with lack of memory or requirement to reduce complexity.


To give it a shot head to https://github.com/mofosyne/minimal-multipart-form-data-parser-c

The interface will be quite simple, like below

int c;
static MinimalMultipartParserContext state = {0};
while ((c = getc(stdin)) != EOF)
{
    // Processor handles incoming stream character by character
    const MultipartParserEvent event = minimal_multipart_parser_process(&state, (char)c);

    // Handle Special Events
    if (event == MultipartParserEvent_DataBufferAvailable)
    {
        // Data Available To Receive
        for (unsigned int j = 0; j < minimal_multipart_parser_get_data_size(&state); j++)
        {
            const char rx = minimal_multipart_parser_get_data_buffer(&state)[j];
            // Output received data
            putc(rx, stdout);
        }
    }
    else if (event == MultipartParserEvent_DataStreamCompleted)
    {
        // Data Stream Finished
        break;
    }
}

// Check if file has been received
if (minimal_multipart_parser_is_file_received(&state))
{
    // File Received Successfully
}
else
{
    // File Reception Failed
}

But I think what would be more interesting to other readers here is other alternatives to consider if they want to solve this issue of multipart form data extraction.

Did a bit of research and these are what I found:

  • fremouw/multipart

    • Does not appear to use malloc
    • Need all post data upfront, the multipart_post_t struct only contains pointers to the original data; not delimited with \0.
    • Parses name, filename and content type
    • Intended for ESP8266 using ESP8266_RTOS_SDK
    • Project considered complete according to Fremouw
  • iafonov/multipart-parser-c

    • Uses malloc
    • Uses callback functions on each data reception
    • You need to parse Content-Type from the response head yourself to get the boundary
      • This is because the init function of that implementation requires it.
      • Ours simply assumes that the first line of this form \r\n--BOUNDARY\r\n is the boundary which is a safe assumption to make
  • francoiscolas/multipart-parser

    • Does not appear to use malloc
    • Uses callback functions on each data reception
    • Validates and throws an error if not of the exact form. Ours doesn't not for code size consideration.
    • You need to parse Content-Type from the response head yourself to get the boundary
      • This is because the init function of that implementation requires it.
      • Ours simply assumes that the first line of this form \r\n--BOUNDARY\r\n is the boundary which is a safe assumption to make
  • abiiranathan/libmultipart

    • Uses malloc
    • Assumes you have already stored the whole request body in memory, ours will process the http request byte by byte.
    • But has extra features and validation for processing filenames, mimetype, etc...