diff --git a/INSTALL.md b/INSTALL.md

new file mode 100644

index 0000000..8872eba

--- /dev/null

+++ b/INSTALL.md

@@ -0,0 +1,56 @@

+# Installation

+

+## Install ImageMagick

+

+Make sure ImageMagick is installed.

+

+However this works on whatever distribution of whatever operating system you use.

+

+If you do not have access to the command convert then this will not work.

+

+## Add a webserver

+

+Copy brutalproxy to a directory and create a webserver to point to that directory.

+

+Make sure brutalproxy is owned by the same user as the webserver. If you use Nginx on a Debian-like linux, this is probaby www-data. If you need a server block because you don't understand how Nginx works, it should look something like this:

+

+```

+server {

+ listen 80;

+ server_name proxy.brutal.url;

+

+ root /var/www/brutalproxy;

+ index index.php;

+

+ location ~ .php$ {

+ try_files $uri =404;

+ fastcgi_pass unix:/var/run/php/php8.1-fpm.sock;

+ fastcgi_index index.php;

+ fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;

+ include fastcgi_params;

+ }

+}

+```

+

+You might want to add some kind of password control too so people don't casually hijack this to download bad things.

+

+## Add a cron job

+

+Edit cleanup.sh to point to where you installed brutalproxy.

+

+Create a cron job to run cleanup.sh once a day. This will sweep out any old files from the cache so you don't burn up your disk space.

+

+```

+0 12 * * * root /var/www/brutalproxy/cleanup.sh

+```

+

+## Patch Brutaldon

+

+Open brutaldon.patch with your favorite text editor and replace "http://proxy.brutal.url" with the actual URL where you are running brutalproxy.

+

+Save.

+

+Apply the patch to your Brutaldon installation.

+

+Restart Brutaldon.

+

diff --git a/LICENSE b/LICENSE

new file mode 100644

index 0000000..d168027

--- /dev/null

+++ b/LICENSE

@@ -0,0 +1,7 @@

+This work is released to the Public Domain.

+

+The author, Anonymous, has dedicated the work to the public domain by waiving all copyright and related or neighboring rights to this work worldwide under copyright law including all related and neighboring rights.

+

+Even beyond the extent allowed by law: if your law does not allow a creator to give his work to the public domain then your law is fake and gay and retarded.

+

+You can copy, modify, distribute and create derivative work, even for commercial purposes, all without asking permission.

diff --git a/README.md b/README.md

new file mode 100644

index 0000000..621f4b0

--- /dev/null

+++ b/README.md

@@ -0,0 +1,21 @@

+# brutalproxy

+

+## Why make this?

+

+Google and browser developers broke the World Wide Web.

+

+The cancer of SSL everywhere, enforced by browsers redirecting to HTTPS and Google downranking pages that don't use HTTPS.

+

+This affects almost every server in 2024, and the Fediverse is not immune.

+

+Brutaldon gets halfway to a solution since you can run it on port 80 and let your server negotiate communication with all the HTTPS-only Fediverse servers. Unfortunately, images still won't load.

+

+Even if you can get an image pulled down to your computer, there is a good chance of it being Googleshit WEBP that isn't supported.

+

+## How does it work?

+

+This is a dead simple caching proxy that downloads images over HTTPS, processes it with ImageMagick to remove malicious payloads and reduce the size, and sends it over port 80 to your legacy browser.

+

+It includes a simple template patch for Brutaldon to alter its image links so that they go yo your proxy instead of the actual server.

+

+Images are downloaded and stored using an sha1 hash of the full URL.

diff --git a/brutaldon.patch b/brutaldon.patch

new file mode 100644

index 0000000..b9eb0ce

--- /dev/null

+++ b/brutaldon.patch

@@ -0,0 +1,191 @@

+diff --color -Naur brutaldon/brutaldon/templates/accounts/account_partial.html ../brutaldon/brutaldon/templates/accounts/account_partial.html

+--- brutaldon/brutaldon/templates/accounts/account_partial.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/accounts/account_partial.html 2025-01-11 12:26:07.630934344 -0500

+@@ -1,7 +1,7 @@

+ 

+ 

+ 

+- <img src="{{ account.user.avatar_static }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ account.user.avatar_static }}"

+ alt="{{ account.user.acct }}"

+ height="64" width="64">

+ 

+diff --color -Naur brutaldon/brutaldon/templates/base.html ../brutaldon/brutaldon/templates/base.html

+--- brutaldon/brutaldon/templates/base.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/base.html 2025-01-11 12:25:55.401743609 -0500

+@@ -82,7 +82,7 @@

+ 

+ <a class="navbar-item" href="{% url "home" %}">

