Upload video via cURL - php

I am trying to upload some video name test.avi to dailymotion..
I used cURL to login to dailymotion, and than I am trying to upload a video through this url http://www.dailymotion.com/widget/upload?skin=default
I scanned the requests when uploading some example video.. but it only gives me this:
Request URL
http://www.dailymotion.com/widget/upload?skin=default&upload_id=c73413240d828de0ce987018dddcb6ed&sid=5444350aa8f801e2605f8f6de15ac38c&urlbase=http://www.dailymotion.com&flash_mode=1
Query String Parameters
skin:default
upload_id:c73413240d828de0ce987018dddcb6ed
sid:5444350aa8f801e2605f8f6de15ac38c
urlbase:http://www.dailymotion.com
flash_mode:1
Request Payload
------------gL6Ef1gL6KM7gL6ei4Ef1Ij5ae0ei4
Content-Disposition: form-data; name="Filename"
test.avi
------------gL6Ef1gL6KM7gL6ei4Ef1Ij5ae0ei4
Content-Disposition: form-data; name="Filedata"; filename="test.avi"
Content-Type: application/octet-stream
------------gL6Ef1gL6KM7gL6ei4Ef1Ij5ae0ei4
Content-Disposition: form-data; name="Upload"
Submit Query
------------gL6Ef1gL6KM7gL6ei4Ef1Ij5ae0ei4--
However, I am not quite sure what to do with this Payload Request.. Can anybody help me with this ?

That's a multi-part formpost, indeed possible to do with curl and its -F command line option. Just provide one -F for each input field in the form.
Of course, you may also need to actually login etc with curl first, and then you may also need to track cookies etc. If that sounds complicated, you may want to start reading on the curl HTTP scripting page.

You can only use cURL to transfer files via FTP. If you're trying to upload a video to a web server using their web interface or an API or similiar than cURL is not your tool.

Related

Vimeo API : streaming upload using HTTP PUT and blueimp's jQuery fileupload

