2

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?

12
  • 3
    Postman and Wireshark are your best friends for such problems. Commented Dec 7, 2020 at 10:45
  • 1
    Check this answer on how to find out what your browser sends to the server: stackoverflow.com/a/26791188/2527795 Commented Dec 7, 2020 at 10:47
  • 3
    Where is the actual c++ part within your question/code snippets? Did I miss something fundamental here? Commented Dec 7, 2020 at 10:47
  • 1
    Look at what the request sent from the browser and from your c++ program looks like, and check what is different. Commented Dec 7, 2020 at 10:50
  • 1
    You can use curl with --trace - to see exactly what it sends and compare that to what your program is sending. Commented Dec 7, 2020 at 10:51

1 Answer 1

1

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.

Sign up to request clarification or add additional context in comments.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.