PHP curl changes the Content-Type to application/x-www-form-urlencoded. Shouldn't do that

匿名 (未验证) 提交于 2019-12-03 08:41:19

问题:

I want to upload a video direct to Youtube from my server for which I am using PHP curl.

I need this request format:

POST /feeds/api/users/default/uploads HTTP/1.1 Host: uploads.gdata.youtube.com Authorization: Bearer ACCESS_TOKEN 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-- 

This is what I have:

$content = $this->buildRequestContent();  $ch = curl_init();  $curlConfig = array(     CURLOPT_URL => 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads',     CURLOPT_POST => true,     CURLOPT_RETURNTRANSFER => true,     CURLOPT_BINARYTRANSFER => true,     CURLOPT_POSTFIELDS => $content,     CURLOPT_HTTPHEADER, array(         "Authorization" => sprintf("GoogleLogin auth=%s", $this->accessToken),         "GData-Version" => 2,         "X-GData-Key" => sprintf("key=%s", $this->developerKey),         "Slug" => sprintf("%s", $this->video->getFilename()),         "Content-Type" => sprintf("multipart/related; boundary=\"%s\"", $this->boundaryString),         "Content-Length" => strlen($content),         "Connection" => "close"     ), );  curl_setopt_array($ch, $curlConfig);  $result = curl_exec($ch); 

Dumping the result shows me that curl changed the Content-Type to application/x-www-form-urlencoded which is of course not supported by youtube.

I put my binary content (the video) into CURLOPT_POSTFIELDS, maybe this is wrong, but I don't know how to set the request body other than that.

So how do I preserve my Content-Type that I set?

回答1:

According to the documentation section regarding the options' parameter setting the HTTP method to POST defaults to content type being set to application/x-www-form-urlencoded. So my suspicion is that setting all the options at once, results in your Content-Type being overwritten.
My suggestion would be to set the content type in a single statement, after you've set the method, i.e.

$curlConfig = array(     CURLOPT_URL => 'http://uploads.gdata.youtube.com/feeds/api/users/default/uploads',     CURLOPT_POST => true,     CURLOPT_RETURNTRANSFER => true,     CURLOPT_BINARYTRANSFER => true,     CURLOPT_POSTFIELDS => $content, );  curl_setopt_array($ch, $curlConfig);  curl_setopt($ch, CURLOPT_HTTPHEADER, array(     'Authorization: ' . sprintf('GoogleLogin auth=%s', $this->accessToken),     'GData-Version: 2',     'X-GData-Key: ' . sprintf('key=%s', $this->developerKey),     'Slug: ' . sprintf('%s', $this->video->getFilename()),     'Content-Type: ' . sprintf('multipart/related; boundary="%s"',                                   $this->boundaryString),     'Content-Length: ' . strlen($content),     'Connection: close' )); 


回答2:

Accepted answer was not helpful for me and I found another problem in your code. According to the current PHP documentation CURLOPT_HTTPHEADER must be set like this:

curl_setopt($ch, CURLOPT_HTTPHEADER, array(     'Content-type: text/plain',     'Content-length: 100' )); 

It must be a list of strings, not a hash like array('Content-Type' => 'text/plain'). Hope it will save someone's debugging time.



标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!