13

I'm trying to use AWS API Gateway as a proxy in front of an image service. I'm able to get the image to come through but it gets displayed as a big chunk of ASCII because Content-Type is getting set to "application/json".

Is there a way to tell the gateway NOT to change the source Content-Type at all?

I just want "image/jpeg", "image/png", etc. to come through.

kjs3
  • 5,758
  • 8
  • 34
  • 49
  • Why API Gateway? Your image service runs in Lambda? Also, the "source" content-type? Presumably you are referring to the "response." – Michael - sqlbot Jul 25 '15 at 00:17
  • Is there a specific reason that the image must be returned by Lambda? An alternative would be to have the Lambda function upload the image to S3 and return a link to that image. – JaredHatfield Jul 25 '15 at 01:09
  • @Michael-sqlbot: I could throw up a proxy with something else but then I'd need to maintain it. AWS can presumably handle any load I might be able to throw at it. Plus the caching could be useful. The need for a proxy in the first place is google search seeing assets on my page as from my companies other service (SEO guy says they think we're scraping). We need to use the same assets so I just want it to look like they're from a different address. No lambda/manipulation needed for this thing, just a proxy. If you can recommend another service I'd check it out. – kjs3 Jul 25 '15 at 17:30
  • @JaredHatfield: Not using lambda for this. Just [maybe] API Gateway standalone. – kjs3 Jul 25 '15 at 17:31
  • Note that you can't (naively) return binary data through API Gateway. See: http://stackoverflow.com/a/37639963/358224 – Jason Jun 07 '16 at 08:10
  • UPDATE, it's possible now https://aws.amazon.com/blogs/compute/binary-support-for-api-integrations-with-amazon-api-gateway/ – Vlad Holubiev Dec 13 '16 at 11:38

3 Answers3

5

I was trying to format a string to be returned w/o quotes and discovered the Integration Response functionality. I haven't tried this fix myself, but something along these lines should work:

  • Go to the Method Execution page of your Resource,
  • click on Integration Response,
  • expand Method Response Status 200,
  • expand Mapping Templates,
  • click "application/json",
  • click the pencil next to Output Passthrough,
  • change "application/json" to "image/png"

Hope it works!

tgig
  • 143
  • 1
  • 7
  • I'm very suspicious of this answer. Other information seems indicate that it is NOT possible to (reliably) return binary data through API Gateway. – Jason Jun 04 '16 at 03:54
  • looks like this got fixed in the mean time https://aws.amazon.com/about-aws/whats-new/2016/11/binary-data-now-supported-by-api-gateway/ – Damon Smith Apr 17 '18 at 01:07
4

I apologize, in advance, for giving an answer that does not directly answer the question, and instead suggests you adopt a different approach... but based in the question and comments, and my own experience with what I believe to be a similar application, it seems like you may be using the the wrong tool for the problem, or at least a tool that is not the optimal choice within the AWS ecosystem.

If your image service was running inside Amazon Lambda, the need for API Gateway would be more apparent. Absent that, I don't see it.

Amazon CloudFront provides fetching of content from a back-end server, caching of content (at over 50 "edge" locations globally), no charge for the storage of cached content, and you can configure up to 100 distinct hostnames pointing to a single Cloudfront distribution, in addition to the default xxxxxxxx.cloudfront.net hostname. It also supports SSL. This seems like what you are trying to do, and then some.

I use it, quite successfully for exactly the scenario you describe: "a proxy in front of an image service." Exactly what my image service and your image service do may be different (mine is a resizer that can look up the source URL of missing/never before requested images, fetch, and resize) but fundamentally it seems like we're accomplishing a similar purpose.

Curiously, the pricing structure of CloudFront in some regions (such as us-east-1 and us-west-2) is such that it's not only cost-effective, but in fact using CloudFront can be almost $0.005 cheaper than not using it per gigabyte downloaded.

In my case, in addition to the back-end image service, I also have an S3 bucket with a single file in it, attached to a single path in the CloudFront distribution (as a second "custom origin"), for the sole purpose of serving up /robots.txt, to control direct access to my images by well-behaved crawlers. This allows the robots.txt file to be managed separately from the image service itself.

If this doesn't seem to address your need, feel free to comment and I will clarify or withdraw this answer.

Michael - sqlbot
  • 169,571
  • 25
  • 353
  • 427
  • 1
    I hesitate to mark this as the "correct" answer because I am still curious about maintaining Content-Type with AWS API Gateway but this was absolutely helpful and is what I ended up doing. – kjs3 Jul 29 '15 at 15:14
  • @kjs3 I'm glad it helped, and I don't blame you at all. Feel free to hold out for a more direct answer. Your question is interesting and perhaps we'll get an answer that addresses it more precisely. If I get an opportunity to do more extensive testing on AWS API Gateway, I will report on what I find. – Michael - sqlbot Jul 29 '15 at 15:26
3

@kjsc: we finally figured out how to get this working on an alternate question with base64 encoded image data which you may find helpful in your solution:

AWS Gateway API base64Decode produces garbled binary?

To answer your question, to get the Content-Type to come through as a hard-coded value, you would first go into the method response screen and add a Content-Type header and whatever Content type you want.

api gateway method response

Then you'd go into the Integration Response screen and set the Content type to your desired value (image/png in this example). Wrap 'image/png' in single quotes.

enter image description here

Community
  • 1
  • 1
Dave Maple
  • 8,102
  • 4
  • 45
  • 64