How to upload file through HTTP protocol with C++?

942 views Asked by At

I'm going to upload files with C++, to a Java spring boot web server.

I constructed the protocol looks like below (in plain text):

POST /gallery/multimedia/uploadvideo HTTP/1.1
Host: 192.168.0.133:8981
Content-Type: multipart/form-data; boundary=------boundary1804289383
Connection: keep-alive

--------boundary1804289383
Content-Type: video/mp4
Content-Disposition: form-data; name="file"; filename="1.mp4"
Content-Length: 948611
Content-Transfer-Encoding: 8bit

... binary video data here ...

--------boundary1804289383--

The server side is Java spring boot server, interface defined as below:

@PostMapping("uploadvideo")
public ResultVo uploadVideo(@RequestParam("file") MultipartFile file);

While posting file, the server responses with code 400, and complains that

Required request part 'file' is not present

However with a simple HTML page, file uploaded successfully, the HTML page listed below:

<html>
    <head></head>
    <body>
        <form id="form" enctype="multipart/form-data" method="post" 
            action="http://192.168.0.133:8981/gallery/multimedia/uploadvideo">
            <input id="file" name="file" type="file" />
            <input id="submit" value="submit" type="submit" />
        </form>
    </body>
</html>

What do I miss?


Edit:

I've tried Postman/Chrome console/curl, all these tools only print the request looks like:

# this is from curl
POST /gallery/multimedia/uploadvideo HTTP/1.1
User-Agent: curl/7.29.0
Host: 192.168.0.133:8981
Accept: */*
Content-Length: 187
Expect: 100-continue
Content-Type: multipart/form-data; boundary=----------------------------3c653d03b97f

How should I construct the file part? Any ideas?

1

There are 1 answers

0
Ted Yu On BEST ANSWER

Firstly, thanks for @strupo 's suggestion.

By turning on --trace option of curl and viewing the output log file, I finally fixed this problem.

In curl, it posts file by several packets:

The header:

POST /gallery/multimedia/uploadvideo HTTP/1.1
User-Agent: curl/7.29.0
Host: 192.168.0.133:8981
Accept: */*
Content-Length: 13602  # you have to calculate content length first
Expect: 100-continue   # very important line
Content-Type: multipart/form-data; boundary=------3c653d03b97f

then it waits for server response:

HTTP/1.1 100

after server responsed code 100, it sends data content, the form-data header goes first:

--------3c653d03b97f
Content-Type: video/mp4
Content-Disposition: form-data; name="file"; filename="1.mp4"
Content-Length: 6640
Content-Transfer-Encoding: 8bit

and file content follows, (in my case, a large memory is allocated, read from file and write to socket in once), and next file.

Finally the protocol should finished with boundary line:

--------3c653d03b97f--

The Content-Length should include all bytes being sent after header. The boundary should be prefixed with -- in file part. Also the \r\n everywhere should be noticed.