title: How to use amazonka presignURL
body: <p>I'm trying to get to grips with the <a href="https://github.com/brendanhay/amazonka/" rel="nofollow noreferrer">amazonka</a> library.  I want to pre-sign a PUT request for S3. Looking at the <a href="https://github.com/brendanhay/amazonka/blob/develop/examples/src/Example/S3.hs" rel="nofollow noreferrer">example here</a>, I put together the code below.  It doesn't work when trying to send up a JPEG image from the client side.  AWS complains that the signature is not correct.</p>
  
  <p>My client-side code works with the nodejs aws sdk, so I can only guess that I am configuring things incorrectly here.</p>
  
  <pre><code>&lt;Error&gt;
    &lt;Code&gt;
      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.
    &lt;/Message&gt;
    &lt;CanonicalRequest&gt;
      PUT
      /my-bucket/test.jpg
      X-Amz-Algorithm=AWS4-HMAC-SHA256&amp;X-Amz-
      Credential=[MY_AWS_ACCESS_KEY]%2F20171010%2Feu-west-
      1%2Fs3%2Faws4_request&amp;X-Amz-Date=20171010T084724Z&amp;X-Amz-
      Expires=100000&amp;X-Amz-SignedHeaders=expect%3Bhost
      expect:
      host:s3-eu-west-1.amazonaws.com
  
      expect;host
      UNSIGNED-PAYLOAD
   &lt;/CanonicalRequest&gt;
  ...
  </code></pre>
  
  <p>Here's my code:</p>
  
  <pre><code>getS3UrlR :: Handler Value
  getS3UrlR = do
    y &lt;- getYesod
    let settings = appSettings y
  
    env &lt;- newEnv $ FromKeys (AccessKey $ encodeUtf8 $ appAwsAccessKey settings) (SecretKey $ encodeUtf8 $ appAwsSecretKey settings)
    ts  &lt;- liftIO $ getCurrentTime
  
    let b = BucketName $ appS3Bucket settings
        k = ObjectKey "profile-pic-test"
    url &lt;- liftIO $ runResourceT . runAWST env . within Ireland $ presignURL ts 100000 (putObject b k (toBody ("" :: ByteString)))
    return $ toJSON $ decodeUtf8 url
  </code></pre>
  
  <p>How can I go about debugging this?</p>
  
  <p>Note - <code>putObject</code> requires a <code>RqBody</code> argument, but I don't have one to provide (as the client is going to supply the request body).  So I just supplied an empty string.  Could that be a problem?</p>
  
  <p>Edit - I tried signing a GET request to see if that would work.  It works fine!  But PUT does not. This is the changed line that works fine:</p>
  
  <pre><code>url &lt;- liftIO $ runResourceT . runAWST env . within Ireland $ presignURL ts 100000 (getObject b k)
  </code></pre>