cli icon indicating copy to clipboard operation
cli copied to clipboard

Support for Content-Type on each part of a multi-part form

Open bowlofeggs opened this issue 4 years ago • 3 comments

Checklist

  • [X] I've searched for similar feature requests.

What enhancement would you like to see?

I would like to be able to do the equivalent of this curl command:

$ curl -v -X PUT https://example.com/ -F "metadata={some: data};type=application/json" -F "file1=@some/file.binary;type=application/octet-stream"

Using curl's --trace-ascii feature, the above results in something like this:

0000: PUT / HTTP/1.1
001e: Host: example.org
0034: User-Agent: curl/7.74.0
004d: Accept: */*
005a: Content-Length: 1014
0070: Content-Type: multipart/form-data; boundary=--------------------
00b0: ----b0115f32bd629a31
00c6: 
=> Send data, 1014 bytes (0x3f6)
0000: --------------------------b0115f32bd629a31
002c: Content-Disposition: form-data; name="metadata"
005d: Content-Type: application/json
007d: 
007f: {some: data}
008d: --------------------------b0115f32bd629a31
00b9: Content-Disposition: form-data; name="file1"; filename="file.binary"
00fb: Content-Type: application/octet-stream
0123: 
0125: Some bytes here
03c8: --------------------------b0115f32bd629a31--

I've attempted a few things with httpie, but I don't see a way to get the application/json component to come through on the other end. Is this possible?

What problem does it solve?

It allows each part of a multi-part form to have its own Content-Type.

bowlofeggs avatar Mar 30 '21 23:03 bowlofeggs

HTTPie supports this use case, but it only allows you to specify the type when you load the contents from a file (i.e., it doesn’t currently support specifying the type for string fields).

This would be the equivalent:

# Prepare files to upload:
$ echo json > /tmp/test.json
$ echo binary > /tmp/test.bin
# Make request:
$ http --offline --multipart PUT example.com \
    'metadata@/tmp/test.json;type=application/json'  \
    'file1@/tmp/test.bin;type=application/octet-stream'
PUT / HTTP/1.1
Accept: */*
Accept-Encoding: gzip, deflate
Connection: keep-alive
Content-Length: 340
Content-Type: multipart/form-data; boundary=eba2bec894024119814db278f9dd5da1
Host: example.com
User-Agent: HTTPie/2.4.0

--eba2bec894024119814db278f9dd5da1
Content-Disposition: form-data; name="metadata"; filename="test.json"
Content-Type: application/json

json

--eba2bec894024119814db278f9dd5da1
Content-Disposition: form-data; name="file1"; filename="test.bin"
Content-Type: application/octet-stream

binary

--eba2bec894024119814db278f9dd5da1--

jkbrzt avatar Mar 31 '21 14:03 jkbrzt

Oh interesting, I hadn't considered doing it that way. I think that's an acceptable way to do it, though it might be nice to have a way to do it as an inline argument on the CLI too.

Feel free to close this issue if you aren't interested in supporting it as an inline argument.

bowlofeggs avatar Mar 31 '21 18:03 bowlofeggs

I did realize that there is one way that using the file to upload the JSON is not quite equivalent to sending it the way curl does. It ends up including the filename, as you noted above. For my current purposes this is fine, but I thought I'd note that here just for completeness.

bowlofeggs avatar Apr 01 '21 21:04 bowlofeggs