From 06c97d3f552df867cf0dbcd5dd41f2e411762cc1 Mon Sep 17 00:00:00 2001
From: Keita Kobayashi <keita@kbys.me>
Date: Sun, 28 Jun 2020 16:53:07 +0900
Subject: [PATCH 1/2] Add opcache, dom, gd, and zip extensions

---
 build-php-remi.sh | 18 +++++++-----------
 1 file changed, 7 insertions(+), 11 deletions(-)

diff --git a/build-php-remi.sh b/build-php-remi.sh
index 8d8fbef..1a041c9 100755
--- a/build-php-remi.sh
+++ b/build-php-remi.sh
@@ -4,8 +4,7 @@ PHP_MINOR_VERSION=$1
 
 echo "Building layer for PHP 7.$PHP_MINOR_VERSION - using Remi repository"
 
-yum install -y wget
-yum install -y yum-utils
+yum install -y wget yum-utils
 wget https://dl.fedoraproject.org/pub/epel/epel-release-latest-6.noarch.rpm
 wget https://rpms.remirepo.net/enterprise/remi-release-6.rpm
 rpm -Uvh epel-release-latest-6.noarch.rpm
@@ -13,12 +12,11 @@ rpm -Uvh remi-release-6.rpm
 
 yum-config-manager --enable remi-php7${PHP_MINOR_VERSION}
 
-yum install -y httpd
-yum install -y postgresql-devel
-yum install -y libargon2-devel
+yum install -y httpd postgresql-devel libargon2-devel compat-libtiff3 libXpm
 
-yum install -y --disablerepo="*" --enablerepo="remi,remi-php7${PHP_MINOR_VERSION}" php php-mbstring php-pdo php-mysql php-pgsql php-xml php-process
+yum install -y --disablerepo="amzn-main" --enablerepo="epel" libwebp
 
+yum install -y --disablerepo="*" --enablerepo="remi,remi-php7${PHP_MINOR_VERSION}" php php-mbstring php-pdo php-mysql php-pgsql php-xml php-process php-opcache php-dom php-gd php-zip
 
 mkdir /tmp/layer
 cd /tmp/layer
@@ -33,13 +31,11 @@ for lib in libncurses.so.5 libtinfo.so.5 libpcre.so.0; do
   cp "/lib64/${lib}" lib/
 done
 
-cp /usr/lib64/libedit.so.0 lib/
-cp /usr/lib64/libargon2.so.0 lib/
-cp /usr/lib64/libpq.so.5 lib/
-cp /usr/lib64/libonig.so.5 lib/
+for lib in libedit.so.0 libargon2.so.0 libpq.so.5 libonig.so.105 libtiff.so.3 libXpm.so.4 libwebp.so.5 libzip.so.5 libgd.so.3; do
+  cp "/usr/lib64/${lib}" lib/
+done
 
 mkdir -p lib/php/7.${PHP_MINOR_VERSION}
 cp -a /usr/lib64/php/modules lib/php/7.${PHP_MINOR_VERSION}/
 
 zip -r /opt/layer/php7${PHP_MINOR_VERSION}.zip .
-

From e8ee8f961fd110b8f315d5d986c4ff8e8d67391e Mon Sep 17 00:00:00 2001
From: Keita Kobayashi <keita@kbys.me>
Date: Mon, 29 Jun 2020 10:18:23 +0900
Subject: [PATCH 2/2] Support binary responses

---
 bootstrap | 38 +++++++++++++++++++++++++++++++-------
 1 file changed, 31 insertions(+), 7 deletions(-)

