title: Vimeo API : streaming upload using HTTP PUT and blueimp's jQuery fileupload
body: <p>I'm trying to implement an upload module on a website which would allow our users to upload videos to our Vimeo account. I'm using blueimp's jQuery File upload and Vimeo's new API.
  <a href="https://github.com/blueimp/jQuery-File-Upload/wiki/Options" rel="noreferrer">https://github.com/blueimp/jQuery-File-Upload/wiki/Options</a>
  <a href="https://developer.vimeo.com/api/upload#http-put-uploading" rel="noreferrer">https://developer.vimeo.com/api/upload#http-put-uploading</a>
  I think it's close to be working but I must be missing some detail.
  According to Vimeo's API, I need to :
  1. Generate an upload ticket, which works fine
  2. I then pass the upload_link_secure to jquery file upload which starts uploading. This is what the requests headers for the PUT request look like :</p>
  
  <pre><code>Request Method:PUT
  Status Code:200 OK
  Accept:*/*
  Accept-Encoding:gzip,deflate,sdch
  Accept-Language:fr-FR,fr;q=0.8,en-US;q=0.6,en;q=0.4
  Connection:keep-alive
  Content-Length:43418955
  Content-Type:multipart/form-data; boundary=----WebKitFormBoundarye8sGy57JH6ACoOfJ
  </code></pre>
  
  <p>This is how I call jQuery file upload :</p>
  
  <pre><code>$('#file').fileupload({
  url: upload_link_secure,
  type: 'PUT'
  });
  </code></pre>
  
  <p>I also tried forcing the Content-Type header to "video/mp4" but it doesn't make any difference in the end.</p>
  
  <p>I also checked the size of the file by binding jquery fileupload's submit event and I also get a lower bytes count than what's sent in the headers, 43418764 in this example, is this okay ?</p>
  
  <ol start="3">
  <li>Verify the upload by sending PUT requests on upload_link_secure, some response headers I get :</li>
  </ol>
  
  <blockquote>
    <p>Status Code:308 Resume Incomplete</p>
    
    <p>Range:bytes=0-3948544</p>
    
    <p>Status Code:308 Resume Incomplete</p>
    
    <p>Range:bytes=0-38682624</p>
    
    <p>Status Code:308 Resume Incomplete</p>
    
    <p>Range:bytes=0-43401216</p>
  </blockquote>
  
  <ol start="4">
  <li>Make sure all the bytes made it to Vimeo, then complete the upload by sending a DELETE request on complete_uri
  I get this last header when verifying the upload :</li>
  </ol>
  
  <blockquote>
    <p>Range:bytes=0-43418955</p>
  </blockquote>
  
  <p>It seems to match the Content-Length send in the first request so I perform a DELETE request, and this is the reponse I get :</p>
  
  <blockquote>
    <p>{"body":{"error":"Your video file is not valid. Either you have uploaded an invalid file format, or your upload is incomplete. Make sure you verify your upload before marking it as complete."},"status":400,"headers":{"Date":"Mon, 06 Oct 2014 17","Server":"Apache","Vary":"Accept,Vimeo-Client-Id,Accept-Encoding","Cache-Control":"no-cache, max-age=315360000","Expires":"Thu, 03 Oct 2024 17","Content-Length":"184","X-Cnection":"close","Content-Type":"application/vnd.vimeo.error+json","Via":"1.1 dca1-10"}} </p>
  </blockquote>
  
  <p>I must have made a very dumb mistake but I'm not very familiar with all those HTTP requests and reponses, does anybody know what I did wrong ?</p>
  
  <p>Thanks !</p>
  
  <p><strong>[edit]</strong> Thanks a lot Dashron, I actually had to set jQuery fileupload's multipart option to false :</p>
  
  <pre><code>$('#file').fileupload({
          url: upload_link_secure,
          type: 'PUT',
          multipart: false
      });
  </code></pre>
  
  <p>After that, I was getting this HTTP error :</p>
  
  <pre><code>XMLHttpRequest cannot load https://1511632921.cloud.vimeo.com/upload?[...]. Request header field Content-Disposition is not allowed by Access-Control-Allow-Headers. 
  </code></pre>
  
  <p><s>There might be a clean fix for that but I didn't find it so I simply commented the lines that set the Content-Disposition header in jquery.fileupload.js</p>
  
  <pre><code>// if (!multipart || options.blob || !this._isInstanceOf('File', file)) {
  //     options.headers['Content-Disposition'] = 'attachment; filename="' +
  //         encodeURI(file.name) + '"';
  // }
  </code></pre>
  
  <p></s>
  (see <strong>edit3</strong>)</p>
  
  <p>Now it works fine ! :)</p>
  
  <p><strong>[edit2]</strong> I was asked for a more complete example of the code I came up with to make that PUT upload work so here is a Gist containing the relevant Twig template from my Symfony application. I hope it's clear enough and that it can help. The code can probably be improved a lot but I guess it's an okay starting point. <a href="https://gist.github.com/paulgv/13ff6d194bc0d662de7b" rel="noreferrer">https://gist.github.com/paulgv/13ff6d194bc0d662de7b</a></p>
  
  <p><strong>[edit3]</strong> I also realize that I never updated my code with a cleaner fix for the issue I had with the <code>Content-Disposition</code> header (see crossed out text above). Thanks to <strong><a href="https://github.com/blueimp" rel="noreferrer">blueimp</a></strong>'s help, I found out that you can simply remove this header in <code>fileuploadsend</code> callback :</p>
  
  <pre><code>.bind('fileuploadsend', function (e, data) {
      data.headers = {};
  })
  </code></pre>