PHP curl изменяет Content-Type на application / x-www-form-urlencoded. Не следует этого делать

Я хочу загрузить видео прямо на Youtube с моего сервера, для которого я использую PHP curl.

Мне нужен этот формат запроса:

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-- 

Это то, что у меня есть:

 $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); 

Сбрасывание результата показывает, что завиток изменил Content-Type на application/x-www-form-urlencoded который, конечно же, не поддерживается youtube.

Я помещаю свой двоичный контент (видео) в CURLOPT_POSTFIELDS , возможно, это неправильно, но я не знаю, как установить тело запроса, кроме этого.

Итак, как мне сохранить свой Content-Type, который я установил?

Согласно разделу документации, касающемуся параметра параметров, для HTTP-метода POST умолчанию используется тип контента, который устанавливается в application/x-www-form-urlencoded . Поэтому я подозреваю, что установка всех параметров сразу приводит к тому, что ваш Content-Type перезаписывается.
Мое предложение состояло в том, чтобы установить тип содержимого в один оператор после того, как вы установили метод, т.е.

 $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' )); 

Принятый ответ не помог мне, и я нашел еще одну проблему в вашем коде. Согласно текущей документации PHP CURLOPT_HTTPHEADER должен быть установлен следующим образом:

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

Это должен быть список строк, а не хэш- array('Content-Type' => 'text/plain') . Надеюсь, что это сэкономит время отладки.