How can I rewrite this CURL multipart/form-data request without using -F?

后端 未结 7 1461
无人共我
无人共我 2020-12-07 10:29

How can I rewrite the following CURL command, so that it doesn\'t use the -F option, but still generates the exact same HTTP request? i.e. so that it passes th

相关标签:
7条回答
  • 2020-12-07 10:58

    This is for multipart/form-data request method. for uploading a file add --form filename="@path/image.jpg;type=image/jpeg"

    curl --form key="value" --form key="value" http://localhost:3000/test

    0 讨论(0)
  • 2020-12-07 10:59

    Here it is how I would do it:

    curl https://httpbin.org/post \
        -H 'content-type: multipart/form-data; boundary=----FormBoundary123456789' \
        --data-binary $'------FormBoundary123456789\r
    Content-Disposition: form-data; name="example"\r
    \r
    test\r
    ------FormBoundary123456789--\r
    '
    

    Or a bit more sophisticated (should be portable to most modern shells):

    DELIM=----FormBoundary$RANDOM$RANDOM
    
    curl https://httpbin.org/post \
        -H "content-type: multipart/form-data; boundary=$DELIM" \
        --data-binary --$DELIM$'\r
    Content-Disposition: form-data; name="example"\r
    \r
    test\r
    '--$DELIM--$'\r
    '
    
    0 讨论(0)
  • 2020-12-07 11:12

    This is to upload one image file using "Content-Type: multipart/related",

    curl --trace trace.txt -X POST -H 'Content-Type: multipart/related; boundary=boundary_1234' --data-binary $'--boundary_1234\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n{\r\n\t"title": "TestFile"\r\n}\r\n\r\n--boundary_1234\r\nContent-Type: image/jpeg\r\n\r\n' --data-binary '@Image0177.jpg' --data-binary $'\r\n--boundary_1234--\r\n' 'http://localhost:3000/google/upload/drive/v2/files?uploadType=multipart'
    
    0 讨论(0)
  • 2020-12-07 11:16

    Here's an alternative answer with the original CURL statement re-written using -d as a one-liner, without temporary files. Personally I think the temporary files approach is easier to understand, but I'm putting this here for reference as well:

    curl -X POST -H "Content-Type: multipart/form-data; boundary=----------------------------4ebf00fbcf09" -d $'------------------------------4ebf00fbcf09\r\nContent-Disposition: form-data; name="example"\r\n\r\ntest\r\n------------------------------4ebf00fbcf09--\r\n' http://localhost:3000/test
    

    Notes: the $'blar' syntax is so that bash will parse the \r\n as a CRLF token. Thanks to this answer for that tip.

    0 讨论(0)
  • 2020-12-07 11:18

    This is what I'm using, I think it's clean and doesn't need temporary files nor gobbles up RAM in case you want to upload whole files (so no reading files into memory).

    # Set these two.
    file='path/to/yourfile.ext'
    url='http://endpoint.example.com/foo/bar'
    
    delim="-----MultipartDelimeter$$$RANDOM$RANDOM$RANDOM"
    nl=$'\r\n'
    mime="$(file -b --mime-type "$file")"
    
    # This is the "body" of the request.
    data() {
        # Also make sure to set the fields you need.
        printf %s "--$delim${nl}Content-Disposition: form-data; name=\"userfile\"${nl}Content-Type: $mime$nl$nl"
        cat "$file"
        printf %s "$nl--$delim--$nl"
    }
    
    # You can later grep this, or something.
    response="$(data | curl -# "$url" -H "content-type: multipart/form-data; boundary=$delim" --data-binary @-)"
    
    0 讨论(0)
  • 2020-12-07 11:24

    Solved:

    curl \
      -X POST \
      -H "Content-Type: multipart/form-data; boundary=----------------------------4ebf00fbcf09" \
      --data-binary @test.txt \
      http://localhost:3000/test
    

    Where test.txt contains the following text, and most importantly has CRLF (\r\n) line endings:

    ------------------------------4ebf00fbcf09
    Content-Disposition: form-data; name="example"
    
    test
    ------------------------------4ebf00fbcf09--
    

    Notes: it is important to use --data-binary instead of plain old -d as the former preserves the line endings (which are very important). Also, note that the boundary in the body starts with an extra --.

    I'm going to repeat it because it's so important, but that request-body file must have CRLF line endings. A multi-platform text editor with good line-ending support is jEdit (how to set the line endings in jEdit).

    If you're interested in how I worked this out (debugging with a Ruby on Rails app) and not just the final solution, I wrote up my debugging steps on my blog.

    0 讨论(0)
提交回复
热议问题