cURL / Mailing Lists / curl-library / Single Mail

curl-library

Re: Re: Uploading with POST and read_callback not just a file

From: Oleksiy <patriot_of_ua_at_ukr.net>
Date: Tue, 20 Sep 2011 17:05:00 +0300
('binary' encoding is not supported, stored as-is) ('binary' encoding is not supported, stored as-is)    Julien Chaffraix: header and body of the post request is right, if
   they are other - nothing works. They are according to the official
   Google manual
   http://code.google.com/apis/youtube/2.0/developers_guide_protocol_direct_uploading.html#Sending_a_Direct_Upload_API_Request

>

>

   Daniel Stenberg: with debug-callback I found out that for some reason
   only header is sent, and body isn't

>

>

   == Info: About to connect() to uploads.gdata.youtube.com port 80 (#0)
   => Send header, 0000000061 bytes (0x0000003d)
   0000: About to connect() to uploads.gdata.youtube.com port 80 (#0).
   == Info: Trying 74.125.39.117... => Send header, 0000000026 bytes
   (0x0000001a)
   0000: Trying 74.125.39.117...
   == Info: connected
   => Send header, 0000000010 bytes (0x0000000a)
   0000: connected.
   == Info: Connected to uploads.gdata.youtube.com (74.125.39.117) port
   80 (#0)
   => Send header, 0000000068 bytes (0x00000044)
   0000: Connected to uploads.gdata.youtube.com (74.125.39.117) port 80 (
   0040: #0).
   => Send header, 0000000577 bytes (0x00000241)
   0000: GET /feeds/api/users/default/uploads HTTP/1.1
   002f: Accept: */*
   003c: Host: uploads.gdata.youtube.com
   005d: Authorization: GoogleLogin auth=D***kyPw
   014a: GData-Version: 2
   015c: X-GData-Key: key=AI3***kQQ
   01d1: Slug: video
   01de: Content-Type: multipart/related; boundary="d31fcjR2"
   0214: Content-Length: 910286
   022c: Connection: close
   023f:
   == Info: HTTP 1.0, assume close after body
   => Send header, 0000000034 bytes (0x00000022)
   0000: HTTP 1.0, assume close after body.
   <= Recv header, 0000000026 bytes (0x0000001a)
   0000: HTTP/1.0 400 Bad Request
   <= Recv header, 0000000040 bytes (0x00000028)
   0000: Content-Type: text/html; charset=UTF-8
   <= Recv header, 0000000023 bytes (0x00000017)
   0000: Content-Length: 11782
   <= Recv header, 0000000037 bytes (0x00000025)
   0000: Date: Tue, 20 Sep 2011 14:01:48 GMT
   <= Recv header, 0000000017 bytes (0x00000011)
   0000: Server: GFE/2.0
   <= Recv header, 0000000002 bytes (0x00000002)
   0000:
   <= Recv data, 0000004096 bytes (0x00001000)
   0000: <!DOCTYPE html>.<html lang=en>. <meta charset=utf-8>. <title>E
   0040: rror 400 (Bad Request)!!1</title>. <style>. *{margin:0;paddi

>

>

>

>

>

   ============================

>

>

   original message was:

>

>

>

   I'm uploading a file to yutube. As file can be very large, I don't
   want to load it all in the buffer, but in parts. With this working
   pieces of code I did uploading, loading whole file into the char *
   buffer. POST request is described here -
   http://code.google.com/apis/youtube/2.0/developers_guide_protocol_direct_uploading.html#Sending_a_Direct_Upload_API_Request

   ****

   body.append("--d31fcjR2\r\n");
   body.append("Content-Type: application/atom+xml; charset=UTF-8\r\n");
   body.append("\r\n");
   body.append("<?xml version=\"1.0\"?>\r\n");
   body.append("<entry xmlns=\"http://www.w3.org/2005/Atom\"\r\n");
   body.append("xmlns:media=\"http://search.yahoo.com/mrss/\"\r\n");
   body.append("xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">\r\n");
   body.append("<media:group>\r\n");
   body.append("<media:title type=\"plain\"> title </media:title>\r\n ");
   body.append("<media:description type=\"plain\">\r\n");
   body.append(" description \r\n");
   body.append("</media:description>\r\n");
   body.append("<media:category\r\n");
   body.append("scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">People\r\n");
   body.append("</media:category>\r\n");
   body.append("<media:keywords> keywords </media:keywords>\r\n ");
   body.append("</media:group>\r\n");
   body.append("</entry>\r\n");
   body.append("--d31fcjR2\r\n");
   body.append("Content-Type: video/H264\r\n");//content type
   body.append("Content-Transfer-Encoding: binary\r\n");
   body.append("\r\n");
   body.append(buffer, size);//*********file
   body.append("\r\n");

   body.append("--d31fcjR2--");

   ****

   curl_easy_setopt(curl, CURLOPT_URL, urlUpload);
   curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
   curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, body.length());
   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);//setting header
   curl_easy_setopt(curl, CURLOPT_POSTFIELDS, body.c_str());//setting
   body

   ***

   To load file to a buffer by parts as I have read the manual I must use
   read_callback. Problem is that I have to send some parts of xml before
   and after the file. So I change that code to this:

   ***

   FILE *file = fopen(path, "rb");

   ***

   curl_easy_setopt(curl, CURLOPT_URL, urlUpload);
   curl_easy_setopt(curl, CURLOPT_ERRORBUFFER, errorBuffer);
   curl_easy_setopt(curl, CURLOPT_VERBOSE, 1L);//additional information,
   for debug
   //curl_easy_setopt(curl, CURLOPT_POSTFIELDSIZE_LARGE, body.length());
   // I have tried with and without it, passing it manually real size of
   the body
   curl_easy_setopt(curl, CURLOPT_HTTPHEADER, header);//setting header
   curl_easy_setopt(curl, CURLOPT_READFUNCTION, ReadCallback); // use our
   own read function
   curl_easy_setopt(curl, CURLOPT_READDATA, file);//specify what data
   will be uploaded

   size_t ReadCallback(void *ptr, size_t size, size_t nmemb, void
   *userdata)
   {
   FILE* file = (FILE *)userdata;
   size_t retcode;
   string body;
   if(beginning == 0)
   {
   body.append("--d31fcjR2\r\n");
   body.append("Content-Type: application/atom+xml; charset=UTF-8\r\n");
   body.append("\r\n");
   body.append("<?xml version=\"1.0\"?>\r\n");
   body.append("<entry xmlns=\"http://www.w3.org/2005/Atom\"\r\n");
   body.append("xmlns:media=\"http://search.yahoo.com/mrss/\"\r\n");
   body.append("xmlns:yt=\"http://gdata.youtube.com/schemas/2007\">\r\n");
   body.append("<media:group>\r\n");
   body.append("<media:title type=\"plain\">Test
   title</media:title>\r\n");//title
   body.append("<media:description type=\"plain\">\r\n");
   body.append("Description\r\n");//description
   body.append("</media:description>\r\n");
   body.append("<media:category\r\n");
   body.append("scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\">People\r\n");//category
   http://code.google.com/apis/youtube/2.0/reference.html#youtube_data_api_tag_media:category
   body.append("</media:category>\r\n");
   body.append("<media:keywords>ara,arara</media:keywords>\r\n");//keywords
   body.append("</media:group>\r\n");
   body.append("</entry>\r\n");
   body.append("--d31fcjR2\r\n");
   body.append("Content-Type: video/H264\r\n");//content type
   body.append("Content-Transfer-Encoding: binary\r\n");
   body.append("\r\n");
   beginning++;
   retcode = body.length();
   ptr = &body;
   }
   else
   retcode = fread(ptr, size, nmemb, file);

   if(retcode == 0 and beginning == 1)
   {
   beginning++;
   body.append("\r\n");
   body.append("--d31fcjR2--");
   retcode = body.length();
   ptr = &body;
   }

   return retcode;
   }

   And this doesn't work, I'm receiving Error 400 (Bad Request). I'm for
   sure form post body wrong

>

('binary' encoding is not supported, stored as-is) -------------------------------------------------------------------
List admin: http://cool.haxx.se/list/listinfo/curl-library
Etiquette: http://curl.haxx.se/mail/etiquette.html
Received on 2011-09-20