Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

curl: Per-file Content-Type for multipart POST (YouTube API)

I'm trying to use curl to batch upload to YouTube, following the API spec here; in short, it requires a multipart POST request with metadata in XML format and Content-Type of application/atom+xml; charset=UTF-8, followed by the video data itself.

My current command line (fetching the metadata from upl.xml and the video from upl.mkv) looks something like this:

curl -s -F "[email protected]" -F "[email protected]" -H 'GData-Version: 2' -H 'Authorization: GoogleLogin auth=<AUTH>' -H 'Slug: upl.mkv' -H 'X-GData-Key: key=<KEY>' http://uploads.gdata.youtube.com/feeds/api/users/default/uploads 

When I check the actual request that's being sent with --trace, it looks as though both files are being sent in the correct order, but the Content-Type of the metadata is set to application/octet-stream; the upload completes as expected, but YouTube refuses to process the video.

If I try to submit upl.xml with --data, --data-ascii, --form-string etc. I just get an assortment of other errors, which leads me to believe it's down to the incorrect Content-Type. If I ignore the metadata and just send the video file it works fine, but unfortunately this doesn't solve my problem.

Am I missing something here, and if not is it possible to do this without breaking out libcurl?

like image 683
furq Avatar asked Nov 21 '12 00:11

furq


People also ask

How do I pass a multipart file in Curl?

With curl, you add each separate multipart with one -F (or --form ) flag and you then continue and add one -F for every input field in the form that you want to send. The above small example form has two parts, one named 'person' that is a plain text field and one named 'secret' that is a file.

How do I use Curl to post files?

To post a file with Curl, use the -d or -F command-line options and start the data with the @ symbol followed by the file name. To send multiple files, repeat the -F option several times.

How does Curl send form data?

To post form data with Curl, you can use one of two command-line parameters: -F (--form) or -d (--data). The -F command-line parameter sends form data with the multipart/form-data content type, and the -d command-line parameter sends form data with the application/x-www-form-urlencoded content type.

What is multipart form data in API?

Multipart/Form-Data is a popular format for REST APIs, since it can represent each key-value pair as a “part” with its own content type and disposition. Each part is separated by a specific boundary string, and we don't explicitly need Percent Encoding for their values.


1 Answers

First, you can specify the content-type for a part you upload by adding ";type=magic/string". Like for example in your video case:

curl -F "[email protected];type=video/mpeg4" [URL]

(use --trace or --trace-ascii to verify that curl sends exactly what you want it to)

... but this said, I'd guess that it is highly unlikely that the receiving server actually cares about what the client claims the content-type is. Meaning I think the source of your problem is actually not the content-type at all.

like image 135
Daniel Stenberg Avatar answered Oct 04 '22 08:10

Daniel Stenberg