title: AWS signed URL too long to shorten
body: <p>I am creating a signed URL with AWS so I can safely pass this URL to another API for temporary use. The signed URL points to a S3 resource. The problem is the other API does not accept such long links. Therefore I am trying to shorten it. I tried to use shorteners like <a href="http://goo.gl" rel="nofollow noreferrer">goo.gl</a> or <a href="http://bit.ly" rel="nofollow noreferrer">bit.ly</a> to no avail because the URL was too long for them. I even built my own private shortener with AWS (<a href="https://aws.amazon.com/blogs/compute/build-a-serverless-private-url-shortener/" rel="nofollow noreferrer">AWS url shortener</a>) but it had the same problem: "The length of website redirect location cannot exceed 2,048 characters.".</p>
  
  <p>I am creating the signed URLs in iOS (Swift) with <code>AWSS3PreSignedURLBuilder.default().getPreSignedURL(preSignedURLRequest)</code> while using AWS Cognito as an unauthorised user. </p>
  
  <p>I have tried the following things to no avail: </p>
  
  <ul>
  <li>Choose the shortest possible S3 bucket name with 3 characters</li>
  <li>Shorten the filename as much as possible. I limited the file name to 10 characters plus file extension name (14 characters in total). Shorter file names are not viable for me because they should be unique to a certain extent.</li>
  </ul>
  
  <p>But even with all these minor tweaks the signed URL returned by AWS is sometimes too long. Especially the token parameter (X-Amz-Security-Token) seems to be really long. With my minor tweaks I sometimes get URLs shorter than 2,048 characters but sometimes slightly longer. I would like to find a solution which guarantees me that the URL is not too long and can be shortened.</p>
  
  <p>In my own private AWS URL shortener the following code snippet creates the S3 object which redirects to the actual long URL.</p>
  
  <p><div class="snippet" data-lang="js" data-hide="false" data-console="true" data-babel="false">
  <div class="snippet-code">
  <pre class="snippet-code-js lang-js prettyprint-override"><code>s3.putObject({
      Bucket: s3_bucket,
      Key: key_short,
      Body: "",
      WebsiteRedirectLocation: url_long,
      ContentType: "text/plain"
    },
    (err, data) =&gt; {
      if (err) {
        console.log(err);
        done("", err.message);
      } else {
        const ret_url = "https://" + cdn_prefix + "/" + id_short;
        console.log("Success, short_url = " + ret_url);
        done(ret_url, "");
      }
    });</code></pre>
  </div>
  </div>
  </p>
  
  <p>The method returns with the following error</p>
  
  <blockquote>
    <p>The length of website redirect location cannot exceed 2,048
    characters.</p>
  </blockquote>
  
  <p>The documentation of putObject for the header "x-amz-website​-redirect-location" in the object meta states the following (<a href="http://docs.aws.amazon.com/AmazonS3/latest/API/RESTObjectPUT.html" rel="nofollow noreferrer">see: put object documentation</a>):</p>
  
  <blockquote>
    <p>The length of the value is limited to 2 KB</p>
  </blockquote>
  
  <p><strong>How can I make sure that the initial AWS signed URL is not too long for the URL shorteners?</strong></p>
  
  <p><strong>EDIT:</strong></p>
  
  <p>One of the problems I have identified is that I create the signed URL as an unauthenticated user in AWS Cognito. Therefore the signed URL includes this ridiculously long token as a parameter. I did not want to embed my accessKey and shortKey in the iOS App thats why I switched to AWS Cognito (see <a href="https://aws.amazon.com/blogs/mobile/how-amazon-cognito-keeps-mobile-app-users-data-safe/" rel="nofollow noreferrer">aws cognito</a>). But currently there are no authorised users just unauthorised ones and I need to create the signed URL as an unauthorised AWS Cognito user. If I create the signed URL with with a regular credentials using accessKey and shortKey I get a much shorter URL. But for that I would have to embed my accessKey and shortKey in the iOS app which is not recommended.</p>