title: YouTube direct upload using ClientLogin via Android
body: <p>I have to make an application which uploads videos for specific YouTube user. I've tried several libraries but unfortunately without any success. So since what I want to do is really very simple, I've decided to do it on my own, but with not much luck until now. I am able to retrieve authentication token successfully, but couldn't manage to make the file upload work. Here is my code:</p>
  
  <pre><code>    File file = new File(videoPath);
     String boundary = "f93dcbA3";
     String endLine = "\r\n";
  
     StringBuilder sb = new StringBuilder();
     sb.append("--");
     sb.append(boundary);
     sb.append(endLine);
     sb.append("Content-Type: application/atom+xml; charset=UTF-8"); 
     sb.append(endLine);
     sb.append(endLine);
     sb.append(entry);
     sb.append(endLine);
     sb.append("--");
     sb.append(boundary);
     sb.append(endLine);
     sb.append("Content-Type: video/3gpp");
     sb.append(endLine);
     sb.append("Content-Transfer-Encoding: binary");
     sb.append(endLine);
     sb.append(endLine);
  
     String bodyStart = sb.toString();
  
     sb = new StringBuilder();
     sb.append(endLine);
     sb.append("--");
     sb.append(boundary);
     sb.append("--");
  
     String bodyEnd = sb.toString();
  
     HttpURLConnection conn;
     try {
      FileInputStream fIn = new FileInputStream(file);
      byte fileBytes[] = new byte[(int) file.length()];
      fIn.read(fileBytes);
  
      conn = (HttpURLConnection) new URL("http://uploads.gdata.youtube.com/feeds/api/users/" + username + "/uploads")
        .openConnection();
  
      conn.setRequestMethod("POST");
               conn.setRequestProperty("Content-Type", "multipart/related; boundary=\"" + boundary + "\"");
               conn.setRequestProperty("Host", "uploads.gdata.youtube.com");
               conn.setRequestProperty("Authorization", "GoogleLogin auth=" + auth);
               conn.setRequestProperty("GData-Version", "2");
               conn.setRequestProperty("X-GData-Key", "key=" + devKey);
               conn.setRequestProperty("Slug", "video.3gp");
               conn.setRequestProperty("Content-Length", "" + (bodyStart.getBytes().length
                  + fileBytes.length + bodyEnd.getBytes().length)); 
               conn.setRequestProperty("Connection", "close");
  
               conn.setDoOutput(true);
               conn.setDoInput(true);
               conn.setUseCaches(false);
               try {
       conn.connect();
  
       Log.d("ID", "" + file.length());
  
       try {
        OutputStream os = new BufferedOutputStream(conn.getOutputStream());
  
        os.write(bodyStart.getBytes());
                 os.write(fileBytes);
                 os.write(bodyEnd.getBytes());
                 os.flush();
  
                 String response = "";
                 try {
                  response = "Success! " + read(conn.getInputStream());
                 } catch (FileNotFoundException e) {
                     // Error Stream contains JSON that we can parse to a FB error
                     response = "Error!" + read(conn.getErrorStream());
                 }
  
                 Log.d("ID", response);
  
       } catch (FileNotFoundException e1) {
        Log.d("ID", e1.getMessage(), e1);
       } catch (IOException e) {
        Log.d("ID", e.getMessage(), e);
       }
      } catch (IOException e2) {
       Log.d("ID", e2.getMessage(), e2);
      }
     } catch (MalformedURLException e3) {
      Log.d("ID", e3.getMessage(), e3);
     } catch (IOException e3) {
      Log.d("ID", e3.getMessage(), e3);
     }
  </code></pre>
  
  <p>And the xml entry (a simple copy-paste from the specification):</p>
  
  <pre><code>     private static String entry = "&lt;?xml version=\"1.0\"?&gt;"
    + "&lt;entry xmlns=\"http://www.w3.org/2005/Atom\""
    + " xmlns:media=\"http://search.yahoo.com/mrss/\""
    + " xmlns:yt=\"http://gdata.youtube.com/schemas/2007\"&gt;"
     + "&lt;media:group&gt;"
      + "&lt;media:title type=\"plain\"&gt;Bad Wedding Toast&lt;/media:title&gt;"
      + "&lt;media:description type=\"plain\"&gt;"
       + "I gave a bad toast at my friend's wedding. Maybe"
      + "&lt;/media:description&gt;"
      + "&lt;media:category"
      + " scheme=\"http://gdata.youtube.com/schemas/2007/categories.cat\"&gt;People"
      + "&lt;/media:category&gt;"
      + "&lt;media:keywords&gt;toast, wedding&lt;/media:keywords&gt;"
     + "&lt;/media:group&gt;"
    + "&lt;/entry&gt;";
  </code></pre>
  
  <p>The code above is written according to the <a href="http://code.google.com/intl/bg/apis/youtube/2.0/developers_guide_protocol_direct_uploading.html#Sending_a_Direct_Upload_API_Request" rel="nofollow">YouTube specification</a>
  In short - the response I receive is "411 Length Required", meaning that I don't have Content-Length in the header, but I do! I have no idea where the problem is, I don't know if any of my code is correct :(
  I'd appreciate any help you could offer me :(</p>