use env for env vars, set cache header, set error if sheet not sent, set request...
authorEduardo <[email protected]>
Sat, 28 Oct 2023 17:53:30 +0000 (19:53 +0200)
committerEduardo <[email protected]>
Sat, 28 Oct 2023 17:53:30 +0000 (19:53 +0200)
index.php

index c019de9250bcfc406f5543b4a70b87e8a7a4dc93..222d510f074b57135a9a2da5fd67678ac3942df3 100644 (file)
--- a/index.php
+++ b/index.php
@@ -5,17 +5,44 @@ require_once "g-sheet-sync.php";
 const TTL = 5 * 60; // time to live for the files in seconds
 
 // credentials.json is the key file we downloaded while setting up our Google Sheets API
-$credentialsPath = "credentials.json";
+$_ENV["credentialsPath"] = "credentials.json";
 // the spreadsheet id (can be found in the url of the doc)
-$sheetId = "1usr8QgimS11BjY_Vwxe7ALSoZLA8fUrLDYrGQ8TCY9Y";
+$_ENV["sheetId"] = "1iubKJ48C7dyKqgCVIGypUEi-KOTrFjRGNzCgVpddA8s";
 
 // get vars
-$sheet = filter_var($_POST["sheet"], FILTER_SANITIZE_URL);
+$sheet = filter_var($_REQUEST["sheet"], FILTER_SANITIZE_URL);
 
-// set content type
+// set headers
 header('Content-Type: application/json');
+header('Cache-Control: max-age=604800'); // a week (7 days) in seconds
+
+if (!$sheet) {
+    http_response_code(400);
+    print('{"error": "400", "message": "Bad Request"}');
+    exit();
+}
 
 switch ($_SERVER['REQUEST_METHOD']) {
+    case 'HEAD':
+        $filename = generateFilename($_ENV["sheetId"], $sheet);
+        if (fileExpired($filename)) {
+            $sheetSync = new GSheetSync($_ENV["credentialsPath"], $_ENV["sheetId"]);
+            $res = $sheetSync->get($sheet);
+
+            $etag = md5($res);
+            header('ETag: ' . $etag);
+            sendNotModifiedIfSameETag($etag, false);
+
+            $file = fopen($filename, "w");
+            fwrite($file, $res);
+            fclose($file);
+        } else {
+            $etag = md5_file($filename);
+            header('ETag: ' . $etag);
+            sendNotModifiedIfSameETag($etag);
+        }
+        break;
+
     case 'GET':
         // generate filename
         $filename = generateFilename($_ENV["sheetId"], $sheet);
@@ -23,7 +50,10 @@ switch ($_SERVER['REQUEST_METHOD']) {
             $sheetSync = new GSheetSync($_ENV["credentialsPath"], $_ENV["sheetId"]);
             $res = $sheetSync->get($sheet);
 
-            error_log("database not available!");
+            // dont make the user wait, print the json
+            $etag = md5($res);
+            header('ETag: ' . $etag);
+            sendNotModifiedIfSameETag($etag, false);
             print($res);
 
             // save res as file with filename
@@ -31,6 +61,9 @@ switch ($_SERVER['REQUEST_METHOD']) {
             fwrite($file, $res);
             fclose($file);
         } else {
+            $etag = md5_file($filename);
+            header('ETag: ' . $etag);
+            sendNotModifiedIfSameETag($etag);
             readfile($filename);
         }
         break;
@@ -41,6 +74,10 @@ switch ($_SERVER['REQUEST_METHOD']) {
         // get values
         $formData = filter_var_array($_POST["form"], FILTER_SANITIZE_ADD_SLASHES);
 
+        // TODO: form put call
+        // check etag
+        // @see https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/If-None-Match
+
         $sheetSync = new GSheetSync(getenv("credentialsPath"), getenv("sheetId"));
         $sheetSync->put($sheet, $formData);
         http_response_code(201);
@@ -49,21 +86,11 @@ switch ($_SERVER['REQUEST_METHOD']) {
     default:
         // Bad request, method not allowed
         http_response_code(405);
-        header('Allow: GET, POST, PUT');
+        header('Allow: HEAD, GET, POST, PUT');
         print('{"error": "405", "message": "Method Not Allowed"}');
         break;
 }
 
-
-# TODO: if get: save the json and serve always the same for TTL or something like that
-#       use a sha or md5 on the input to return the same output as requested.
-
-// $filepath = "test.json";
-
-// $file = fopen($filepath, "w");
-// fwrite($file, "test");
-// fclose($file);
-
 /**
  * @return bool true if expired or does not exist, false if still valid
  */
@@ -81,6 +108,31 @@ function fileExpired(string $filename): bool
     return false;
 }
 
-function generateFilename(string $sheetid, string $sheet): string {
+function generateFilename(string $sheetid, string $sheet): string
+{
     return md5($sheetid . $sheet) . ".json";
-}
\ No newline at end of file
+}
+
+function hasFileContentChanged(string $oldFilePath, string $newFileString): bool
+{
+    return !(md5_file($oldFilePath) == md5($newFileString));
+}
+
+
+/**
+ * Sends an 304 Not Modified header if the ETag matches the sent one
+ */
+function sendNotModifiedIfSameETag(string $etag, bool $die = true)
+{
+    // Check whether browser had sent a HTTP_IF_NONE_MATCH request header
+    if (isset($_SERVER['HTTP_IF_NONE_MATCH'])) {
+        // If HTTP_IF_NONE_MATCH is same as the generated ETag => content is the same as browser cache
+        // So send a 304 Not Modified response header and exit
+        if ($_SERVER['HTTP_IF_NONE_MATCH'] == $etag) {
+            http_response_code(304);
+            header('HTTP/1.1 304 Not Modified');
+            if ($die)
+                exit();
+        }
+    }
+}