I'm trying to implement an upload module on a website which would allow our users to upload videos to our Vimeo account. I'm using blueimp's jQuery File upload and Vimeo's new API.
https://github.com/blueimp/jQuery-File-Upload/wiki/Options
https://developer.vimeo.com/api/upload#http-put-uploading
I think it's close to be working but I must be missing some detail.
According to Vimeo's API, I need to :
1. Generate an upload ticket, which works fine
2. I then pass the upload_link_secure to jquery file upload which starts uploading. This is what the requests headers for the PUT request look like :
Request Method:PUT
Status Code:200 OK
Accept:*/*
Accept-Encoding:gzip,deflate,sdch
Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
Connection:keep-alive
Content-Length:43418955
Content-Type:multipart/form-data; boundary=----WebKitFormBoundarye8sGy57JH6ACoOfJ
This is how I call jQuery file upload :
$('#file').fileupload({
url: upload_link_secure,
type: 'PUT'
});
I also tried forcing the Content-Type header to "video/mp4" but it doesn't make any difference in the end.
I also checked the size of the file by binding jquery fileupload's submit event and I also get a lower bytes count than what's sent in the headers, 43418764 in this example, is this okay ?
Verify the upload by sending PUT requests on upload_link_secure, some response headers I get :
Status Code:308 Resume Incomplete
Range:bytes=0-3948544
Status Code:308 Resume Incomplete
Range:bytes=0-38682624
Status Code:308 Resume Incomplete
Range:bytes=0-43401216
Make sure all the bytes made it to Vimeo, then complete the upload by sending a DELETE request on complete_uri
I get this last header when verifying the upload :
Range:bytes=0-43418955
It seems to match the Content-Length send in the first request so I perform a DELETE request, and this is the reponse I get :
{"body":{"error":"Your video file is not valid. Either you have uploaded an invalid file format, or your upload is incomplete. Make sure you verify your upload before marking it as complete."},"status":400,"headers":{"Date":"Mon, 06 Oct 2014 17","Server":"Apache","Vary":"Accept,Vimeo-Client-Id,Accept-Encoding","Cache-Control":"no-cache, max-age=315360000","Expires":"Thu, 03 Oct 2024 17","Content-Length":"184","X-Cnection":"close","Content-Type":"application/vnd.vimeo.error+json","Via":"1.1 dca1-10"}}
I must have made a very dumb mistake but I'm not very familiar with all those HTTP requests and reponses, does anybody know what I did wrong ?
Thanks !
[edit] Thanks a lot Dashron, I actually had to set jQuery fileupload's multipart option to false :
$('#file').fileupload({
url: upload_link_secure,
type: 'PUT',
multipart: false
});
After that, I was getting this HTTP error :
XMLHttpRequest cannot load https://1511632921.cloud.vimeo.com/upload?[...]. Request header field Content-Disposition is not allowed by Access-Control-Allow-Headers.
There might be a clean fix for that but I didn't find it so I simply commented the lines that set the Content-Disposition header in jquery.fileupload.js
// if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
// options.headers['Content-Disposition'] = 'attachment; filename="' +
// encodeURI(file.name) + '"';
// }
(see edit3)
Now it works fine ! :)
[edit2] I was asked for a more complete example of the code I came up with to make that PUT upload work so here is a Gist containing the relevant Twig template from my Symfony application. I hope it's clear enough and that it can help. The code can probably be improved a lot but I guess it's an okay starting point. https://gist.github.com/paulgv/13ff6d194bc0d662de7b
[edit3] I also realize that I never updated my code with a cleaner fix for the issue I had with the Content-Disposition header (see crossed out text above). Thanks to blueimp's help, I found out that you can simply remove this header in fileuploadsend callback :
.bind('fileuploadsend', function (e, data) {
data.headers = {};
})
PUT uploads do not support multipart form encoding. PUT uploads should have a request body of only the raw bytes of the file.
Multipart is supported on POST uploads, but POST uploads do not support resumable uploads or range headers.

POST request with files and fields in guzzle

Ok I'll give a little background to start. I have system A written in CakePHP that handles ads and products and such. Recently I have been working on another system, written in Laravel, that acts as a self-serve tool for realtors to post and manage their real estate listings that reside in system A. I am now at the point of uploading images from the self-serve site to system A. I wrote a simple controller action in Cake to handle a POST request and save the image file on the server.
http://example.com/image/add
I am able to send POST requests, upload images and get a proper response using REST applications such as postman. All looks good on system A (Cake) side of things.
Now in the self-serve system, in Laravel, I am using Guzzle to send HTTP requests. I have filled out the guzzle post request with the exact same fields and files, but I don't recieve the same output. The request is received by system A, but the image is not added and a random HTML page is returned. If postman and a few other applications get the exact same response and functionality, but my request sent in Guzzle is not, I am thinking there is an issue with my guzzle request. Here is my guzzle code:
$client = new Client();
// Create the request.
$request = $client->createRequest("POST", "http://example.com/image/add");
// Set the POST information.
$postBody = $request->getBody();
$postBody->setField('user_id', $userId);
$postBody->setField('api_key', $token);
$postBody->setField('product_id', $product_id);
$postBody->addFile(new PostFile('image[data]', fopen('tmp/images/'.$input->image, 'r')));
// Send the request and get the response.
$response = $client->send($request);
Here is the working POST request from Postman:
POST /image/add HTTP/1.1
Host: example.com
Cache-Control: no-cache
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="product_id"
1000
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="user_id"
8345
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="api_key"
secretKey
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Content-Disposition: form-data; name="data[image]"; filename="steve-jobs.jpg"
Content-Type: image/jpeg
----WebKitFormBoundaryE19zNvXGzXaLvS5C
Here is the guzzle request to string, I apologize for readability issues.
POST /image/add HTTP/1.1 Host: example.com User-Agent: Guzzle/4.0.2 curl/7.22.0 PHP/5.5.9-1+sury.org~precise+1 Content-Length: 124647 Content-Type: multipart/form-data; boundary=53a1f21e04080 --53a1f21e04080 Content-Disposition: form-data; name="user_id" 8345 --53a1f21e04080 Content-Disposition: form-data; name="api_key" secretKey --53a1f21e04080 Content-Disposition: form-data; name="product_id" 1000 --53a1f21e04080 Content-Disposition: form-data; filename="steve-jobs.jpg"; name="image[data]" Content-Type: image/jpeg
Then a bunch a characters for the image data.
I am asking if anyone can see an issue with my POST request in guzzle or if anyone has run into this kind of weird issue with guzzle before.
Edit:
I am using CakePHP 2.4.1
As far as I can tell it's just a small mistake in the file field name, it should be data[image], not image[data].
new PostFile('data[image]', /* ... */);
In your app you are probably relying on the file data being available via CakeRequest::$data, however it will only land there in case it's wrapped in the data key, otherwise it is added to CakeRequest::$params['form'].
Not really a duplicate, however for (a more CakePHP form helper related) reference see also:
CakePHP: posted file data not included in request->data

