summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDaniel Weipert <code@drogueronin.de>2023-11-13 13:37:26 +0100
committerDaniel Weipert <code@drogueronin.de>2023-11-20 17:30:39 +0100
commitd017568a77d677e449e66d689450532a760d6f11 (patch)
tree2d386b94278f30d6fe3dc585e4be3f676b549621
initial commit
-rw-r--r--.gitignore3
-rw-r--r--.htaccess9
-rw-r--r--Dockerfile15
-rw-r--r--composer.json24
-rw-r--r--composer.lock47
-rw-r--r--docker-compose.yml5
-rw-r--r--index.php83
-rw-r--r--test/router.php3
8 files changed, 189 insertions, 0 deletions
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..2879d3b
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,3 @@
+/vendor/
+
+.env
diff --git a/.htaccess b/.htaccess
new file mode 100644
index 0000000..d025b2b
--- /dev/null
+++ b/.htaccess
@@ -0,0 +1,9 @@
+RewriteEngine On
+# Redirect /index.php to / (optional, but recommended I guess)
+RewriteCond %{THE_REQUEST} ^[A-Z]{3,9}\ /.*index\.php
+RewriteRule ^index.php/?(.*)$ $1 [R=301,L]
+
+# Run everything else but real files through index.php
+RewriteCond %{REQUEST_FILENAME} !-d
+RewriteCond %{REQUEST_FILENAME} !-f
+RewriteRule ^(.*)$ index.php/$1?%{QUERY_STRING} [L]
diff --git a/Dockerfile b/Dockerfile
new file mode 100644
index 0000000..bdb70e1
--- /dev/null
+++ b/Dockerfile
@@ -0,0 +1,15 @@
+FROM php:apache
+
+COPY --from=composer /usr/bin/composer /usr/bin/composer
+
+WORKDIR /var/www/html
+
+RUN apt-get update && apt-get -y install git
+
+COPY composer* .
+RUN composer install
+
+RUN a2enmod rewrite
+
+COPY index.php .
+COPY .htaccess .
diff --git a/composer.json b/composer.json
new file mode 100644
index 0000000..4393981
--- /dev/null
+++ b/composer.json
@@ -0,0 +1,24 @@
+{
+ "name": "dweipert/gemini-http-proxy",
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "require": {
+ "dweipert/gemini-foundation": "dev-main"
+ },
+ "repositories": [
+ {
+ "type": "vcs",
+ "url": "https://git.dweipert.de/gemini-foundation"
+ }
+ ],
+ "minimum-stability": "dev",
+ "autoload": {
+ "psr-4": {
+ "Dweipert\\GeminiHttpProxy\\": "src/"
+ }
+ }
+}
diff --git a/composer.lock b/composer.lock
new file mode 100644
index 0000000..c6f6310
--- /dev/null
+++ b/composer.lock
@@ -0,0 +1,47 @@
+{
+ "_readme": [
+ "This file locks the dependencies of your project to a known state",
+ "Read more about it at https://getcomposer.org/doc/01-basic-usage.md#installing-dependencies",
+ "This file is @generated automatically"
+ ],
+ "content-hash": "5402a4c52a05baa8de485a52ec6532cc",
+ "packages": [
+ {
+ "name": "dweipert/gemini-foundation",
+ "version": "dev-main",
+ "source": {
+ "type": "git",
+ "url": "https://git.dweipert.de/gemini-foundation",
+ "reference": "bc4d0071d7a0726e08b44795ff29cc1d0262dfe4"
+ },
+ "default-branch": true,
+ "type": "library",
+ "autoload": {
+ "psr-4": {
+ "GeminiFoundation\\": "src/"
+ },
+ "files": [
+ "src/functions.php"
+ ]
+ },
+ "authors": [
+ {
+ "name": "Daniel Weipert",
+ "email": "code@drogueronin.de"
+ }
+ ],
+ "time": "2023-11-13T12:15:40+00:00"
+ }
+ ],
+ "packages-dev": [],
+ "aliases": [],
+ "minimum-stability": "dev",
+ "stability-flags": {
+ "dweipert/gemini-foundation": 20
+ },
+ "prefer-stable": false,
+ "prefer-lowest": false,
+ "platform": [],
+ "platform-dev": [],
+ "plugin-api-version": "2.6.0"
+}
diff --git a/docker-compose.yml b/docker-compose.yml
new file mode 100644
index 0000000..8dd6e04
--- /dev/null
+++ b/docker-compose.yml
@@ -0,0 +1,5 @@
+services:
+ proxy:
+ build: .
+ environment:
+ - "GEMINI_HOST=${GEMINI_HOST}"
diff --git a/index.php b/index.php
new file mode 100644
index 0000000..23c314f
--- /dev/null
+++ b/index.php
@@ -0,0 +1,83 @@
+<?php
+
+use GeminiFoundation\Client;
+use GeminiFoundation\Gemtext;
+
+require __DIR__ . '/vendor/autoload.php';
+
+$geminiHost = $_ENV['GEMINI_HOST'];
+
+$url = parse_url(
+ "//$_SERVER[HTTP_HOST]$_SERVER[REQUEST_URI]"
+);
+$url['query'] ??= '';
+
+$client = new Client($geminiHost);
+$response = $client->request("$url[path]$url[query]");
+
+ob_start();
+$mime = explode(';', $response->getMeta())[0];
+if (strpos($mime, 'text/gemini') === 0) {
+ $parser = new Gemtext($response->getBody());
+ $lines = $parser->parse();
+
+ $wasListItem = false;
+ $currentListItems = [];
+ foreach ($lines as $line) {
+ if ($wasListItem && $line['type'] !== 'listitem') {
+ echo "<ul>";
+ foreach ($currentListItems as $listItem) {
+ echo "<li>$listItem[text]</li>";
+ }
+ echo "</ul>";
+ $wasListItem = false;
+ $currentListItems = [];
+ }
+
+ if ($line['type'] === 'preformatted_on') {
+ echo "<div>$line[alt]</div><pre>";
+ }
+ else if ($line['type'] === 'preformatted') {
+ echo htmlentities($line['raw']);
+ }
+ else if ($line['type'] === 'preformatted_off') {
+ echo "</pre>";
+ }
+ else if ($line['type'] === 'heading') {
+ echo "<h$line[size]>$line[text]</h$line[size]>";
+ }
+ else if ($line['type'] === 'listitem') {
+ $currentListItems[] = $line;
+ $wasListItem = true;
+ }
+ else if ($line['type'] === 'quote') {
+ echo "<blockquote>$line[text]</blockquote>";
+ }
+ else if ($line['type'] === 'link') {
+ $line['link'] = str_replace(["gemini://$geminiHost", $geminiHost], "https://$geminiHost", $line['link']);
+ $line['text'] = $line['text'] ?: $line['link'];
+ echo "<a href=\"$line[link]\">$line[text]</a>";
+ }
+ else if ($line['type'] === 'text') {
+ echo "<p>$line[text]</p>";
+ }
+ }
+}
+
+else if (strpos($mime, 'image') === 0) {
+ echo "<img src=\"data:{$mime};base64," . base64_encode($response->getBody()) . "\">";
+}
+
+echo "<hr>";
+echo "Proxied from <a href=\"gemini://$geminiHost$url[path]$url[query]\">gemini://$geminiHost$url[path]$url[query]</a>";
+$content = ob_get_clean();
+
+?>
+<!doctype html>
+<html>
+ <head>
+ </head>
+ <body>
+ <?php echo $content; ?>
+ </body>
+</html>
diff --git a/test/router.php b/test/router.php
new file mode 100644
index 0000000..cead5ee
--- /dev/null
+++ b/test/router.php
@@ -0,0 +1,3 @@
+<?php
+
+include dirname(__DIR__) . '/index.php';