title: PUT to S3 with presigned url gives 403 error
body: <p>I'm using Node to get an presignedRUL for S3 in order to PUT an image to an S3 bucket.</p>
  
  <pre><code>var aws = require('aws-sdk');
  // Request presigned URL from S3
  exports.S3presignedURL = function (req, res) {
    var s3 = new aws.S3();
    var params = {
      Bucket: process.env.S3_BUCKET, 
      Key: '123456', //TODO: creat unique S3 key
      //ACL:'public-read',
      ContentType: req.body['Content-Type'], //'image/jpg'
    };
    s3.getSignedUrl('putObject', params, function(err, url) {
        if(err) console.log(err);
        res.json({url: url});
    });
  };
  </code></pre>
  
  <p>This successfully retrieves a presigned url of form...</p>
  
  <p><a href="https://[my-bucket-name].s3.amazonaws.com/1233456?AWSAccessKeyId=[My-ID]&amp;Expires=1517063526&amp;Signature=95eA00KkJnJAgxdzNNafGJ6GRLc%3D" rel="noreferrer">https://[my-bucket-name].s3.amazonaws.com/1233456?AWSAccessKeyId=[My-ID]&amp;Expires=1517063526&amp;Signature=95eA00KkJnJAgxdzNNafGJ6GRLc%3D</a>
  (Do I have to include an expires header?)</p>
  
  <p>Back on the client side (web app) I use angular to generate an HTTP request.  I have used both $http and ngFileUpload, with similar lack of success.  Here is my ngFileUpload code.</p>
  
  <pre><code>Upload.upload({
      url: responce.data.url, //S3 upload url including bucket name
      method: 'PUT',
      'Content-Type': file.type, //I have tried putting the ContentTyep header all over
      headers: { 
          //'x-amz-acl':'public-read',
          'Content-Type': file.type, 
      }, 
      data: { 
          file: file,
          headers:{'Content-Type': file.type,}
      },                         
  })
  </code></pre>
  
  <p>However, seemingly regardless of how I format my header I always get a 403 error.  In the XML of the error it says, </p>
  
  <pre><code>SignatureDoesNotMatch&lt;/Code&gt;&lt;Message&gt;The request signature we calculated does not match the signature you provided. Check your key and signing method.
  </code></pre>
  
  <p>I don't think CORS is an issue.  Originally I was getting some CORS errors but they looked different and I got them to go away with some changes to the S3 bucket CORS settings.  I've tried a lot of trial and error setting of the headers for both the request for the presignedURL and PUT request to S3, but I can't seem to find the right combo.  </p>
  
  <p>I did notice that when I console.log the 403 response error, the field </p>
  
  <pre><code>config.headers:{Content-Type: undefined, __setXHR_: ƒ, Accept: "application/json, text/plain, */*"}
  </code></pre>
  
  <p>Is this saying that the Content-Type head isn't set?  How can that be when I've set that header everywhere I can think possible?  Anyways, been banging my head against the wall of this for a bit...</p>
  
  <hr>
  
  <p>EDIT: as requested, my Current CORS.  (I threw everything in to get rid of the CORS warnings I had earlier.  I will pare it down to the essentials only after I get my uploads working.)</p>
  
  <pre><code>&lt;?xml version="1.0" encoding="UTF-8"?&gt;
  &lt;CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/"&gt;
  &lt;CORSRule&gt;
      &lt;AllowedOrigin&gt;*&lt;/AllowedOrigin&gt;
      &lt;AllowedOrigin&gt;http://localhost:9500&lt;/AllowedOrigin&gt;
      &lt;AllowedOrigin&gt;https://localhost:9500&lt;/AllowedOrigin&gt;
      &lt;AllowedOrigin&gt;http://www.example.com&lt;/AllowedOrigin&gt;
      &lt;AllowedOrigin&gt;https://www.example.com&lt;/AllowedOrigin&gt;
      &lt;AllowedOrigin&gt;http://lvh.me:9500&lt;/AllowedOrigin&gt;
      &lt;AllowedMethod&gt;GET&lt;/AllowedMethod&gt;
      &lt;AllowedMethod&gt;PUT&lt;/AllowedMethod&gt;
      &lt;AllowedMethod&gt;POST&lt;/AllowedMethod&gt;
      &lt;MaxAgeSeconds&gt;3000&lt;/MaxAgeSeconds&gt;
      &lt;ExposeHeader&gt;ETag&lt;/ExposeHeader&gt;
      &lt;AllowedHeader&gt;*&lt;/AllowedHeader&gt;
      &lt;AllowedHeader&gt;Content-Type&lt;/AllowedHeader&gt;
      &lt;AllowedHeader&gt;Authorization&lt;/AllowedHeader&gt;
  &lt;/CORSRule&gt;
  &lt;/CORSConfiguration&gt;
  </code></pre>