microsoft / cpprestsdk

The C++ REST SDK is a Microsoft project for cloud-based client-server communication in native code using a modern asynchronous C++ API design. This project aims to help C++ developers connect to and interact with services.
Other
8.02k stars 1.66k forks source link

Broken multipart body #1762

Open Chrys4lisfag opened 1 year ago

Chrys4lisfag commented 1 year ago

I am trying to upload files to restsdk http server in multipart payload. When I check received buffer I see modified payload.

Sending using cpr library

cpr::File config1{"test.exe"};
cpr::File config2{"config2.json"};

cpr::Multipart mult{{"test.exe", config1}, { "config2.json", config2 }};

const cpr::Url uri = std::string( "http://127.0.0.1:8181" ) + "/upload_scripts_config";

cpr::PostCallback( []( const cpr::Response& r )
{
    ...
}, uri, mult );

Recv on server

pplx::task<void> handle_upload_scripts_config( web::http::http_request req )
    {
        try
        {
            Concurrency::streams::container_buffer<std::vector<uint8_t>> buffer;
            req.body().read_to_end( buffer ).get();

            std::ofstream f( "bin.bin");
            f.write( (char*)buffer.collection().data(), buffer.collection().size());

         ...   
        }
        ...
    }

Lets compare text.exe hex bytes to received payload (the part from MZ header start) Received - Left. Original - Right

BCompare_kvbojQJk5V

As we see, all the \r (Carriage Return) symbols are removed in recv buffer.

I tested the same thing with resinio lib and I get valid buffer

router->http_post( "/upload_scripts_config", []( restinio::request_handle_t req, auto )
{
const auto body = req->body();

std::ofstream file_stream( "bin.bin", std::ios::binary);
file_stream.write( body.data(), body.size());

return req->create_response().connection_close().done();
} );

How should I deal with it?