Repository: awslabs/aws-lambda-rust-runtime (language: rust)

Issue:
Cannot return svg image from lambda endpoint
I am trying to create a lambda service that returns a svg based on a Jira ticket. I have everything I need to create the svg, and I got my lambda service running in AWS. The problem I am having is that the endpoint will only return a base64 encoded version of the data. I am not sure what is going wrong, but I created this example project to show what is going on.

https://github.com/aquacash5/svg-aws-rs-example

## Raw binary response
```rust
async fn function_handler(_event: Request) -> Result<Response<Body>, Error> {
    let svg_doc = create_svg();
    let mut svg_data: Vec<u8> = Vec::new();
    svg::write(&mut svg_data, &svg_doc)?;
    let resp = Response::builder()
        .status(200)
        .header("content-type", "image/svg+xml")
        .body(svg_data.into())
        .map_err(Box::new)?;
    Ok(resp)
}
```

## Convert to string first
```rust
async fn function_handler(_event: Request) -> Result<Response<Body>, Error> {
    let svg_doc = create_svg();
    let mut svg_data: Vec<u8> = Vec::new();
    svg::write(&mut svg_data, &svg_doc)?;
    let svg_str = String::from_utf8(svg_data)?;
    let resp = Response::builder()
        .status(200)
        .header("content-type", "image/svg+xml")
        .body(svg_str.into())
        .map_err(Box::new)?;
    Ok(resp)
}
```

Both versions produce the same result.


Discussion / hints:
Lambda only knows about text formats, so http responses have to be translated to base64 when the format is binary. In your case, we're unfortunately not doing the right thing because your document is xml, but we don't take that content type into consideration when we do the transformation. The problematic code is here if you want to provide a solution:

https://github.com/awslabs/aws-lambda-rust-runtime/blob/main/lambda-http/src/response.rs#L179-L201
`image/svg+xml` is treated as binary by lambda-http crate. You need to add `BinaryMediaTypes` in your SAM tamplete to configure REST API to work with binary response.  This is in API Gateway's [developer guide](https://docs.aws.amazon.com/apigateway/latest/developerguide/api-gateway-payload-encodings.html#api-gateway-payload-encodings-proxy).

```
  ApiGatewayApi:
    Type: AWS::Serverless::Api
    Properties:
      StageName: prod
      MethodSettings:
        - ResourcePath: /
          HttpMethod: GET
      BinaryMediaTypes:
      - *~1*
```

@bnusunny should we treat those as text? at the end of the day, svgs are text files, aren't they?

Fix patch:
diff --git a/lambda-http/src/response.rs b/lambda-http/src/response.rs
index adfe3528..299a60b2 100644
--- a/lambda-http/src/response.rs
+++ b/lambda-http/src/response.rs
@@ -188,10 +188,13 @@ where
             return convert_to_text(self, "utf-8");
         };
 
+        // See list of common MIME types:
+        // https://developer.mozilla.org/en-US/docs/Web/HTTP/Basics_of_HTTP/MIME_types/Common_types
         if content_type.starts_with("text")
             || content_type.starts_with("application/json")
             || content_type.starts_with("application/javascript")
             || content_type.starts_with("application/xml")
+            || content_type.ends_with("+xml")
         {
             return convert_to_text(self, content_type);
         }


Test patch: