尝试将包含元数据的照片上传到Picasa时,“获取Multipart必须包含Atom和媒体部分”错误

时间:2012-03-23 15:03:18

标签: php curl google-data-api picasa

我有以下代码尝试将带有元数据的图像上传到Picasa网络相册。

如果我取出元数据并直接执行 Content-Type:image / jpeg POST请求,则下面的代码适用于上传图片。

$albumUrl = "https://picasaweb.google.com/data/feed/api/user/$userId/albumid/$albumId";
$imgName = $_SERVER['DOCUMENT_ROOT'] . '/picasa/cute_baby_kitten.jpg';

$rawImgXml = '<entry xmlns="http://www.w3.org/2005/Atom">
              <title>plz-to-love-realcat.jpg</title>
              <summary>Real cat wants attention too.</summary>
              <category scheme="http://schemas.google.com/g/2005#kind"
                term="http://schemas.google.com/photos/2007#photo"/>
            </entry>';

$fileSize = filesize($imgName);
$fh = fopen($imgName, 'rb');
$imgData = fread($fh, $fileSize);
fclose($fh);

$dataLength = strlen($rawImgXml) + $fileSize;
$data = "";
$data .= "\nMedia multipart posting\n";
$data .= "--P4CpLdIHZpYqNn7\n";
$data .= "Content-Type: application/atom+xml\n\n";
$data .= $rawImgXml . "\n";
$data .= "--P4CpLdIHZpYqNn7\n";
$data .= "Content-Type: image/jpeg\n\n";
$data .= $imgData . "\n";
$data .= "--P4CpLdIHZpYqNn7--";

$header = array('GData-Version:  2', $authHeader, 'Content-Type: multipart/related;boundary=P4CpLdIHZpYqNn7', 'Content-Length: ' . $dataLength, 'MIME-version: 1.0');

$ret = "";
$ch  = curl_init($albumUrl);
$options = array(
        CURLOPT_SSL_VERIFYPEER=> false,
        CURLOPT_POST=> true,
        CURLOPT_RETURNTRANSFER=> true,
        CURLOPT_HEADER=> true,
        CURLOPT_FOLLOWLOCATION=> true,
        CURLOPT_POSTFIELDS=> $data,
        CURLOPT_HTTPHEADER=> $header
    );
curl_setopt_array($ch, $options);
$ret = curl_exec($ch);
curl_close($ch);

问题是我一直收到400 Bad Request: Multipart must have Atom and media part错误消息。

以下是我发送的标题:

Array
(
    [0] => GData-Version:  2
    [1] => Authorization:  GoogleLogin auth="THISISAVALIDAUTHCODE"
    [2] => Content-Type: multipart/related;boundary=P4CpLdIHZpYqNn7
    [3] => Content-Length: 179951
    [4] => MIME-version: 1.0
)

这是POST请求正文的样子:

Media multipart posting
--P4CpLdIHZpYqNn7
Content-Type: application/atom+xml

<entry xmlns="http://www.w3.org/2005/Atom">
              <title>plz-to-love-realcat.jpg</title>
              <summary>Real cat wants attention too.</summary>
              <category scheme="http://schemas.google.com/g/2005#kind"
                term="http://schemas.google.com/photos/2007#photo"/>
            </entry>
--P4CpLdIHZpYqNn7
Content-Type: image/jpeg

IMAGE DATA GOES HERE
--P4CpLdIHZpYqNn7--

我想我已经在POST正文中正确放置了换行符,但我不是百分百肯定。我也想知道我是否正确计算了Content-Length

我在这里做错了什么?

1 个答案:

答案 0 :(得分:0)

所以,事实证明 Content-Length的问题。

YouTube API docs的这个小片段解决了它。

  

要计算正确的Content-Length,您需要计算POST请求的完整字符串长度。但是,除了XML组件和文件二进制文件之外,直接上载请求还定义了一个边界字符串,用于分隔请求的不同部分。所以 Content-Length的计算需要考虑XML和文件二进制文件的大小以及插入的边界字符串和换行符的大小

我将Content-Length设置为二进制图像数据和XML的长度之和。我没有计算换行符或边界标记。

所以这一点

'Content-Length: ' . $dataLength

需要改为

'Content-Length: ' . strlen($data)