So i managed to built oauth 2.0 youtube video upload, but everytime i upload a video i get an HTTP 400 ERROR with a invalid request.
But the weirdest thing is that the video is uploading to youtube while having : Failed (upload aborted).
im not using any framework, cause google doesnt have yet any to oauth 2.0, so i built all of my code on my own.
And also i did managed to send comments, and stuff.... the only problem is the video upload itself.
My code:
public function uploadVideo($video, $title, $description, $category, $keywords) {
$url = 'http://uploads.gdata.youtube.com/feeds/api/users/FacebookDevelopersIL/uploads';
$boundary = uniqid();
$accessToken = $this->refreshAccessToken("13", "11313", 'REFRESHTOKEN');
$xmlString = "<?xml version='1.0'?><entry xmlns='http://www.w3.org/2005/Atom' xmlns:media='http://search.yahoo.com/mrss/' xmlns:yt='http://gdata.youtube.com/schemas/2007'><media:group><media:title type='plain'>".$title."</media:title><media:description type='plain'>".$description."</media:description> <media:category scheme='http://gdata.youtube.com/schemas/2007/categories.cat'>".$category."</media:category><media:keywords>".$keywords."</media:keywords></media:group></entry>";
$videoData = file_get_contents($video);
$headers = array(
'POST /feeds/api/users/FacebookDevelopersIL/uploads HTTP/1.1',
'Host: uploads.gdata.youtube.com',
'Authorization: Bearer '.$accessToken,
'GData-Version: 2',
'X-GData-Key: key='.YOUTUBE_SRM_DEVELOPER_KEY,
'Slug: IMG_0047.mp4',
'Content-Type: multipart/related; boundary='.$boundary,
'Content-Length:'.strlen($videoData),
'Connection: close'
);
$postData = "--".$boundary . "\r\n"
."Content-Type: application/atom+xml; charset=UTF-8\r\n\r\n"
.$xmlString . "\r\n"
."--".$boundary . "\r\n"
."Content-Type: video/mp4\r\n"
."Content-Transfer-Encoding: binary\r\n\r\n"
.$videoData . "\r\n"
."--".$boundary . "--";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
$response = curl_exec($ch);
curl_close($ch);
Trace::dump($response); }
The error im getting: HTTP/1.1 400 Bad Request Server: HTTP Upload Server Built on May 7 2012 18:16:42 (1336439802) Content-Type: text/html; charset=UTF-8 X-GUploader-UploadID: AEnB2Uq7cHcf6rS4bcamu18ChAF3gnKJqsF6U_dk2qB4WR9GhAoTL_-iUejitgead-Gh-1fpJcke1z68TAxoopS2vYiGmCW69A Date: Thu, 10 May 2012 11:55:24 GMT Pragma: no-cache Expires: Fri, 01 Jan 1990 00:00:00 GMT Cache-Control: no-cache, no-store, must-revalidate Content-Length: 15 Connection: close
Invalid Request
thanx everyone!
Couple of things I notice: hard coding the POST and Host headers is poor form, because curl will take care of them automatically for you. I suspect part of the problem is the insertion of the carriage return/line feed between the $videoData and the last boundary marker. That will be interpreted as part of the video file. All you need are line feeds as line separators. Maybe the carriage return renders the video file invalid?
Maybe curl_setopt($ch, CURLOPT_VERBOSE, true) will provide some illumination.
This works for me (on a Linux host):
/*
** https://developers.google.com/youtube/2.0/developers_guide_protocol_direct_uploading
*/
private function send_to_youtube($video_file, $video_info) {
// Refresh access token
log_msg("Obtaining access token");
$response = http_post($this->config['token_url'], array(
'client_id' => $this->config['client_id'],
'client_secret' => $this->config['client_secret'],
'refresh_token' => $video_info->refresh_key,
'grant_type' => $this->config['grant_type']
));
if ($response['http_code'] != 200)
throw new Exception("Unable to obtain access token. ".print_r($response, true));
$authorization = json_decode($response['contents'], true);
// Build multi-part upload request
// api xml and then video file contents
$boundary = uniqid();
$location = '';
if ($video_info->latitude && $video_info->longitude)
$location = '
<georss:where>
<gml:Point>
<gml:pos>'. $video_info->latitude .' '. $video_info->longitude .'</gml:pos>
</gml:Point>
</georss:where>';
$content = '--'.$boundary.'
Content-Type: application/atom+xml; charset=UTF-8
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:yt="http://gdata.youtube.com/schemas/2007"
xmlns:georss="http://www.georss.org/georss"
xmlns:gml="http://www.opengis.net/gml">
<media:group>
<media:title type="plain">'. $video_info->title .'</media:title>
<media:description type="plain">
'. $video_info->description .'
</media:description>
<media:category
scheme="http://gdata.youtube.com/schemas/2007/categories.cat">
'. $video_info->category .'
</media:category>
<media:keywords>'. implode(', ', $video_info->tags) .'</media:keywords>
</media:group>
'. $location .'
</entry>
--'.$boundary.'
Content-Type: '. $video_info->type .'
Content-Transfer-Encoding: binary
'.file_get_contents($video_file).'
--'.$boundary.'--';
$headers = array(
'Authorization: '.$authorization['token_type'].' '.$authorization['access_token'],
'GData-Version: 2',
'X-GData-Key: key='.$this->config['dev_key'],
'Slug: '.$video_info->filename,
'Content-Type: multipart/related; boundary="'.$boundary.'"',
'Content-Length: '.strlen($content),
'Connection: close'
);
// Upload video
log_msg("Sending video '{$video_info->title}', {$video_info->url}");
$ch = curl_init($this->config['upload_url']);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, $content);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, true);
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 0);
$response = curl_exec($ch);
$http_code = curl_getinfo($ch, CURLINFO_HTTP_CODE);
curl_close($ch);
if (!$http_code == 201) { // Something other than 'New Entry'
log_msg("Upload Failed: ".print_r($response, true));
return new SimpleXMLElement();
}
$entry = new SimpleXMLElement($response);
$yt_link = $entry->link[0]->attributes()->href;
log_msg("Upload Complete: ".$yt_link);
return $entry;
}
Related
Here is the WSDL ...
I am using the SOAP Client in PHP with documentation HERE ...
Soap Call
$wsdl = 'https://api.krollcorp.com/EBusinessTest/Kroll.Dealer.EBusiness.svc/Docs?singleWsdl';
try {
$client = new SoapClient($wsdl, array('soap_version' => SOAP_1_2, 'trace' => 1));
// $result = $client->SubmitPurchaseOrder();
$result = $client->__soapCall("SubmitPurchaseOrder", array());
} catch (SoapFault $e) {
printf("\nERROR: %s\n", $e->getMessage());
}
$requestHeaders = $client->__getLastRequestHeaders();
$request = $client->__getLastRequest();
$responseHeaders = $client->__getLastResponseHeaders();
printf("\nRequest Headers -----\n");
print_r($requestHeaders);
printf("\nRequest -----\n");
print_r($request);
printf("\nResponse Headers -----\n");
print_r($responseHeaders);
printf("\nEND\n");
Output
ERROR: The SOAP action specified on the message, '', does not match the HTTP SOAP Action, 'http://tempuri.org/IEBusinessService/SubmitPurchaseOrder'.
Request Headers -----
POST /EBusinessTest/Kroll.Dealer.EBusiness.svc HTTP/1.1
Host: api.krollcorp.com
Connection: Keep-Alive
User-Agent: PHP-SOAP/5.6.19
Content-Type: application/soap+xml; charset=utf-8; action="http://tempuri.org/IEBusinessService/SubmitPurchaseOrder"
Content-Length: 200
Request -----
<?xml version="1.0" encoding="UTF-8"?>
<env:Envelope xmlns:env="http://www.w3.org/2003/05/soap-envelope" xmlns:ns1="http://tempuri.org/"><env:Body><ns1:SubmitPurchaseOrder/></env:Body></env:Envelope>
Response Headers -----
HTTP/1.1 500 Internal Server Error
Content-Length: 637
Content-Type: application/soap+xml; charset=utf-8
Server: Microsoft-IIS/7.5
X-Powered-By: ASP.NET
Date: Wed, 06 Sep 2017 12:42:57 GMT
END
Attempts
I am a beginner at using SOAP APIs.
I believe this is failing because SOAP 1.2 uses WsHttpBinding instead of BasicHttpBinding.
I am not sure how to set WS Addressing with the SOAP Client in PHP ...
Below code is working for me.You can enable Ws-A Addressing and call soap method-
$client = new SoapClient("http://www.xyz.Services?Wsdl", array('soap_version' => SOAP_1_2,'trace' => 1,'exceptions'=> false
));
$wsa_namespace = 'http://www.w3.org/2005/08/addressing';
$ACTION_ISSUE = 'http://www.xyx/getPassword';// Url With method name
$NS_ADDR = 'http://www.w3.org/2005/08/addressing';
$action = new SoapHeader($NS_ADDR, 'Action', $ACTION_ISSUE, true);
$to = new SoapHeader($NS_ADDR, 'To', 'http://www.xyx.svc/Basic', false);
$headerbody = array('Action' => $action,'To' => $to);
$client->__setSoapHeaders($headerbody);
//$fcs = $client->__getFunctions();
//pre($client->__getLastRequest());
//pre($fcs);
$parameters=array('UserId'=>'12345678','MemberId'=>'123456','Password' => '123456','PassKey' => 'abcdef1234');
;
$result = $client->__soapCall('getPassword', array($parameters));//getPassword method name
print_r(htmlspecialchars($client->__getLastRequest()));// view your request in xml code
print_r($client->__getLastRequest());die; //Get Last Request
print_r($result);die; //print response
Dude, I totally feel your pain. I was able to get this to work but I don't think this is the right way, but it is pointing in the right direction. A caveat though, you have to know what namespace soap_client is going to assign to the addressing. Best way is just to capture the request XML and look for what namespace is attache to the addressing, and then pass it in. Below is my code with a default of 'ns2' for namespace, but you can't count on it for your example. Good Luck!
private function generateWSAddressingHeader($action,$to,$replyto,$message_id=false,$ns='ns2')
{
$message_id = ($message_id) ? $message_id : $this->_uniqueId(true);
$soap_header = <<<SOAP
<{$ns}:Action env:mustUnderstand="0">{$action}</{$ns}:Action>
<{$ns}:MessageID>urn:uuid:{$message_id}</{$ns}:MessageID>
<{$ns}:ReplyTo>
<{$ns}:Address>{$replyto}</{$ns}:Address>
</{$ns}:ReplyTo>
<{$ns}:To env:mustUnderstand="0">$to</{$ns}:To>
SOAP;
return new \SoapHeader('http://www.w3.org/2005/08/addressing','Addressing',new \SoapVar($soap_header, XSD_ANYXML),true);
}
My solution is
Send request using SoapUi
Copy request http log from SoapUi screen ( Bottom of SoapUi program)
Past that code into the PHP project as fallows
$soap_request = '{copy that part from SoapUi http log}';
$WSDL = "**wsdl adres**";
$ch = curl_init();
curl_setopt($ch, CURLOPT_HEADER, false);
curl_setopt($ch, CURLOPT_URL, $WSDL);
curl_setopt($ch, CURLOPT_FAILONERROR, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, Array(
'Content-Type: application/soap+xml; charset=utf-8',
'SOAPAction: "run"',
'Accept: text/xml',
'Cache-Control: no-cache',
'Pragma: no-cache',
'Content-length: '. strlen($soap_request),
'User-Agent: PHP-SOAP/7.0.10',
));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 30);
curl_setopt($ch, CURLOPT_TIMEOUT, 30);
curl_setopt($ch, CURLOPT_POSTFIELDS, $soap_request);
$response = curl_exec($ch);
if (empty($response)) {
throw new SoapFault('CURL error: '.curl_error($ch), curl_errno($ch));
}
curl_close($ch);
Im trying to upload an image to Smugmug using the Upload API v2.
I've been trying for quite a time but it wont work.
This is what i've came up with so far.
When i run the script the response is as follows:
HTTP/1.1 100 Continue HTTP/1.1 200 OK Cache-Control: private, no-store, no-cache, max-age=1, must-revalidate Content-Type: text/xml; charset=utf-8 Date: Tue, 07 Jul 2015 14:18:50 GMT Edge-Control: no-store Expires: Tue, 07 Jul 2015 14:18:50 GMT Server: nginx X-Powered-By: SmugMug/1.0 X-SmugMug-Hiring: How to love what you do: http://www.smugmug.com/jobs/ X-SmugMug-Values: 1/4 - Thrill your customers Content-Length: 38 Connection: keep-alive
But the file isn't uploaded..
Do you see anything wrong with the code?
include_once("oauth/OAuth.php");
include_once("constants.php");
$access_token = '***';
$access_token_secret = '***';
$consumer = new OAuthConsumer(API_KEY, API_KEY_SECRET);
$signature_method = new OAuthSignatureMethod_PLAINTEXT;
$token = new OAuthToken($access_token, $access_token_secret);
$req_token = OAuthRequest::from_consumer_and_token($consumer, $token, "POST", 'http://upload.smugmug.com');
$req_token->sign_request($signature_method, $consumer, $token);
$parameters = $req_token->get_parameters();
$path = 'image.png';
$type = pathinfo($path, PATHINFO_EXTENSION);
$data = file_get_contents($path);
$base64 = 'data:image/' . $type . ';base64,' . base64_encode($data);
$finfo = finfo_open(FILEINFO_MIME_TYPE);
$mime = finfo_file($finfo, $path);
finfo_close($finfo);
$header[] = 'Authorization: OAuth realm="http://upload.smugmug.com/",
oauth_consumer_key='.$parameters['oauth_consumer_key'].',
oauth_token='.$parameters['oauth_token'].',
oauth_signature_method='.$parameters['oauth_signature_method'].',
oauth_signature='.$parameters['oauth_signature'].',
oauth_timestamp='.time().',
oauth_nonce='.md5(time() . mt_rand()).',
oauth_version=1.0';
$body[] = 'Accept: application/json';
$body[] = 'X-Smug-Version: v2';
$body[] = 'X-Smug-ResponseType: JSON';
$body[] = 'X-Smug-AlbumUri: /api/v2/album/******';
$body[] = 'X-Smug-Filename: image.png';
$body[] = 'Content-MD5: '.$base64.'';
$body[] = 'Content-Length: '.filesize($path).'';
$body[] = 'Content-Type: '.$mime.'';
$ch = curl_init();
curl_setopt($ch, CURLOPT_HTTPHEADER, $header);
curl_setopt($ch, CURLOPT_BINARYTRANSFER, true);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_VERBOSE, true);
curl_setopt($ch, CURLOPT_HEADER, 1);
curl_setopt($ch, CURLOPT_URL, 'http://upload.smugmug.com/');
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 0);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, 0);
curl_setopt($ch, CURLOPT_POSTFIELDS, $body);
curl_error ($ch);
$result = curl_exec($ch);
print_r($result);
Using OAuth can be tricky, and the upload API for SmugMug is a little unique. It might be helpful to use one of the PHP wrappers out there rather than write your own code. Here are two, both of which have examples of how to upload images:
1.) phpSmug
2.) DFM Smug Wrapper
For example with the DFM Smug Wrapper, you can do the following (copied from the README file included with the wrapper):
<?php
require_once("dfm-smug-wrapper/dfm-smug-wrapper.php");
$f = new DFM_Smug(
"oauth_consumer_key=12345678",
"oauth_secret=some_secret",
"token_id=12345",
"token_secret=some_other_secret",
"app_name=My Cool App/1.0 (http://app.com)",
"api_ver=2.0"
);
$f->images_upload("AlbumID=123456", "File=/path/to/image.jpg");
?>
Hi I'm trying to send this json object using the POST method but i'm not sure how to include the headers below, i was checking a lot of examples, but no one uses the headers below listed.
This is the code of my php processing page, this page will process the inputs received from a form.html and will create the json object to be transferred to the http server (external platform)
<?php
$host ="10.10.237.8";
$puerto = 21098;
$BUFF = 2048;
$socket = socket_create(AF_INET, SOCK_STREAM, SOL_TCP);
$conexion = socket_connect($socket, $host, $puerto);
if($conexion)
{
$msisdn=$_POST["msisdn"];
$mensaje=$_POST["mensaje"];
$php_array = array(
"numero" => $msisdn,
"mensaje" => "$mensaje",
);
$json_array=json_encode($php_array);
echo "Conexion Exitosa, puerto: " . $puerto."\n\n";
echo $json_array;
socket_write($socket, $json_array);
// Receive the results (if any) from the server
$server_response = socket_read($socket, $BUFF);
$decoded_response = json_decode($server_response, true); // decode the data received
echo $decoded_response['passphrase']; // and spit the results
}
else
{
echo "\nLa conexion TCP no se pudo realizar, puerto: ".$puerto;
}
socket_close($socket);
?>
these are the headers information, where i whould include them ? how to do it ? using cURL ? do you have a good example ?
POST /SMBULK/BATCH HTTP/1.0
Authorization: Basic dGVzdDp0ZXN0
Host: 10.10.237.8:21098
Content-Length: 395
User-Agent: Wget/1.12 (solaris2.10)
Content-Type: application/x-www-form-urlencoded
Connection: Keep-Alive
Accept: */*
I hope you can help me. The php code above is not working because some of the information (POST, Content-Length, Content-Type, User-Agent...etc ) is not being included (except "host" which did was included).
I managed to did this but it's not working:
<?php
$str_obj_json='{
"method":"SUBMIT","params":{
"batchType":"submit",
"batchId":"alvarons",
"origAddr":"550",
"origTon":2,
"userData":"Movistar les desea Feliz Navidad",
"submits":
[
{
"messId":"mess127_001",
"destAddr":"51975375377"}
]
}
}';
$ch = curl_init('http://10.10.237.8:21098/SMBULK/BATCH');
curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "POST");
curl_setopt($ch, CURLOPT_POSTFIELDS, $str_obj_json);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, array(
'Content-Type: application/x-www-form-urlencoded',
'Content-Length: 395',
'Authorization: Basic dGVzdDp0ZXN0',
'User-Agent: Wget/1.12 (solaris2.10)',
'Connection: Keep-Alive',
'Accept: */*')
);
$result = curl_exec($ch);
?>
What is wrong ?
To send json object using cUrl you have to add "Content-Type: application/json" to header
curl_setopt($curl, CURLOPT_HTTPHEADER,
array(
'Content-type: application/json'
'Content-Length: 395',
'Authorization: Basic dGVzdDp0ZXN0',
'User-Agent: Wget/1.12 (solaris2.10)',
'Connection: Keep-Alive',
'Accept: */*');
at the moment I am coding an article/customer/billing software with PHP and this is my last step before letting my partner test it.
I'm really stuck at the moment. We want to upload our articles automatically to eBay. The generation of the CSV file for the File Exchange Program works fine, manual uploading also works and the articles will be listed.
Now we want the software to do the upload by itself. We reference to the eBay File Exchange Guide here:
and here:
.
This is my present code:
$SOCKETPROC = fsockopen('bulksell.ebay.de', 80, $errno, $errstr, 4);
fputs($SOCKETPROC, "POST https://bulksell.ebay.de/ws/eBayISAPI.dll?FileExchangeUploadForm HTTP/1.0\r\n");
fputs($SOCKETPROC, "Connection: Keep Alive\r\n");
fputs($SOCKETPROC, "User-Agent: App v1.0\r\n");
fputs($SOCKETPROC, "Host: https://bulksell.ebay.de/ws/eBayISAPI.dll?FileExchangeUpload\r\n");
fputs($SOCKETPROC, "Content-Type: multipart/form-data; boundary=THIS_STRING_SEPARATES\r\n");
fputs($SOCKETPROC, "Content-Length: " . filesize('export/ebay/items-' . date('Y-m-d') . '.csv') + filesize('export/ebay/token') . "\r\n");
fputs($SOCKETPROC, "--THIS_STRING_SEPARATES\r\n");
fputs($SOCKETPROC, "Content-Disposition: form-data; name=\"token\"\r\n");
fputs($SOCKETPROC, file_get_contents('export/ebay/token'));
fputs($SOCKETPROC, "\r\n--THIS_STRING_SEPARATES\r\n");
fputs($SOCKETPROC, "Content-Disposition: form-data; name=\"file\"; filename=\"items-" . date('Y-m-d') . ".csv\"\r\n");
fputs($SOCKETPROC, "Content-Type: text/csv\r\n\r\n");
fputs($SOCKETPROC, file_get_contents('export/ebay/items-' . date('Y-m-d') . '.csv'));
fputs($SOCKETPROC, "\r\n--THIS_STRING_SEPARATES\r\n");
fputs($SOCKETPROC, "Connection: Close\r\n\r\n"); // Not sure if this line is relevant
$RESULT = fgets($SOCKETPROC);
fclose($SOCKETPROC);
But the file just won't appear in the eBay list of uploaded files. When I change the https:// to http:// and checkout the result with fgets($SOCKETPROC); I'm getting a HTTP/1.1 200 OK, otherwise I don't get any reaction.
Note: .de is being used on purpose. So no typo or mistake there.
Try connect and upload by cUrl:
$token = "your_token";
$ebay_url = "https://bulksell.ebay.de/ws/eBayISAPI.dll?FileExchangeUpload";
$sendheaders = array(
"User-Agent: MyClient v1.6",
);
$fields = array(
"token" => $token,
"file" => "#file.csv"
);
$ch = curl_init($ebay_url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_HEADER, 0); // set to 0 to eliminate header info from response
curl_setopt($ch, CURLOPT_NOBODY, 0); // set to 1 to eliminate body info from response
curl_setopt($ch, CURLOPT_HTTP_VERSION, CURL_HTTP_VERSION_1_0); // use HTTP/1.0 instead of 1.1
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); // Returns response data instead of TRUE(1)
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE); // uncomment this line if you get no gateway response. ###
curl_setopt($ch, CURLOPT_HTTPHEADER, $sendheaders);
curl_setopt($ch, CURLOPT_POSTFIELDS, $fields); // use HTTP POST to send form data
$resp = curl_exec($ch); //execute post and get results
curl_close ($ch);
wondering how I can set all this data in a curl session, via php:
POST /feeds/api/users/default/uploads HTTP/1.1
Host: uploads.gdata.youtube.com
Authorization: AuthSub token="DXAA...sdb8"
GData-Version: 2
X-GData-Key: key=adf15ee97731bca89da876c...a8dc
Slug: video-test.mp4
Content-Type: multipart/related; boundary="f93dcbA3"
Content-Length: 1941255
Connection: close
--f93dcbA3
Content-Type: application/atom+xml; charset=UTF-8
<?xml version="1.0"?>
<entry xmlns="http://www.w3.org/2005/Atom"
xmlns:media="http://search.yahoo.com/mrss/"
xmlns:yt="http://gdata.youtube.com/schemas/2007">
<media:group>
<media:title type="plain">Bad Wedding Toast</media:title>
<media:description type="plain">
I gave a bad toast at my friend's wedding.
</media:description>
<media:category
scheme="http://gdata.youtube.com/schemas/2007/categories.cat">People
</media:category>
<media:keywords>toast, wedding</media:keywords>
</media:group>
</entry>
--f93dcbA3
Content-Type: video/mp4
Content-Transfer-Encoding: binary
<Binary File Data>
--f93dcbA3--
I don't understand why have some headers, then the --f93dcbA3 more headers (what's the boundary?), some xml (why here ?), more headers and the content of a file.
I know how to make the request without the xml part and the 'boundary'.
Any help will be appreciated :D
The boundary is required because the form enctype is multipart/form-data, rather in this case multipart/related. The boundary is a unique string that cannot appear anywhere else in the request, and it is used to separate each element from the form, whether it is the value of a text input, or a file upload. Each boundary has its own content-type.
Curl cannot do multipart/related for you, so you will need to use a workaround, see this message from the curl mailing list for suggestions. Basically, you will have to construct most of the message yourself.
Note, the last boundary has an additional -- at the end.
This code should hopefully help get you started:
<?php
$url = 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads';
$authToken = 'DXAA...sdb8'; // token you got from google auth
$boundary = uniqid(); // generate uniqe boundary
$headers = array("Content-Type: multipart/related; boundary=\"$boundary\"",
"Authorization: AuthSub token=\"$authToken\"",
'GData-Version: 2',
'X-GData-Key: key=adf15....a8dc',
'Slug: video-test.mp4');
$postData = "--$boundary\r\n"
."Content-Type: application/atom+xml; charset=UTF-8\r\n\r\n"
.$xmlString . "\r\n" // this is the xml atom data
."--$boundary\r\n"
."Content-Type: video/mp4\r\n"
."Content-Transfer-Encoding: binary\r\n\r\n"
.$videoData . "\r\n" // this is the content of the mp4
."--$boundary--";
$ch = curl_init($url);
curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $postData);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_FOLLOWLOCATION, 1);
curl_setopt($ch, CURLOPT_HEADER, 0);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
curl_close($ch);
Hope that helps.