2013-04-18 15 views
8

Tôi muốn tải video trực tiếp lên Youtube từ máy chủ của tôi mà tôi đang sử dụng PHP curl.PHP curl thay đổi Content-Type thành application/x-www-form-urlencoded. Không nên làm điều đó

Tôi cần định dạng yêu cầu này:

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

Đây là những gì tôi có:

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

bán phá giá kết quả cho thấy tôi curl làm thay đổi Content-Type để application/x-www-form-urlencoded đó là tất nhiên không được hỗ trợ bởi youtube .

Tôi đặt nội dung nhị phân (video) vào CURLOPT_POSTFIELDS, có thể điều này sai, nhưng tôi không biết cách đặt thân yêu cầu khác.

Vậy làm cách nào để bảo vệ Loại nội dung mà tôi đã đặt?

+1

Theo tài liệu 'CURLOPT_POST' đặt 'Content-Type' tự động thành' application/x-www-form-urlencoded'. Hãy thử có thể thiết lập tùy chọn này và 'CURLOPT_HEADER' trong các câu lệnh đơn, hoặc ít nhất là sau trong một câu lệnh đơn bằng cách sử dụng' curl_setopt' * sau * bạn đã thiết lập phương thức. – Havelock

+1

Đã hoạt động. Bạn có thể đăng câu trả lời này để tôi có thể chấp nhận câu trả lời không? –

Trả lời

7

Theo documentation section regarding the options' parameter đặt phương thức HTTP thành POST mặc định thành loại nội dung được đặt thành application/x-www-form-urlencoded. Vì vậy, sự nghi ngờ của tôi là đặt tất cả các tùy chọn cùng một lúc, kết quả là số Content-Type của bạn bị ghi đè.
Đề nghị của tôi sẽ là để thiết lập các kiểu nội dung trong một tuyên bố duy nhất, sau khi bạn đã thiết lập phương pháp, ví dụ:

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

Vui lòng cập nhật ví dụ của bạn, nó không phải là mảng hai chiều. Nó phải là: array ("Authorization:". Sprintf ..., "Content-Type:". Sprintf ....) –

+0

@JohnCongdon: đúng, cảm ơn! Thật buồn cười không ai nhận thấy nó chỉ trong hơn hai năm, ba upvotes và "chấp nhận câu trả lời". (Tôi chắc chắn bạn có nghĩa là "không phải là một mảng kết hợp" thay vì "không phải là một mảng hai chiều";)) – Havelock

+0

Sự xấu hổ cho cURL PHP. Không chỉ 'CURLOPT_POST' ghi đè' Nội dung Kiểu ', mà còn ngăn các tiêu đề HTTP khác được đặt cùng một lúc. Cảm ơn giải pháp đó! – NeverEndingQueue

10

Được chấp nhận câu trả lời là không hữu ích cho tôi và tôi thấy một vấn đề trong mã của bạn. Theo dòng PHP documentation CURLOPT_HTTPHEADER phải được thiết lập như thế này:

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

Nó phải là một danh sách các chuỗi, không phải là một hash như array('Content-Type' => 'text/plain'). Hy vọng nó sẽ tiết kiệm thời gian gỡ lỗi của ai đó.

+1

Nói cách khác, bạn không thể chuyển mảng liên kết đến CURLOPT_HTTPHEADER, chỉ mảng đơn giản. Vấn đề này khiến tôi phát điên trong nhiều giờ ... – andreszs

Các vấn đề liên quan