diff --git a/bootstrap b/bootstrap
index 5fcf610..3322241 100755
--- a/bootstrap
+++ b/bootstrap
@@ -8,6 +8,19 @@ $AWS_LAMBDA_RUNTIME_API = getenv('AWS_LAMBDA_RUNTIME_API');
 /* https://gist.github.com/henriquemoody/6580488 */
 $http_codes = [100=>'Continue',101=>'Switching Protocols',102=>'Processing',200=>'OK',201=>'Created',202=>'Accepted',203=>'Non-Authoritative Information',204=>'No Content',205=>'Reset Content',206=>'Partial Content',207=>'Multi-Status',208=>'Already Reported',226=>'IM Used',300=>'Multiple Choices',301=>'Moved Permanently',302=>'Found',303=>'See Other',304=>'Not Modified',305=>'Use Proxy',306=>'Switch Proxy',307=>'Temporary Redirect',308=>'Permanent Redirect',400=>'Bad Request',401=>'Unauthorized',402=>'Payment Required',403=>'Forbidden',404=>'Not Found',405=>'Method Not Allowed',406=>'Not Acceptable',407=>'Proxy Authentication Required',408=>'Request Timeout',409=>'Conflict',410=>'Gone',411=>'Length Required',412=>'Precondition Failed',413=>'Request Entity Too Large',414=>'Request-URI Too Long',415=>'Unsupported Media Type',416=>'Requested Range Not Satisfiable',417=>'Expectation Failed',418=>'I\'m a teapot',419=>'Authentication Timeout',420=>'Enhance Your Calm',420=>'Method Failure',422=>'Unprocessable Entity',423=>'Locked',424=>'Failed Dependency',424=>'Method Failure',425=>'Unordered Collection',426=>'Upgrade Required',428=>'Precondition Required',429=>'Too Many Requests',431=>'Request Header Fields Too Large',444=>'No Response',449=>'Retry With',450=>'Blocked by Windows Parental Controls',451=>'Redirect',451=>'Unavailable For Legal Reasons',494=>'Request Header Too Large',495=>'Cert Error',496=>'No Cert',497=>'HTTP to HTTPS',499=>'Client Closed Request',500=>'Internal Server Error',501=>'Not Implemented',502=>'Bad Gateway',503=>'Service Unavailable',504=>'Gateway Timeout',505=>'HTTP Version Not Supported',506=>'Variant Also Negotiates',507=>'Insufficient Storage',508=>'Loop Detected',509=>'Bandwidth Limit Exceeded',510=>'Not Extended',511=>'Network Authentication Required',598=>'Network read timeout error',599=>'Network connect timeout error'];
 
+function is_binary_type($content_type) {
+  if ($content_type === "image/svg+xml") {
+    return false;
+  } else if (
+    substr($content_type, 0, 6) === "image/" ||
+    substr($content_type, 0, 5) === "font/" ||
+    $content_type === "application/octet-stream"
+  ) {
+    return true;
+  }
+  return false;
+}
+
 function start_webserver() {
   $SERVER_STARTUP_TIMEOUT = 1000000; // 1 second
 
@@ -176,9 +189,10 @@ while (true) {
 
   $response = array();
   $response['multiValueHeaders'] = array();
-  $response['body'] = '';
+  $content_type = '';
+  $raw_body = '';
 
-  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$response) {
+  curl_setopt($ch, CURLOPT_HEADERFUNCTION, function ($ch, $header) use (&$response, &$content_type) {
     if (preg_match('/HTTP\/1.1 (\d+) .*/', $header, $matches)) {
       $response['statusCode'] = intval($matches[1]);
       return strlen($header);
@@ -197,6 +211,10 @@ while (true) {
       return strlen($header);
     }
 
+    if (strtolower($name) === "content-type") {
+      $content_type = $value;
+    }
+
     if (!array_key_exists($name, $response['multiValueHeaders'])) {
       $response['multiValueHeaders'][$name] = array();
     }
@@ -206,8 +224,8 @@ while (true) {
     return strlen($header);
   });
 
-  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$response) {
-    $response['body'] .= $chunk;
+  curl_setopt($ch, CURLOPT_WRITEFUNCTION, function ($ch, $chunk) use (&$raw_body) {
+    $raw_body .= $chunk;
 
     return strlen($chunk);
   });
@@ -225,8 +243,16 @@ while (true) {
     } else {
         $response["statusDescription"] = "$status Unknown";
     }
-    $response["isBase64Encoded"] = false;
   }
+
+  $encode_body = is_binary_type($content_type);
+  $response["isBase64Encoded"] = $encode_body;
+  if ($encode_body) {
+    $response['body'] = base64_encode($raw_body);
+  } else {
+    $response['body'] = $raw_body;
+  }
+
   $response_json = json_encode($response);
   curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'POST');
   curl_setopt($ch, CURLOPT_RETURNTRANSFER, TRUE);
@@ -240,5 +266,3 @@ while (true) {
   curl_exec($ch);
   curl_close($ch);
 }
-
-?>
