Skip to content

http_client_sync example hangs on uploading ~2GB multipart data #2823

@ashjas

Description

@ashjas

Version of Beast
1.71 , but it does not matter, i tried with 1.81 with same behaviour.

OS: windows

When i try to upload 2GB of data using multipart form data , the testcase hangs although the data gets uploaded successfully as reported by the server.

Here is the reworked http_client_sync.cpp example tweaked to reproduce this.

int main(int argc, char** argv)
{
    try
    {
        // Check command line arguments.
        auto const target = "/some/upload/api";
        int version = 11;

        // The io_context is required for all I/O
        net::io_context ioc;

        // These objects perform our I/O
        tcp::resolver resolver(ioc);
        beast::tcp_stream stream(ioc);

        // Look up the domain name
        auto const results = resolver.resolve("127.0.0.1", "13537");

        // Make the connection on the IP address we get from a lookup
        stream.connect(results);
        
        // Set up an HTTP GET request message
        http::request<http::string_body> req{http::verb::put, target, version};

        //lambda to set the RestRequest fields...
        auto SetField = [&] (http::field f, std::string headerStr) {
            if(headerStr.size()) {
                req.set(f, headerStr);
            }
            else if(f == http::field::user_agent) {//Set user-agent as beast version if user provided none.
                req.set(f, BOOST_BEAST_VERSION_STRING);
            }
        };
        req.keep_alive(false);
        SetField(http::field::content_type, "multipart/form-data; boundary=ABC-Data");
        SetField(http::field::host, "127.0.0.1:13537");
        SetField(http::field::user_agent, BOOST_BEAST_VERSION_STRING);
        SetField(http::field::accept,           "*/*");

        //create the body:
        std::string body;
        //some logic to prepare the multipart data..
        prepare_multipart_data(body);//reads a file, and prepares the multipart data.
        //results in:
        /*
        --ABC-Data
        Content-Disposition: form-data; name="criteria"

        {"abc":"def"}
        --ABC-Data
        Content-Disposition: form-data; name="file"; filename="somefile"
        Content-Type: application/zip

        some random file data...
        --ABC-Data--
        */
        req.body() = body;
        req.prepare_payload();

        // Send the HTTP request to the remote host
        std::cout << req << std::endl;
        http::write(stream, req);

        // This buffer is used for reading and must be persisted
        beast::flat_buffer buffer;

        // Declare a container to hold the response
        http::response<http::dynamic_body> res;

        // Receive the HTTP response
        http::read(stream, buffer, res);

        // Write the message to standard out
        std::cout << res << std::endl;

        // Gracefully close the socket
        beast::error_code ec;
        stream.socket().shutdown(tcp::socket::shutdown_both, ec);

        // not_connected happens sometimes
        // so don't bother reporting it.
        //
        if(ec && ec != beast::errc::not_connected)
            throw beast::system_error{ec};

        // If we get here then the connection is closed gracefully
    }
    catch(std::exception const& e)
    {
        std::cerr << "Error: " << e.what() << std::endl;
        return EXIT_FAILURE;
    }
    return EXIT_SUCCESS;
}

Here is a sample req that gets generated and works for file sizes ~1.5GB, but fails for 2GB+ data.

PUT /some/upload/api HTTP/1.1
Connection: close
Content-Type: multipart/form-data; boundary=ABC-Data
Host: 127.0.0.1:13537
User-Agent: Boost.Beast/266
Accept: */*
Content-Length: 229

--ABC-Data
Content-Disposition: form-data; name="criteria"

{"abc":"def"}
--ABC-Data
Content-Disposition: form-data; name="file"; filename="somefile"
Content-Type: application/zip

some random file data...
--ABC-Data--

Any suggestions ?

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

Milestone

No milestone

Relationships

None yet

Development

No branches or pull requests

Issue actions