Skip to content

Accept multipart-formdata without CRLF in the last line #1619

@mccare

Description

@mccare

Hi,

I'm sending multipart-formdata to a server that is using cpp-httplib internally. The problem I'm running into is, that cpp-httplib requires the last line of the request to end in a CRLF. But the client library I'm using (undici from node) does not send a CRLF after the last boundary of a multipart formdata POST request. cpp-httplib will respond with a 400 error. If I use curl or axios, it will work, since they both append a CRLF after the last boundary

Sample last boundary (accepted by cpp-httplib)

--------------------------da314b32b9ea03ee--\r\n

Sample last boundary (producing 400 by cpp-httplib)

--------------------------da314b32b9ea03ee--

I haven't found a 100% answer if a CRLF is required after the last line on a multipart-formdata request, my guess is it is not required (the spec says something about CRLF between body parts but nothing about the last line). Message body from HTTP is also not required to end in a CRLF.

I've tried adding a case for the boundary parsing where it checks for dash_ but it didn't really work out. Since my C++ knowledge is rather limited, happy to have some pointers here. Is cpp-httpd relying on CRLF ending in some other place, too?

Here what I tried:

      case 4: { // Boundary
        if (crlf_.size() > buf_size()) { return true; }
        if (buf_start_with(crlf_)) {
          buf_erase(crlf_.size());
          state_ = 1;
        } else {
          if (dash_crlf_.size() > buf_size()) { return true; }
          if (buf_start_with(dash_crlf_)) {
            buf_erase(dash_crlf_.size());
            is_valid_ = true;
            buf_erase(buf_size()); // Remove epilogue
          } else if (buf_start_with(dash_)) {
            // case where the last line will end in -- without a CRLF
            buf_erase(dash_.size());
            is_valid_ = true;
            buf_erase(buf_size()); // Remove epilogue
          } else {
            return true;
          }
        }
        break;

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions