From a44d072cf2392dcfe6edc4ed40ac60ceb90ae214 Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Fri, 20 Oct 2023 15:54:26 +0200 Subject: [PATCH 1/7] Remove params from $request_uri in BuildsRenderer This prevents url params from being included when building a file url with getFileNameURL(), leading to a url that always works. --- source/BuildsRenderer.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/BuildsRenderer.php b/source/BuildsRenderer.php index 07217f0..6ef047d 100644 --- a/source/BuildsRenderer.php +++ b/source/BuildsRenderer.php @@ -257,7 +257,7 @@ class BuildsRenderer { $request_uri = ($_SERVER['REQUEST_URI'] == "/" || stringContains($_SERVER['REQUEST_URI'], "bpy")) ? - "/download/daily" : $_SERVER['REQUEST_URI']; + "/download/daily" : strtok($_SERVER['REQUEST_URI'], '?'); $env_id = getEnvId(); -- 2.30.2 From 4f8d64e555f6b0a8f4d17cbabec9a2933f3def5b Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Fri, 20 Oct 2023 15:58:54 +0200 Subject: [PATCH 2/7] Add support for JSON listing By appending ?format=json&v=1 it is now possible to display the list of builds as JSON object. This makes it easier for updaters or download scripts to list the builds offered. Notice that v=1 must be specified for the listing to appear, otherwise we return code 400 with an error message. --- source/BuildsRenderer.php | 11 +++++++++++ source/main.php | 18 +++++++++++++++++- 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/source/BuildsRenderer.php b/source/BuildsRenderer.php index 6ef047d..01c3137 100644 --- a/source/BuildsRenderer.php +++ b/source/BuildsRenderer.php @@ -8,6 +8,17 @@ class BuildsRenderer { $this->builds = $builds; } + public function renderJSON() { + /* Return a JSON formatted list of builds. */ + foreach ($this->builds as $build) { + // Construct a full URL to the downloadable file + $build->url = $this->getFileNameURL($build); + // We do not wish to display filesystem paths + unset($build->directory_lister); + } + echo(json_encode($this->builds, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + } + public function renderPage() { $platform_filters = array( 'windows', diff --git a/source/main.php b/source/main.php index 8a49039..6c09829 100644 --- a/source/main.php +++ b/source/main.php @@ -29,7 +29,23 @@ function handleDownloadRequest() { return; } - // Serve the directory listing. + // Check if we are requesting a JSON formatted view. + if (isset($_GET['format']) && $_GET['format'] == 'json') { + header('Content-Type: application/json; charset=utf-8'); + // Require v=1 to be specified + if (!isset($_GET['v']) || $_GET['v'] != '1') { + $data = [ 'error' => 'Missing supported format version, for example v=1']; + echo json_encode( $data ); + http_response_code(400); + return; + } + $builds = $lister->getBuilds(); + $renderer = new BuildsRenderer($builds); + $renderer->renderJSON(); + return; + } + + // Serve the directory listing as HTML. require 'templates/header.php'; // Logic inside content_build_lister.php will render the list of builds require 'templates/content_build_lister.php'; -- 2.30.2 From 16b3ccec5910d3e3de7159243cd60b68a06f05c7 Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Tue, 31 Oct 2023 21:51:31 +0100 Subject: [PATCH 3/7] Implement JSON and HTML responses separately Follow the single responsibility priciple. --- source/main.php | 45 +++++++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 18 deletions(-) diff --git a/source/main.php b/source/main.php index 6c09829..aab03e5 100644 --- a/source/main.php +++ b/source/main.php @@ -13,6 +13,29 @@ function handleNotFoundRequest() { return; } +function renderDownloadResponseAsJSON($lister) { + header('Content-Type: application/json; charset=utf-8'); + // Require v=1 to be specified + if (!isset($_GET['v']) || $_GET['v'] != '1') { + $data = [ 'error' => 'Missing supported format version, for example v=1']; + echo json_encode( $data ); + http_response_code(400); + return; + } + $builds = $lister->getBuilds(); + $renderer = new BuildsRenderer($builds); + $renderer->renderJSON(); + return; +} + +function renderDownloadResponseAsHTML($lister) { + // Serve the directory listing as HTML. + require 'templates/header.php'; + // Logic inside content_build_lister.php will render the list of builds + require 'templates/content_build_lister.php'; + require 'templates/footer.php'; +} + function handleDownloadRequest() { $lister = createListerForCurrentRequest(); $is_valid = $lister->isValid(); @@ -30,26 +53,12 @@ function handleDownloadRequest() { } // Check if we are requesting a JSON formatted view. - if (isset($_GET['format']) && $_GET['format'] == 'json') { - header('Content-Type: application/json; charset=utf-8'); - // Require v=1 to be specified - if (!isset($_GET['v']) || $_GET['v'] != '1') { - $data = [ 'error' => 'Missing supported format version, for example v=1']; - echo json_encode( $data ); - http_response_code(400); - return; - } - $builds = $lister->getBuilds(); - $renderer = new BuildsRenderer($builds); - $renderer->renderJSON(); - return; + if ($_GET['format'] == 'json') { + renderDownloadResponseAsJSON($lister); } - // Serve the directory listing as HTML. - require 'templates/header.php'; - // Logic inside content_build_lister.php will render the list of builds - require 'templates/content_build_lister.php'; - require 'templates/footer.php'; + renderDownloadResponseAsHTML($lister); + } function handleDashboardRequest() { -- 2.30.2 From 04d0ac80ceb2ffdc7a94026806e4f003b38135f0 Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Tue, 31 Oct 2023 23:50:02 +0100 Subject: [PATCH 4/7] Check for 'format' before accessing it Removes Warning of undefined key. --- source/main.php | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source/main.php b/source/main.php index aab03e5..81502fc 100644 --- a/source/main.php +++ b/source/main.php @@ -53,7 +53,7 @@ function handleDownloadRequest() { } // Check if we are requesting a JSON formatted view. - if ($_GET['format'] == 'json') { + if (isset($_GET['format']) && $_GET['format'] == 'json') { renderDownloadResponseAsJSON($lister); } -- 2.30.2 From c2917f3e06eaf654c25ce36b16c108b92744f9ba Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Wed, 1 Nov 2023 11:02:03 +0100 Subject: [PATCH 5/7] Use exit instead of return Once we are done building the response, we should exit. Using return allows for more content to be added to the response, and we don't want that. --- source/main.php | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/source/main.php b/source/main.php index 81502fc..8535e44 100644 --- a/source/main.php +++ b/source/main.php @@ -20,12 +20,12 @@ function renderDownloadResponseAsJSON($lister) { $data = [ 'error' => 'Missing supported format version, for example v=1']; echo json_encode( $data ); http_response_code(400); - return; + exit; } $builds = $lister->getBuilds(); $renderer = new BuildsRenderer($builds); $renderer->renderJSON(); - return; + exit; } function renderDownloadResponseAsHTML($lister) { -- 2.30.2 From 9cadc5cb1c053bc9dd2eeed2637fff60a9a15cbf Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Wed, 1 Nov 2023 11:03:06 +0100 Subject: [PATCH 6/7] Build a dedicated array for the JSON response Do not modify the content of $builds in BuildsRenderer. --- source/BuildsRenderer.php | 24 +++++++++++++++++++----- 1 file changed, 19 insertions(+), 5 deletions(-) diff --git a/source/BuildsRenderer.php b/source/BuildsRenderer.php index 01c3137..01a86a3 100644 --- a/source/BuildsRenderer.php +++ b/source/BuildsRenderer.php @@ -10,13 +10,27 @@ class BuildsRenderer { public function renderJSON() { /* Return a JSON formatted list of builds. */ + $builds_json = array(); foreach ($this->builds as $build) { - // Construct a full URL to the downloadable file - $build->url = $this->getFileNameURL($build); - // We do not wish to display filesystem paths - unset($build->directory_lister); + $builds_json[] = array( + 'url' => $this->getFileNameURL($build), + 'app' => $build->app, + 'version' => $build->version, + 'risk_id' => $build->risk_id, + 'branch' => $build->branch, + 'patch' => $build->patch, + 'hash' => $build->hash, + 'platform' => $build->platform, + 'architecture' => $build->architecture, + 'bitness' => $build->bitness, + 'file_mtime' => $build->file_mtime, + 'file_name' => $build->file_name, + 'file_size' => $build->file_size, + 'file_extension' => $build->file_extension, + 'release_cycle' => $build->release_cycle, + ); } - echo(json_encode($this->builds, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); + echo(json_encode($builds_json, JSON_PRETTY_PRINT | JSON_UNESCAPED_SLASHES)); } public function renderPage() { -- 2.30.2 From 8fbca889a5dd8e8c9a26ab37e79d745cea5998ea Mon Sep 17 00:00:00 2001 From: Francesco Siddi Date: Wed, 1 Nov 2023 11:59:49 +0100 Subject: [PATCH 7/7] Address feedback from code review --- source/main.php | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/source/main.php b/source/main.php index 8535e44..6f37bd2 100644 --- a/source/main.php +++ b/source/main.php @@ -20,12 +20,12 @@ function renderDownloadResponseAsJSON($lister) { $data = [ 'error' => 'Missing supported format version, for example v=1']; echo json_encode( $data ); http_response_code(400); - exit; + return; } $builds = $lister->getBuilds(); $renderer = new BuildsRenderer($builds); $renderer->renderJSON(); - exit; + return; } function renderDownloadResponseAsHTML($lister) { @@ -55,6 +55,7 @@ function handleDownloadRequest() { // Check if we are requesting a JSON formatted view. if (isset($_GET['format']) && $_GET['format'] == 'json') { renderDownloadResponseAsJSON($lister); + return; } renderDownloadResponseAsHTML($lister); -- 2.30.2