Add an interceptor for CORS OPTIONS preflighting.
authorRobert Sesek <rsesek@bluestatic.org>
Sun, 19 Nov 2017 05:00:08 +0000 (00:00 -0500)
committerRobert Sesek <rsesek@bluestatic.org>
Sun, 19 Nov 2017 05:00:23 +0000 (00:00 -0500)
http/cors_options_interceptor.php [new file with mode: 0644]

diff --git a/http/cors_options_interceptor.php b/http/cors_options_interceptor.php
new file mode 100644 (file)
index 0000000..6b3d899
--- /dev/null
@@ -0,0 +1,51 @@
+<?php
+// Hoplite
+// Copyright (c) 2017 Blue Static
+//
+// This program is free software: you can redistribute it and/or modify it
+// under the terms of the GNU General Public License as published by the Free
+// Software Foundation, either version 3 of the License, or any later version.
+//
+// This program is distributed in the hope that it will be useful, but WITHOUT
+// ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+// FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+// more details.
+//
+// You should have received a copy of the GNU General Public License along with
+// this program.  If not, see <http://www.gnu.org/licenses/>.
+
+namespace hoplite\http;
+
+require_once HOPLITE_ROOT . '/http/interceptor.php';
+require_once HOPLITE_ROOT . '/http/response_code.php';
+
+class CorsOptionsInterceptor implements Interceptor
+{
+  private $allowed_origins = [];
+
+  public function __construct($allowed_origins = []) {
+    $this->allowed_origins = $allowed_origins;
+  }
+
+  public function DoIntercept(FrontController $controller,
+                              Action $action = NULL,
+                              Request $request,
+                              Response $response)
+  {
+    if ($action === NULL) {
+      return;
+    }
+
+    // If a CORS pre-flight is in process, interrupt the action flow and
+    // permit the request.
+    if ($request->http_method == 'OPTIONS' &&
+        isset($request->data['_SERVER']['HTTP_ACCESS_CONTROL_REQUEST_METHOD'])) {
+      if (in_array($request->data['_SERVER']['HTTP_ORIGIN'], $this->allowed_origins)) {
+        $controller->SendResponseCode(ResponseCode::OK);
+      } else {
+        $controller->SendResponseCode(ResponseCode::FORBIDDEN);
+        return;
+      }
+    }
+  }
+}