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.01k stars 1.66k forks source link

Large file upload end up with exception "Failed to read HTTP status line" #817

Open aksswami opened 6 years ago

aksswami commented 6 years ago

I am trying upload large file ranging from 10 MB to few GB and somehow request always end up with an exception while stream uploading large files. The exception I get is web::http::http_exception: Failed to read HTTP status line

I traced back the origin of exception and it's coming from handler to connection. (http_client_asio.cpp) And I am getting operation_aborted from asio for some reason. I have tried to debug it further but due to my limited knowledge didn't get any solution or root cause.

Also, the request seems to upload the full data in MB case but it fails to close successfully, not sure why.

Here is the sample code I am trying

auto task_stream = file_stream<uint8_t>::open_istream(file_name);
    task_stream.then([&file_name](concurrency::streams::istream stream)-> pplx::task<web::http::http_response> {
        web::http::client::http_client client(web::http::uri("http://someurl"));
        web::http::http_request request(web::http::methods::POST);
        request.headers().add(web::http::header_names::authorization, "Bearer XXX");

        stream.seek(0, std::ios::end);
        auto length = stream.tell();
        stream.seek(0, std::ios::beg);

        request.set_body(stream, length);  
        ucout << request.to_string() << std::endl;

        return client.request(request);
    }).then([](web::http::http_response response)
            -> web::json::value {
                if (response.status_code() == 201)
                {
                    printf("Success");
                }
                else
                {
                    printf("Nothing");
                }
                auto json_value = response.extract_json().get();
                return json_value;
            }).wait()

Any help would be really appreciated.

ashishsb95 commented 6 years ago

Try adding a config to your client web::http::client::http_client_config cfg; cfg.set_timeout(std::chrono::seconds(3600));

http_client client(U("http://127.0.0.1:10000"),cfg);

aksswami commented 6 years ago

I have already tried increasing the timeout. But I don't think this is the reason behind this error. Even if the request timed_out it should fail gracefully not in operation_aborted.

ashishsb95 commented 6 years ago

Try closing your stream in the response handler.

aksswami commented 6 years ago

How do you suggest to close the stream in response handler? For this, I have to somehow capture the stream variable in response lambda. And I don't know how to do that with consecutive then expressions.