Compare commits
6 Commits
fd47eb1216
...
9733bd2f07
Author | SHA1 | Date |
---|---|---|
Sven Vogel | 9733bd2f07 | |
Sven Vogel | 6e2f5d4b1a | |
Sven Vogel | f55717de17 | |
Sven Vogel | 9912389ea7 | |
Sven Vogel | 6cc60cdd16 | |
Sven Vogel | c80e13b2e0 |
19
Dockerfile
19
Dockerfile
|
@ -1,10 +1,13 @@
|
||||||
FROM erseco/alpine-php-webserver
|
FROM golang:1.20-alpine
|
||||||
LABEL maintainer="Sven Vogel <sven.vogel123@web.de>"
|
WORKDIR /usr/src/app
|
||||||
LABEL version="1.0.1"
|
|
||||||
|
|
||||||
COPY php/index-inlined-minified.php /var/www/html/index.php
|
# pre-copy/cache go.mod for pre-downloading dependencies and only redownloading them in subsequent builds if they change
|
||||||
COPY php/messages.php /var/www/html/messages.php
|
COPY go.mod index-inlined-minified.html main.go ./
|
||||||
COPY nginx.conf /etc/nginx
|
RUN go mod download && go mod verify
|
||||||
|
|
||||||
# Let runit start nginx & php-fpm
|
RUN go build -v -o /usr/local/bin/app ./...
|
||||||
CMD [ "/bin/docker-entrypoint.sh" ]
|
|
||||||
|
ENV PORT=8000
|
||||||
|
ENV BIND=0.0.0.0
|
||||||
|
|
||||||
|
CMD ["app"]
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
|
||||||
|
compile-web:
|
||||||
|
cd web && inliner page.html > ../index-inlined-minified.html
|
||||||
|
|
||||||
|
run:
|
||||||
|
go run .
|
||||||
|
|
||||||
|
docker-build:
|
||||||
|
docker build -t errorpages .
|
||||||
|
|
||||||
|
docker-run:
|
||||||
|
docker run -itd --rm -p 8000:8000 -e BIND="0.0.0.0" -e PORT="8000" --name errorpages errorpages
|
|
@ -3,7 +3,8 @@
|
||||||
"go",
|
"go",
|
||||||
"gopls",
|
"gopls",
|
||||||
"nodejs",
|
"nodejs",
|
||||||
"nodePackages.vscode-html-languageserver-bin"
|
"nodePackages.vscode-html-languageserver-bin",
|
||||||
|
"nodePackages.inliner"
|
||||||
],
|
],
|
||||||
"nixpkgs": {
|
"nixpkgs": {
|
||||||
"commit": "f80ac848e3d6f0c12c52758c0f25c10c97ca3b62"
|
"commit": "f80ac848e3d6f0c12c52758c0f25c10c97ca3b62"
|
||||||
|
|
File diff suppressed because one or more lines are too long
|
@ -0,0 +1,92 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"errors"
|
||||||
|
"fmt"
|
||||||
|
"html/template"
|
||||||
|
"log"
|
||||||
|
"net/http"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
)
|
||||||
|
|
||||||
|
type StatusData struct {
|
||||||
|
Code string
|
||||||
|
Message string
|
||||||
|
Response int
|
||||||
|
}
|
||||||
|
|
||||||
|
var Statuses = map[string]string{
|
||||||
|
"401": "You are not authorized to access the resource",
|
||||||
|
"404": "The requested resource couldn't be found",
|
||||||
|
"403": "Access to the resource was denied for the server",
|
||||||
|
"405": "Method not supported by the server",
|
||||||
|
"407": "You are no authorized to access the resource",
|
||||||
|
"408": "Request timed out",
|
||||||
|
"410": "The requested content is permanently gone",
|
||||||
|
"414": "Requested URI is too long",
|
||||||
|
"415": "Unsupported media type",
|
||||||
|
"500": "The server encountered an internal error",
|
||||||
|
"501": "Method not supported by the server",
|
||||||
|
"502": "Requested endpoint encountered an error",
|
||||||
|
"503": "Service is currently unavailable",
|
||||||
|
"504": "Requested endpoint is unreachable",
|
||||||
|
"505": "Protocol version not supported",
|
||||||
|
"511": "Requested endpoint requires authentication for proxy",
|
||||||
|
}
|
||||||
|
|
||||||
|
func isStatusCode(code string) (int, error) {
|
||||||
|
num, err := strconv.Atoi(code)
|
||||||
|
if err != nil {
|
||||||
|
return 500, errors.New("not a number")
|
||||||
|
}
|
||||||
|
|
||||||
|
if num > 99 && num < 512 {
|
||||||
|
return num, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
return 500, errors.New("Invalid range")
|
||||||
|
}
|
||||||
|
|
||||||
|
func genStatus(request string) StatusData {
|
||||||
|
// create and init page status
|
||||||
|
var status StatusData
|
||||||
|
status.Code = "500"
|
||||||
|
status.Message = fmt.Sprintf("Invalid error response code recieved: %.5s[..]", request)
|
||||||
|
status.Response = 500
|
||||||
|
|
||||||
|
// check if we have a valid status code
|
||||||
|
var code, err = isStatusCode(request)
|
||||||
|
if err == nil {
|
||||||
|
status.Code = request
|
||||||
|
status.Message = fmt.Sprintf("Interrupted unsupported error response: %s", request)
|
||||||
|
status.Response = code
|
||||||
|
}
|
||||||
|
|
||||||
|
// set custom status message if present
|
||||||
|
description, ok := Statuses[request]
|
||||||
|
if ok {
|
||||||
|
status.Message = description
|
||||||
|
}
|
||||||
|
|
||||||
|
return status
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// load template
|
||||||
|
tmpl, err := template.ParseFiles("index-inlined-minified.html")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
|
||||||
|
status := genStatus(r.URL.Path[1:])
|
||||||
|
// set status code to propagate http error code
|
||||||
|
w.WriteHeader(status.Response)
|
||||||
|
tmpl.Execute(w, status)
|
||||||
|
})
|
||||||
|
|
||||||
|
var address = fmt.Sprintf("%s:%s", os.Getenv("BIND"), os.Getenv("PORT"))
|
||||||
|
|
||||||
|
log.Fatal(http.ListenAndServe(address, nil))
|
||||||
|
}
|
104
nginx.conf
104
nginx.conf
|
@ -1,104 +0,0 @@
|
||||||
worker_processes 1;
|
|
||||||
error_log stderr warn;
|
|
||||||
pid /run/nginx.pid;
|
|
||||||
|
|
||||||
events {
|
|
||||||
worker_connections 1024;
|
|
||||||
}
|
|
||||||
|
|
||||||
http {
|
|
||||||
include mime.types;
|
|
||||||
default_type application/octet-stream;
|
|
||||||
|
|
||||||
# Define custom log format to include reponse times
|
|
||||||
log_format main_timed '$remote_addr - $remote_user [$time_local] "$request" '
|
|
||||||
'$status $body_bytes_sent "$http_referer" '
|
|
||||||
'"$http_user_agent" "$http_x_forwarded_for" '
|
|
||||||
'$request_time $upstream_response_time $pipe $upstream_cache_status';
|
|
||||||
|
|
||||||
access_log /dev/stdout main_timed;
|
|
||||||
error_log /dev/stderr notice;
|
|
||||||
|
|
||||||
keepalive_timeout 65;
|
|
||||||
|
|
||||||
# Write temporary files to /tmp so they can be created as a non-privileged user
|
|
||||||
client_body_temp_path /tmp/client_temp;
|
|
||||||
proxy_temp_path /tmp/proxy_temp_path;
|
|
||||||
fastcgi_temp_path /tmp/fastcgi_temp;
|
|
||||||
uwsgi_temp_path /tmp/uwsgi_temp;
|
|
||||||
scgi_temp_path /tmp/scgi_temp;
|
|
||||||
|
|
||||||
# Default server definition
|
|
||||||
server {
|
|
||||||
listen 8080 default_server;
|
|
||||||
server_name _;
|
|
||||||
|
|
||||||
sendfile off;
|
|
||||||
|
|
||||||
# Increase proxy buffers for large requests
|
|
||||||
proxy_buffer_size 128k;
|
|
||||||
proxy_buffers 4 256k;
|
|
||||||
proxy_busy_buffers_size 256k;
|
|
||||||
|
|
||||||
# Upload limit
|
|
||||||
client_max_body_size 2M;
|
|
||||||
client_body_buffer_size 128k;
|
|
||||||
|
|
||||||
root /var/www/html;
|
|
||||||
index index.php index.html;
|
|
||||||
|
|
||||||
location / {
|
|
||||||
# First attempt to serve request as file, then
|
|
||||||
# as directory, then fall back to index.php
|
|
||||||
try_files $uri $uri/ /index.php?q=$uri&$args;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Redirect server error pages to the static page /50x.html
|
|
||||||
error_page 500 502 503 504 /50x.html;
|
|
||||||
location = /50x.html {
|
|
||||||
root /var/lib/nginx/html;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Pass the PHP scripts to PHP-FPM listening on 127.0.0.1:9000
|
|
||||||
location ~ [^/]\.php(/|$) {
|
|
||||||
fastcgi_split_path_info ^(.+\.php)(/.+)$;
|
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
fastcgi_param SCRIPT_NAME $fastcgi_script_name;
|
|
||||||
fastcgi_param PATH_INFO $fastcgi_path_info;
|
|
||||||
fastcgi_index index.php;
|
|
||||||
fastcgi_intercept_errors off;
|
|
||||||
include fastcgi_params;
|
|
||||||
}
|
|
||||||
|
|
||||||
location ~* \.(jpg|jpeg|gif|png|css|js|ico|xml)$ {
|
|
||||||
expires 5d;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Deny access to . files, for security
|
|
||||||
location ~ /\. {
|
|
||||||
log_not_found off;
|
|
||||||
deny all;
|
|
||||||
}
|
|
||||||
|
|
||||||
# Allow fpm ping and status from localhost
|
|
||||||
location ~ ^/(fpm-status|fpm-ping)$ {
|
|
||||||
access_log off;
|
|
||||||
allow 127.0.0.1;
|
|
||||||
deny all;
|
|
||||||
fastcgi_param SCRIPT_FILENAME $document_root$fastcgi_script_name;
|
|
||||||
include fastcgi_params;
|
|
||||||
fastcgi_pass 127.0.0.1:9000;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
# Include other server configs
|
|
||||||
include /etc/nginx/conf.d/*.conf;
|
|
||||||
|
|
||||||
gzip on;
|
|
||||||
gzip_proxied any;
|
|
||||||
gzip_types text/plain application/xml text/css text/js text/xml application/x-javascript text/javascript application/json application/xml+rss;
|
|
||||||
gzip_vary on;
|
|
||||||
gzip_disable "msie6";
|
|
||||||
|
|
||||||
}
|
|
|
@ -1,35 +0,0 @@
|
||||||
<?php
|
|
||||||
|
|
||||||
const RESPONSES = [
|
|
||||||
// Currently supported responses
|
|
||||||
// See: https://developer.mozilla.org/en-US/docs/Web/HTTP/Status#server_error_responses
|
|
||||||
401 => "You are not authorized to access the resource",
|
|
||||||
404 => "The requested resource couldn't be found",
|
|
||||||
403 => "Access to the resource was denied for the server",
|
|
||||||
405 => "Method not supported by the server",
|
|
||||||
407 => "You are no authorized to access the resource",
|
|
||||||
408 => "Request timed out",
|
|
||||||
500 => "The server encountered an internal error",
|
|
||||||
501 => "Method not supported by the server",
|
|
||||||
502 => "Requested endpoint encountered an error",
|
|
||||||
503 => "Service is currently unavailable",
|
|
||||||
504 => "Requested endpoint is unreachable",
|
|
||||||
511 => "Requested endpoint requires authentication for proxy",
|
|
||||||
];
|
|
||||||
|
|
||||||
function get_status_message($uri): array
|
|
||||||
{
|
|
||||||
$status = "501";
|
|
||||||
$message = "The received status is unsupported by this server: `" . substr($uri, 0, 10) . "`";
|
|
||||||
$int_code = 501;
|
|
||||||
|
|
||||||
$code = intval(trim(str_replace("/", "", $uri)));
|
|
||||||
|
|
||||||
if (key_exists($code, RESPONSES)) {
|
|
||||||
$int_code = $code;
|
|
||||||
$status = (string) $code;
|
|
||||||
$message = RESPONSES[$code];
|
|
||||||
}
|
|
||||||
|
|
||||||
return [$status, $message, $int_code];
|
|
||||||
}
|
|
|
@ -163,4 +163,4 @@ div {
|
||||||
100% {
|
100% {
|
||||||
background-position: calc(100% + 8rem) 0;
|
background-position: calc(100% + 8rem) 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,11 +1,3 @@
|
||||||
<?php
|
|
||||||
include "messages.php";
|
|
||||||
|
|
||||||
global $response;
|
|
||||||
$response = get_status_message($_SERVER["REQUEST_URI"]);
|
|
||||||
|
|
||||||
http_response_code($response[2]);
|
|
||||||
?>
|
|
||||||
<!doctype html>
|
<!doctype html>
|
||||||
<html lang="en">
|
<html lang="en">
|
||||||
<head>
|
<head>
|
||||||
|
@ -13,6 +5,7 @@ http_response_code($response[2]);
|
||||||
<meta name="viewport"
|
<meta name="viewport"
|
||||||
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
content="width=device-width, user-scalable=no, initial-scale=1.0, maximum-scale=1.0, minimum-scale=1.0">
|
||||||
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
||||||
|
<meta name="darkreader-lock"> <!-- Request dark reader to ignore this site. See: https://github.com/darkreader/darkreader/blob/main/CONTRIBUTING.md#disabling-dark-reader-on-your-site -->
|
||||||
<title>Montehaselino - Automatic Status Response</title>
|
<title>Montehaselino - Automatic Status Response</title>
|
||||||
<link href="master.css" rel="stylesheet"/>
|
<link href="master.css" rel="stylesheet"/>
|
||||||
</head>
|
</head>
|
||||||
|
@ -24,14 +17,15 @@ http_response_code($response[2]);
|
||||||
<img id="mountain" src="res/svg/error-page-overlay.svg" alt="">
|
<img id="mountain" src="res/svg/error-page-overlay.svg" alt="">
|
||||||
<div id="rocks"></div>
|
<div id="rocks"></div>
|
||||||
<h1>ERROR</h1>
|
<h1>ERROR</h1>
|
||||||
<?php
|
<h2>{{.Code}}</h2>
|
||||||
global $response;
|
<h3>{{.Message}}</h3>
|
||||||
echo "<h2>" . $response[0] ."</h2>";
|
|
||||||
echo "<h3>" . $response[1] . "</h3>";
|
|
||||||
?>
|
|
||||||
<a href="javascript:window.history.back();">Go Back</a>
|
<a href="javascript:window.history.back();">Go Back</a>
|
||||||
<hr>
|
<hr>
|
||||||
<div class="subtle">This is an automatically generated error response page.<br>Please contact administration if you feel this shouldn't be here.</div>
|
<div class="subtle">
|
||||||
|
This is an automatically generated error response page. <br>
|
||||||
|
Please contact administration if you feel this shouldn't be here.
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</body>
|
</body>
|
||||||
</html>
|
</html>
|
||||||
|
|
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 1.9 KiB |
Before Width: | Height: | Size: 11 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 1.3 KiB After Width: | Height: | Size: 1.3 KiB |
Loading…
Reference in New Issue