Search code examples
angularjsamazon-web-servicesangular-file-upload

Amazon S3 - ERR_INSECURE_RESPONSE


This question has already been asked here but that answer didn't help me as I know that the URL is correct as it points to a US Standard url as detailed in the amazon guide here

So I'm attempting to upload a file to my bucket via the angular library ng-file-upload. I believe that I've setup the bucket correctly:

  • The buckets name is ac.testing
  • The CORS configuration for this:

    <?xml version="1.0" encoding="UTF-8"?>
      < CORSConfiguration xmlns="http://s3.amazonaws.com/doc/2006-03-01/">
      < CORSRule>
        < AllowedOrigin>*</AllowedOrigin>
        < AllowedMethod>POST</AllowedMethod>
        < AllowedHeader>*</AllowedHeader>
      < /CORSRule>
    < /CORSConfiguration>
    

I had to put a space after the opening brackets above as SO didn't let me add it if I didn't.

I've understood this as allow POSTS from any location regardless of heading - is that correct?

And my policy which I generated:

{
    "Version": "2012-10-17",
    "Id": "Policy<numbers>",
    "Statement": [
        {
            "Sid": "Stmt<numbers>",
            "Effect": "Allow",
            "Principal": "*",
            "Action": "s3:PutObject",
            "Resource": "arn:aws:s3:::ac.testing/*"
        }
    ]
}

Finally - in my actual code that attempts to upload:

      var policy = {
        "expiration": "2020-01-01T00:00:00Z",
        "conditions": [
          {"bucket": "ac.testing"},
          ["starts-with", "$key", ""],
          {"acl": "private"},
          ["starts-with", "$Content-Type", ""],
          ["starts-with", "$filename", ""],
          ["content-length-range", 0, 524288000]
        ]
      }

      var uploadDetails = {
        url: 'https://ac.testing.s3.amazonaws.com/',
        method: 'POST',
        data: {
          key: file.name, 
          acl: 'public-read', 
          // application/octet-stream is the default format used by S3
          'Content-Type': file.type != '' ? file.type : 'application/octet-stream', 
          AWSAccessKeyId: '<my-access-key-id>',
          policy: policy, 
          signature: '<my-access-signature>',
          filename: file.name, 
        },
        file: file
      };


      if (file) {
        // Upload to Amazon S3
        file.upload = Upload.upload(uploadDetails).then(function(success) {
          console.log(JSON.stringify(success) );
        },function(error) {
          console.log(error);
        },function(progress) {
          console.log(JSON.stringify(progress) );
        });
      }  

So where am I going wrong here?

EDIT

A couple of things that I wasn't doing was encoding the policy and the signature according to Base64 encoding.

That process involves encoding your policy and then using that generated code, along with your AWS Secret Access Key to generate an SHA-1 HMAC code. Even after this it still returns the same error.

I also added another Permission for the bucket. It matches the policy and CORS settings already defined here but is defined as everyone:

Permission

EDIT 2

I created a new bucket called ac-k24-uploads and updated the url to match this:

uploadDetails = {
    url: 'https://ac-k24-uploads.s3.amazonaws.com/',

Now the error coming back is this:

enter image description here

EDIT 3

Looking around it seems that headers that amazon doesn't like are being added to the request. I tried it on ng-file-uploads and it works but on my own machine it doesn't. The fix for this seems to be removing these headers like so:

method: 'POST',
  headers: {
    'Authorization': undefined
  },

but I still get the same error. Why are these headers being attached to this request?

EDIT 4

Even with the code above the headers were still getting added at a different place so I located it and remove them. The error which I recieve now is this:

enter image description here


Solution

  • The actual problem was two fold:

    • The headers were incorrect as the "Authorization" header was still present even after deleting it from the Upload.upload portion of the code. To fix this I had to delete the object from my api.injector code - this was where it was being added.

      delete config.headers['Authorization']
      
    • Following on from EDIT3 the signature that I generated was wrong - so I had to regenerate it.

    Thanks to Michael for the help.