empires: Construct reliable paths for all game API endpoints
authorCarl Worth <cworth@cworth.org>
Sun, 24 May 2020 15:06:11 +0000 (08:06 -0700)
committerCarl Worth <cworth@cworth.org>
Sun, 24 May 2020 15:20:47 +0000 (08:20 -0700)
By appending to window.location we can ensure that we're always
hitting an endpoint one level below the game ID, (and not replacing
the game ID), regardless of whether the current path ends in a
trailing slash or not.

empires/game.js

index 746cdfdc943d37d55c6d0f6fb6ce3f8315407a42..3f45e7de730bbd8c35037a25cef5a4f7e802ebb2 100644 (file)
@@ -1,3 +1,39 @@
+/* Construction of Game API endpoint paths. Logically all endpoints
+ * are just local resources underneath the current path, but just
+ * referring to them by a local name only works if the current path
+ * has a trailing slash.
+ *
+ * That is, if the current path is:
+ *
+ *     https://lmno.games/empires/WXYZ/
+ *
+ * Then a path of "register" goes to:
+ *
+ *     https://lmno.games/empires/WXYZ/register
+ *
+ * Just as we want. But if the current path happens to be:
+ *
+ *     https://lmno.games/empires/WXYZ
+ *
+ * Then a path of "register" goes to:
+ *
+ *     https://lmno.games/empires/register
+ *
+ * Which cannot work since we have lost the game ID in the path.
+ *
+ * Of course, we would like to have canonical URLs for the game (with
+ * the trailing slash) but since that depends on macehinery outside
+ * the scope of this file, let's construct API paths that will work
+ * either way.
+ */
+function GAME_API(endpoint) {
+  var path = window.location.pathname;
+  if (! path.endsWith('/'));
+      path += '/';
+  path += endpoint;
+  return path;
+}
+
 function undisplay(element) {
   element.style.display="none";
 }
@@ -14,7 +50,7 @@ ${message}
 function register(form) {
   var request = new XMLHttpRequest();
 
-  request.open("POST", "register");
+  request.open("POST", GAME_API("register"));
   request.setRequestHeader("Content-Type", "application/json; charset=UTF-8");
   var data = {
     "character": form.character.value
@@ -38,25 +74,25 @@ function toggle_host_tools() {
 function post_reveal() {
   const request = new XMLHttpRequest();
 
-  request.open("POST", "reveal");
+  request.open("POST", GAME_API("reveal"));
   request.send();
 }
 
 function post_start() {
   const request = new XMLHttpRequest();
 
-  request.open("POST", "start");
+  request.open("POST", GAME_API("start"));
   request.send();
 }
 
 function post_reset() {
   const request = new XMLHttpRequest();
 
-  request.open("POST", "reset");
+  request.open("POST", GAME_API("reset"));
   request.send();
 }
 
-const events = new EventSource(window.location + "events");
+const events = new EventSource(GAME_API("events"));
 
 events.onerror = function(event) {
   if (event.target.readyState === EventSource.CLOSED) {