content: package com.airbnb.airpal.resources;
  
  import com.amazonaws.services.s3.AmazonS3;
  import com.amazonaws.services.s3.model.GetObjectRequest;
  import com.amazonaws.services.s3.model.ObjectMetadata;
  import com.google.common.io.ByteStreams;
  import com.google.inject.Inject;
  import lombok.val;
  
  import javax.inject.Named;
  import javax.ws.rs.GET;
  import javax.ws.rs.Path;
  import javax.ws.rs.PathParam;
  import javax.ws.rs.Produces;
  import javax.ws.rs.WebApplicationException;
  import javax.ws.rs.core.MediaType;
  import javax.ws.rs.core.Response;
  import javax.ws.rs.core.StreamingOutput;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  
  @Path("/api/s3")
  public class S3FilesResource
  {
  
      private final AmazonS3 s3Client;
      private final String outputBucket;
  
      @Inject
      public S3FilesResource(
              AmazonS3 s3Client,
              @Named("s3Bucket") String outputBucket)
      {
          this.s3Client = s3Client;
          this.outputBucket = outputBucket;
      }
  
      private String getOutputKey(String fileBaseName)
      {
          return "airpal/" + fileBaseName;
      }
  
      @GET
      @Path("/{filename}")
      @Produces(MediaType.APPLICATION_OCTET_STREAM)
      public Response getFile(@PathParam("filename") String filename)
      {
          val outputKey = getOutputKey(filename);
          val getRequest = new GetObjectRequest(outputBucket, outputKey);
          final val object = s3Client.getObject(getRequest);
  
          if (object == null) {
              return Response.status(Response.Status.NOT_FOUND).build();
          } else {
              ObjectMetadata objectMetadata = object.getObjectMetadata();
              Response.ResponseBuilder builder = Response.ok().type(objectMetadata.getContentType());
              if (objectMetadata.getContentEncoding() != null) {
                  builder = builder.encoding(objectMetadata.getContentEncoding()); // gzip
              }
              return builder.entity(new StreamingOutput() {
                  @Override
                  public void write(OutputStream output)
                          throws IOException, WebApplicationException
                  {
                      try (InputStream objectData = object.getObjectContent()) {
                          ByteStreams.copy(objectData, output);
  
                      } finally {
                          output.close();
                      }
                  }
              }).build();
          }
      }
  }
  