+ {% if own_acct %}

+- <img src="{{ own_acct.avatar_static }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ own_acct.avatar_static }}"

+ class="image is-32x32 avatar"

+ height="32" width="32"

+ alt="Brutaldon ('{{ own_acct.username }}')">

+diff --color -Naur brutaldon/brutaldon/templates/main/block.html ../brutaldon/brutaldon/templates/main/block.html

+--- brutaldon/brutaldon/templates/main/block.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/block.html 2025-01-11 12:28:06.934550057 -0500

+@@ -15,7 +15,7 @@

+ 

+ 

+ <a href="{% url "user" user.acct %}">

+- <img src="{{ user.avatar }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ user.avatar }}"

+ height="64" width="64"

+ alt="">

+ 

+diff --color -Naur brutaldon/brutaldon/templates/main/follow.html ../brutaldon/brutaldon/templates/main/follow.html

+--- brutaldon/brutaldon/templates/main/follow.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/follow.html 2025-01-11 12:27:09.973004273 -0500

+@@ -17,7 +17,7 @@

+ 

+ 

+ <a href="{% url "user" user.acct %}">

+- <img src="{{ user.avatar }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ user.avatar }}"

+ height="64" width="64"

+ alt="">

+ 

+diff --color -Naur brutaldon/brutaldon/templates/main/mute.html ../brutaldon/brutaldon/templates/main/mute.html

+--- brutaldon/brutaldon/templates/main/mute.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/mute.html 2025-01-11 12:28:15.475381572 -0500

+@@ -15,7 +15,7 @@

+ 

+ 

+ <a href="{% url "user" user.acct %}">

+- <img src="{{ user.avatar }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ user.avatar }}"

+ height="64" width="64"

+ alt="">

+ 

+diff --color -Naur brutaldon/brutaldon/templates/main/notifications.html ../brutaldon/brutaldon/templates/main/notifications.html

+--- brutaldon/brutaldon/templates/main/notifications.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/notifications.html 2025-01-11 12:29:14.797156861 -0500

+@@ -83,7 +83,7 @@

+ 

+ 

+ 

+- <img src="{{ note.account.avatar_static }}" alt=""

++ <img src="http://proxy.brutal.url/preview.php?{{ note.account.avatar_static }}" alt=""

+ height="64" width="64">

+ 

+ 

+diff --color -Naur brutaldon/brutaldon/templates/main/post_minimal_partial.html ../brutaldon/brutaldon/templates/main/post_minimal_partial.html

+--- brutaldon/brutaldon/templates/main/post_minimal_partial.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/post_minimal_partial.html 2025-01-11 12:29:51.368717186 -0500

+@@ -30,7 +30,7 @@

+ 

+ 

+ <a href="{% url "user" own_acct.acct %}" class="image avatar is-48x48 level-item">

+- <img src="{{ own_acct.avatar_static }}" alt="[{{ own_acct.acct }}]"

++ <img src="http://proxy.brutal.url/preview.php?{{ own_acct.avatar_static }}" alt="[{{ own_acct.acct }}]"

+ height="48" width="48">

+ 

+ <input type="submit" class="button is-primary level-item"

+diff --color -Naur brutaldon/brutaldon/templates/main/post_partial.html ../brutaldon/brutaldon/templates/main/post_partial.html

+--- brutaldon/brutaldon/templates/main/post_partial.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/post_partial.html 2025-01-11 12:27:43.748292669 -0500

+@@ -125,7 +125,7 @@

+ 

+ 

+ <a href="{% url "user" own_acct.acct %}" class="image avatar is-48x48 level-item" >

+- <img src="{{ own_acct.avatar_static }}" alt="[{{ own_acct.acct }}]"

++ <img src="http://proxy.brutal.url/preview.php?{{ own_acct.avatar_static }}" alt="[{{ own_acct.acct }}]"

+ height="48" width="48">

+ 

+ <input type="submit" class="button is-primary level-item"

+diff --color -Naur brutaldon/brutaldon/templates/main/search_results.html ../brutaldon/brutaldon/templates/main/search_results.html

+--- brutaldon/brutaldon/templates/main/search_results.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/search_results.html 2025-01-11 12:26:56.487691304 -0500

+@@ -45,7 +45,7 @@

+ 

+ 

+ <a href="{% url "user" user.acct %}">

+- <img src="{{ user.avatar }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ user.avatar }}"

+ alt=""

+ height="64" width="64">

+ 

+diff --color -Naur brutaldon/brutaldon/templates/main/toot_partial.html ../brutaldon/brutaldon/templates/main/toot_partial.html

