title: YouTube API - Direct Upload - 413 Request Entity Too Large
body: <p>I've been trying to upload videos to the YouTube API via direct upload. I finally cracked the OAuth Process and I have a valid token. I really only need to do 2 things with YouTube, Authenticate and upload. I am not browsing, or using any of the other functionality. Users upload videos to this website, and I send them to YouTube for playback.</p>
  
  <p>I feel like I've come 80-90% of the way on my own here, so I do not want to scrap this and use the Zend Library that Google provides.</p>
  
  <p>Problem:
  When I send the request I get this response:</p>
  
  <pre><code>HTTP/1.1 413 Request Entity Too Large
  Content-Type: text/html; charset=UTF-8
  Content-Length: 171
  Date: Thu, 18 Apr 2013 18:33:22 GMT
  Expires: Thu, 18 Apr 2013 18:33:22 GMT
  Cache-Control: private, max-age=0
  X-Content-Type-Options: nosniff
  X-Frame-Options: SAMEORIGIN
  X-XSS-Protection: 1; mode=block
  Server: GSE
  Connection: close
  </code></pre>
  
  <p>If I turn on the warnings, I also get a Broken Pipe warning, which is probably just the code trying to upload the data through the closed/refused connection.</p>
  
  <p>My request is this:</p>
  
  <pre><code>POST /feeds/api/users/default/uploads HTTP/1.1 
  Host: gdata.youtube.com Connection: close 
  User-Agent: PHP Accept-encoding: identity 
  Authorization: Bearer &lt;TOKEN IS HERE&gt; 
  GData-Version: 2.0 
  X-GData-Key: key=&lt;MYKEYISHERE&gt;
  Slug: throwing_can.mp4 
  Content-Type: multipart/related; boundary="5170429d1b193" 
  Content-Length: 3920610 
  </code></pre>
  
  <p>With the file itself chunked and written to the stream.</p>
  
  <pre><code>function ytapi_write_file($handle, $path, $chunksize = 8192){
      $filehandle = fopen($path, 'r');
      while(!feof($filehandle)){
          fwrite($handle, fread($filehandle, $chunksize));
      }
      fclose($filehandle);
      $filehandle = null;
  }
  
  function ytapi_write($handle, $request){
      fwrite($handle, $request);
      return $request;
  }
  </code></pre>
  
  <p>Like so.</p>
  
  <pre><code>ytapi_write($handle, $start); //This writes the header.
  ytapi_write_file($handle, $path, 8192); //This writes the file raw/binary.
  ytapi_write($handle, $end); //This writes the final boundary.
  </code></pre>
  
  <p>Also, I use this for the header info:</p>
  
  <pre><code>$_header = array(
      'Host'=&gt;'gdata.youtube.com',
      'Connection'=&gt;'close',
      'User-Agent'=&gt;'PHP',
      'Accept-encoding'=&gt;'identity'
  );
  </code></pre>
  
  <p>Any idea as to what I'm doing wrong? I can provide more information if needed. The file I am uploading is a little over 3MB, a file that is sitting on the server in question. I've verified the location is correct.</p>
  
  <h2>UPDATE</h2>
  
  <p>Changed to uploads.gdata.youtube.com</p>
  
  <p>Now I get this error message:</p>
  
  <pre><code>Host: uploads.gdata.youtube.com
  Connection: close
  User-Agent: PHP
  Accept-encoding: identity
  tcp://uploads.gdata.youtube.com:80HTTP/1.1 400 Bad Request
  Server: HTTP Upload Server Built on Apr 8 2013 13:06:58 (1365451618)
  X-GData-User-Country: US
  Content-Type: application/vnd.google.gdata.error+xml
  X-GUploader-UploadID: &lt;SOME ID&gt;
  Date: Thu, 18 Apr 2013 19:42:14 GMT
  Pragma: no-cache
  Expires: Fri, 01 Jan 1990 00:00:00 GMT
  Cache-Control: no-cache, no-store, must-revalidate
  Content-Length: 228
  Connection: close
  </code></pre>