Php POST - get boundary value

So I want to upload a file using curl, but the problem is: the post request contains a boundary variable that is checked upon by the website. I know this because I get errors when modifying this variable in Tamper Data.
Http headers (important part):
Content-Type: multipart/form-data; boundary=----pluploadboundaryp18mu3sf5fus08pd11c3kvq163514
Post request:
------pluploadboundaryp18mu3sf5fus08pd11c3kvq163514\r\n
Content-Disposition: form-data; name="name"\r\n
\r\n
1.jpg\r\n
------pluploadboundaryp18mu3sf5fus08pd11c3kvq163514\r\n
Content-Disposition: form-data; name="imageData"; filename="1.jpg"\r\n
Content-Type: image/jpeg\r\n
\r\n
{Filecontent}
So my question is: How can I bypass or duplicate this boundary?
Edit: if you want to test yourself the form upload is located at:https://www.marktplaats.nl/syi/239/1399/plaatsAdvertentie.html
So i got the answer on my question. Also thanks to Ruslan Bes for helping.
The problem was i sended my post request as http_build_query($post) instead of $post.
Small mistakes can cause a lot of problems :D

PHP CURL - Passing an image from a remote url with http header response code checking in one curl resource

I have php application that serve image, the image is coming from a remote URL and passing it to the browser with content type image. My code has 2 steps:
Using curl to check the http header response. If it is a valid image (httpcode 200).
if httpcode is 200, I used readfile function with header content-type: image/jpg.
For me the approach above is not a good idea because it makes 2 http hit. My goal is to make the 2 steps above just one using CURL. Is it possible?
Appreciate any inputs on this.
Thanks.

How to handle images sent by a mobile device?

A peer of mine is developing an iPhone application that will allow users to post images on my site via my API. I am building the part of the API that will accept and process the images.
The mobile developer is sending headers like such:
Content-Disposition: form-data; name="photo_1"; filename="photo_1.jpg"
Content-Type: application/octet-stream
When looking for the images sent, is it the same method as with normal HTML forms? Should I look for $_FILES?
Or, using PHP, how would I find his image?
Doesn't appear it's being sent via a form, i.e., <form enctype=multipart/form-data"> and <input type="file">, so the $_FILES array won't be populated.
You'll probably need to read:
$HTTP_RAW_POST_DATA
or do:
$rawPost = file_get_contents("php://input");
From the manual:
php://input allows you to read raw
data from the request body. In case of
POST requests, it preferrable to
$HTTP_RAW_POST_DATA as it does not
depend on special php.ini directives.
Moreover, for those cases where
$HTTP_RAW_POST_DATA is not populated
by default, it is a potentially less
memory intensive alternative to
activating
always_populate_raw_post_data.
php://input is not available with
enctype="multipart/form-data".
For more info, check out:
http://php.net/manual/en/wrappers.php.php
http://php.net/manual/en/reserved.variables.httprawpostdata.php
I suppose iOS is sending the whole file as a single block of data in the POSTDATA section of the HTTP request. You can retrieve the whole POSTDATA (not parsed):
<?php
$postdata = file_get_contents("php://input");
?>
$_FILES is meant for reading files sent with enctype="multipart/form-data" in a proper HTML form. iOS is probably sending a plain old POST containing just a bunch of bytes which represent the file.
Tell me if this solves!
See these answers I gave to similar questions (processing uploads from php://input):
userland multipart/form-data handler and also
How to validate if uploaded file is an image? [file sent via HTML5's File API, received via php://input]

Categories