+--- brutaldon/brutaldon/templates/main/toot_partial.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/toot_partial.html 2025-01-11 08:02:04.158784744 -0500

+@@ -14,7 +14,7 @@

+ 

+ 

+ <a href="{% url "user" toot.account.acct %}">

+- <img loading="auto" src="{{ toot.account.avatar_static }}"

++ <img loading="auto" src="http://proxy.brutal.url/preview.php?{{ toot.account.avatar_static }}"

+ height="64" width="64" float="left"

+ alt="">

+ 

+@@ -22,7 +22,7 @@

+ {% if reblog %}

+ 

+ <a href="{% url "user" reblog_by %}">

+- <img loading="auto" src ="{{ reblog_icon }}" alt=""

++ <img loading="auto" src ="http://proxy.brutal.url/preview.php?{{ reblog_icon }}" alt=""

+ height="32" width="32">

+ 

+ 

+@@ -74,7 +74,7 @@

+ 

+ 

+ <img loading="lazy" alt="{{ toot.card.title }}"

+- src="{{ toot.card.image }}"

++ src="http://proxy.brutal.url/preview.php?{{ toot.card.image }}"

+ class="is-max-128" width="128" height="128">

+ 

+ 

+@@ -99,11 +99,11 @@

+ {% for media in toot.media_attachments %}

+ {% if media.type == "image" %}

+ 

+- 

++ 

+ {% if toot.sensitive and not preferences.preview_sensitive %}

+ <img loading="lazy" src="{% static "images/sensitive.png" %}"

+ {% else %}

+- <img loading="lazy" src="{{ media.preview_url }}"

++ <img loading="lazy" src="http://proxy.brutal.url/preview.php?{{ media.preview_url }}"

+ {% endif %}

+ alt="{% if media.description %}

+ {{ media.description }}

+@@ -124,11 +124,11 @@

+ width="256" height="256"

+ poster="{{ media.preview_url }}">

+ 

+- 

++ 

+ {% if toot.sensitive and not preferences.preview_sensitive %}

+ <img loading="lazy" src="{% static "images/sensitive.png" %}"

+ {% else %}

+- <img loading="lazy" src="{{ media.preview_url }}"

++ <img loading="lazy" src="http://proxy.brutal.url/preview.php?{{ media.preview_url }}"

+ {% endif %}

+ alt="{% if media.description %}

+ {{ media.description }}

+diff --color -Naur brutaldon/brutaldon/templates/main/user.html ../brutaldon/brutaldon/templates/main/user.html

+--- brutaldon/brutaldon/templates/main/user.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/main/user.html 2025-01-11 12:28:59.891705759 -0500

+@@ -21,7 +21,7 @@

+ 

+ 

+ 

+- <img src="{{ user.avatar }}" alt="Avatar"

++ <img src="http://proxy.brutal.url/preview.php?{{ user.avatar }}" alt="Avatar"

+ height="96" width="96">

+ {% if user.locked %}

+ 

+diff --color -Naur brutaldon/brutaldon/templates/requests/request_partial.html ../brutaldon/brutaldon/templates/requests/request_partial.html

+--- brutaldon/brutaldon/templates/requests/request_partial.html 2025-01-12 07:16:02.990452094 -0500

++++ ../brutaldon/brutaldon/templates/requests/request_partial.html 2025-01-11 12:26:31.045214110 -0500

+@@ -1,7 +1,7 @@

+ 

+ 

+ 

+- <img src="{{ request.avatar_static }}"

++ <img src="http://proxy.brutal.url/preview.php?{{ request.avatar_static }}"

+ alt="{{ request.acct }}"

+ height="64" width="64">

+ 

+

diff --git a/cache.php b/cache.php

new file mode 100644

index 0000000..cd1dd35

--- /dev/null

+++ b/cache.php

@@ -0,0 +1,18 @@

+<?php

+

+include("init.php");

+

+// Get file if not cached yet

+if(!file_exists("$dir/cache/$hash.$ext"))

+ include("fetch.php");

+

+// Replace webp with jpeg

+if($ext == "webp")

+ $ext = "jpg";

+

+// Write HTTP headers and cache file

+write_octet("$dir/cache/$hash.$ext", $ext, $expire);

+

+exit;

+

+?>

diff --git a/cache/.empty b/cache/.empty

new file mode 100644

index 0000000..e69de29

diff --git a/cleanup.sh b/cleanup.sh

new file mode 100755

index 0000000..856c7de

--- /dev/null

+++ b/cleanup.sh

@@ -0,0 +1,3 @@

+#!/bin/sh

+find /var/www/brutalproxy/cache -mtime +3 -type f -delete

