Actually, you do not have to disable Lambda Proxy Integration, nor do you have to specify "*/*" as a Binary Media Type, nor do you have to have your Lambda code convert the output to Base64, nor do you have to modify LambdaEntryPoint in order to get this to work.
Although some sources indicate that the "*/*" entry is necessary, the answer lies in the comment accompanying the Binary Media Types setting:
"API Gateway will look at the Content-Type and Accept HTTP headers to
decide how to handle the body."
In other words, for some odd reason, rather than just paying attention to the returned Content-Type in applying the Binary Media Types list, the gateway also takes into account the requesting client's Accept header. Most clients default to Accept:*/*, thus the origin of the workaround, and the most common explanation as to why this list doesn't seem to work. Not only does the client's Accept header seem to be given more credence than the returned Content-Type value here, there is no semantic assessment of "*/*". It is not evaluated as a wildcard, which should match any content type. Thus, an exact match of said value, literally "*/*", winds up being needed in the Binary Media Types list.
A simple solution (one which works for me) is to:
- Have the client, instead of specifying "*/*" in its Accept header, specify the actual expected MIME type. (Do not specify multiple Accept types, as only the first listed type is evaluated.)
- Include the same MIME type in the Binary Media Types list. Do not specify "*/*".
- Have the Lambda function return a non-Base64-encoded binary file, specifying its actual MIME type in the Content-Type header.
For instance, in C#, by returning a
FileContentResult from the ControllerBase.File() method, specifying the appropriate MIME content type, as in:
return File(pdfContents, "application/pdf"); //pdfContents contains raw binary data
API Gateway will match the data type to its Binary Media Types list and regard the returned data as binary. So far, I have not needed to insert RegisterResponseContentEncodingForContentType() in LambdaEntryPoint.Init().