title: S3 Pre-signed URL with custom endpoint via API Gateway, MethodNotAllowed
body: <p>I'm attempting to use a pre-signed url for an S3 bucket with a custom endpoint. I seem so close, but I keep getting a Method Not Allowed error. Here's where I'm at.</p>
  
  <p>I have an API Gateway which connects an endpoint to a Lambda function. That function, among other things, generates a pre-signed url. Like so,</p>
  
  <pre><code>var s3 = new AWS.S3({
      endpoint: 'custom.domain.com/upload',
      s3BucketEndpoint: true,
      signatureVersion: 'v4'
  });
  
  //...
  
  s3.getSignedUrl('putObject', {
      ACL: 'bucket-owner-full-control',
      Bucket: process.env.S3_BUCKET_NAME,
      ContentType: "image/png",
      Key: asset.id + ".png"
  };
  </code></pre>
  
  <p>This code successfully returns a url with what appears to be all the correct query params, correct key name, and the url is pointing to my endpoint. When attempting to upload however, I receive the following error:</p>
  
  <blockquote>
    <p>
    <Code>MethodNotAllowed</Code>The specified method is not allowed against this resource.PUTSERVICE[request id was here][host id was here]</p>
  </blockquote>
  
  <p>If I remove my custom endpoint declaration from my S3 config, I receive a standard domain prefixed pre-signed url and the upload works fine.</p>
  
  <p>Other notes on my setup.</p>
  
  <ol>
  <li>I have configured the /upload resource on API Gateway to be an S3 passthrough for the PUT method.</li>
  <li>I have enabled CORS where needed. On the bucket and on my API. I have confirmed CORS is good, as the browser passes checks.</li>
  <li>I have setup my policies. The lambda function has access to the internet from my VPC, it has full S3 access, and it has a trust relationship with both S3 and API Gateway. This execution role is shared amongst the resources.</li>
  <li>I am using the axios package to upload the file via PUT.</li>
  <li>I have added a CloudTrail log, but it reports the exact same error as the browser...</li>
  <li>Temporarily making my bucket public makes no difference.</li>
  <li>I've attempted to add the query strings to the API Gateway Request/Response integrations without success.</li>
  <li>I've added the necessary content type headers to the request and to the pre-signed url config.</li>
  <li>I Googled the heck out of this thing.</li>
  </ol>
  
  <p>Am I missing something? Is this possible? I plan to disable my custom endpoint and move forward with the default pre-signed url for the time being, but long term, I would like the custom endpoint. Worst case I may pay for some AWS support. </p>
  
  <p>Thanks for the help!</p>