+find /var/www/brutalproxy/preview -mtime +3 -type f -delete

diff --git a/fetch.php b/fetch.php

new file mode 100644

index 0000000..7d2ed88

--- /dev/null

+++ b/fetch.php

@@ -0,0 +1,34 @@

+<?php

+

+// Fetch file if not exists in cache

+if(!file_exists("$dir/proxy/$hash.$ext")) {

+

+ ini_set('default_socket_timeout', $timeout);

+ file_put_contents("$dir/temp/$hash.$ext", file_get_contents($img));

+

+ //

+ // Parse all files through ImageMagick to remove potential malware payloads

+ //

+

+ // JPEG files

+ if($ext == "jpg" || $ext == "jpeg") {

+ exec("convert -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG $dir/temp/$hash.$ext $dir/cache/$hash.$ext");

+ exec("convert -resize 500x500> -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG $dir/temp/$hash.$ext $dir/preview/$hash.$ext");

+ }

+ // Convert WEBM to JPEG

+ else if($ext == "webp") {

+ exec("convert -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG $dir/temp/$hash.$ext $dir/cache/$hash.jpg");

+ exec("convert -resize 500x500> -sampling-factor 4:2:0 -strip -quality 85 -interlace JPEG $dir/temp/$hash.$ext $dir/preview/$hash.jpg");

+ }

+ // PNG and GIF

+ else {

+ exec("convert -sampling-factor 4:2:0 -strip $dir/temp/$hash.$ext $dir/cache/$hash.$ext");

+ exec("convert -resize 500x500> -sampling-factor 4:2:0 -strip $dir/temp/$hash.$ext $dir/preview/$hash.$ext");

+ }

+

+ // Remove temp file

+ unlink("$dir/temp/$hash.$ext");

+

+}

+

+?>

diff --git a/index.php b/index.php

new file mode 100644

index 0000000..7e1282a

--- /dev/null

+++ b/index.php

@@ -0,0 +1,15 @@

+

+

+ 

+ You are lost

+ 

+

+ 

+ You are lost

+ This is a proxy used to fetch images from the Fediverse for display in the Brutaldon client.

+ You should never end up at this URL. What are you doing?

+ Since you are here, I'll tell you there are currently files in the cache and they occupy of disk space.

+ Now go away.

+ 

+

+

diff --git a/init.php b/init.php

new file mode 100644

index 0000000..9aa137e

--- /dev/null

+++ b/init.php

@@ -0,0 +1,34 @@

+<?php

+

+// Set installation dir

+$dir = "/var/www/brutalproxy";

+

+// Set browser expiration

+$expire = 14 * 606024;

+

+// Set timeout for file requests

+$timeout = 10;

+

+// Create useful variables

+$img = $_SERVER['QUERY_STRING'];

+$ext = substr(strrchr($img, "."), 1);

+$hash = sha1($img);

+

+// Give up and die if it is not a supported extension

+$types = array("jpg", "jpeg", "png", "gif", "webp");

+if(!in_array($ext, $types)) {

+ exit();

+}

+

+// Write file to output with HTTP headers

+function write_octet($file, $type, $expire) {

+ $bytes = file_get_contents($file);

+ header("Content-Type: image/$type");

+ header("Content-Length: " . strlen($bytes));

+ header("Cache-Control: public", true);

+ header("Pragma: public", true);

+ header('Expires: ' . gmdate('D, d M Y H:i:s', time() + $expire) . ' GMT', true);

+ echo $bytes;

+}

+

+?>

diff --git a/preview.php b/preview.php

new file mode 100644

index 0000000..cbfbfc7

--- /dev/null

+++ b/preview.php

@@ -0,0 +1,18 @@

+<?php

+

+include("init.php");

+

+// Get file if not cached yet

+if(!file_exists("$dir/cache/$hash.$ext"))

+ include("fetch.php");

+

+// Replace webp with jpeg

+if($ext == "webp")

+ $ext = "jpg";

+

+// Write HTTP headers and preview file

+write_octet("$dir/preview/$hash.$ext", $ext, $expire);

+

+exit;

+

+?>

diff --git a/preview/.empty b/preview/.empty

new file mode 100644

index 0000000..e69de29

diff --git a/temp/.empty b/temp/.empty

new file mode 100644

index 0000000..e69de29

Proxy Information
Original URL
gemini://git.brainsocks.xyz/brutalproxy/master/pcdiff/f1d7e7176719f4bd8956dfacc9ab4a13540e9936
Status Code
Success (20)
Meta
text/plain
Capsule Response Time
969.346139 milliseconds
Gemini-to-HTML Time
8.797715 milliseconds

This content has been proxied by September (ba2dc).