This commit is contained in:
Mael G. 2023-03-19 15:07:40 +01:00
commit 1a9481bd83
7 changed files with 253 additions and 0 deletions

61
Makefile Normal file
View file

@ -0,0 +1,61 @@
EXTENSION ?=
DIST_DIR ?= dist/
GOOS ?= linux
ARCH ?= $(shell uname -m)
BUILDINFOSDET ?=
SOFT_NAME := epee_service
SOFT_VERSION := $(shell git describe --tags $(git rev-list --tags --max-count=1))
VERSION_PKG := $(shell echo $(SOFT_VERSION) | sed 's/^v//g')
ARCH := x86_64
LICENSE := AGPL-3
URL := https://git.gnous.eu/enpls/epee-service
DESCRIPTION := EnPLS Epee (Enpls Proxy EnginE) Utility Service
BUILDINFOS := ($(shell date +%FT%T%z)$(BUILDINFOSDET))
LDFLAGS := '-X main.version=$(SOFT_VERSION) -X main.buildinfos=$(BUILDINFOS)'
OUTPUT_SOFT := $(DIST_DIR)frite-$(SOFT_VERSION)-$(GOOS)-$(ARCH)$(EXTENSION)
.PHONY: vet
vet:
go vet main.go
.PHONY: test
test:
go test -v ./...
.PHONY: prepare
prepare:
mkdir -p $(DIST_DIR)
.PHONY: clean
clean:
rm -rf $(DIST_DIR)
.PHONY: build
build: prepare
go build -ldflags $(LDFLAGS) -o $(OUTPUT_SOFT)
.PHONY: package-deb
package-deb: prepare
fpm -s dir -t deb -n $(SOFT_NAME) -v $(VERSION_PKG) \
--description "$(DESCRIPTION)" \
--url "$(URL)" \
--architecture $(ARCH) \
--license "$(LICENSE)" \
--package $(DIST_DIR) \
$(OUTPUT_SOFT)=/usr/bin/frite-web \
extra/links.txt.example=/etc/frite/links.txt \
extra/frite-web.service=/usr/lib/systemd/system/frite-web.service
.PHONY: package-rpm
package-rpm: prepare
fpm -s dir -t rpm -n $(SOFT_NAME) -v $(VERSION_PKG) \
--description "$(DESCRIPTION)" \
--url "$(URL)" \
--architecture $(ARCH) \
--license "$(LICENSE) "\
--package $(DIST_DIR) \
$(OUTPUT_SOFT)=/usr/bin/frite-web \
extra/links.txt.example=/etc/frite/links.txt \
extra/frite-web.service=/usr/lib/systemd/system/frite-web.service

3
go.mod Normal file
View file

@ -0,0 +1,3 @@
module git.gnous.eu/enpls/epee-service
go 1.19

77
main.go Normal file
View file

@ -0,0 +1,77 @@
package main
import (
"embed"
"encoding/json"
"fmt"
"html/template"
"log"
"net/http"
)
//go:embed static
var staticFS embed.FS
//go:embed templates
var templatesFS embed.FS
// Error model
type Error struct {
Title string `json:"title"`
Message string `json:"message"`
}
func main() {
port := "5900"
http.Handle("/static/", http.FileServer(http.FS(staticFS)))
http.HandleFunc("/", errorHandler)
log.Printf("Listening on :%s...", port)
err := http.ListenAndServe(fmt.Sprintf(":%s", port), nil)
if err != nil {
log.Fatal(err)
}
}
func errorHandler(w http.ResponseWriter, r *http.Request) {
errorCode := r.URL.Query().Get("error")
// Load error messages from JSON file
jsonData, err := templatesFS.ReadFile("templates/errors.json")
if err != nil {
generateInternalServerError(w, err)
return
}
errors := make(map[string]Error)
err = json.Unmarshal(jsonData, &errors)
if err != nil {
generateInternalServerError(w, err)
return
}
errorData := errors[errorCode]
if errorData.Title == "" {
errorData.Title = "Error"
errorData.Message = "An error occurred."
}
// Render error page
tmpl, err := templatesFS.ReadFile("templates/error.html")
if err != nil {
generateInternalServerError(w, err)
return
}
t, err := template.New("error").Parse(string(tmpl))
if err != nil {
generateInternalServerError(w, err)
return
}
t.Execute(w, errorData)
}
func generateInternalServerError(w http.ResponseWriter, err error) {
log.Println(err)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
w.WriteHeader(http.StatusInternalServerError)
w.Write([]byte(`{"error": "Internal Server Error"}`))
}

Binary file not shown.

61
static/main.css Normal file
View file

@ -0,0 +1,61 @@
@import url('https://fonts.googleapis.com/css2?family=Nunito:wght@500;800&display=swap');
* {
margin: 0px;
padding: 0px;
}
body {
font-family: 'Nunito', sans-serif;
background-color: #f1efe9;
color: #282828;
font-weight: 500;
}
h1 {
font-weight: 800;
}
.container {
display: flex;
min-height: 100vh;
flex-direction: column;
}
.main {
flex: 1;
}
.header {
padding: 20px;
text-align: center;
}
.main {
width: 80%;
margin: 0 auto;
margin-top: 5vh;
}
.main h1 {
font-size: 8vh;
}
.main p {
padding-top: 0.5vh;
}
.footer {
background-color: #282828;
color: #f1efe9;
padding: 20px;
text-align: center;
}
.main a {
color: #7d5fff;
}
.footer a {
color: #f1efe9;
}

29
templates/error.html Normal file
View file

@ -0,0 +1,29 @@
<!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta http-equiv="X-UA-Compatible" content="IE=edge">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<title>{{.Title}}</title>
<link rel="stylesheet" href="/static/main.css">
</head>
<body>
<div class="container">
<div class="header">
<h1>EnPLS Network </h1>
</div>
<div class="main">
<h1>{{.Title}}</h1>
<p>{{.Message}}</p>
<p>If you believe that this situation is unusual, please don't hesitate to <a
href="mailto:mael@enpls.org">contact us</a>.
</div>
<div class="footer">
<p>&copy; Copyright {{.Year}} EnPLS Network - <a href="https://enpls.org">enpls.org</a> </p>
</div>
</div>
</body>
</html>

22
templates/errors.json Normal file
View file

@ -0,0 +1,22 @@
{
"404": {
"title": "404, Page Not Found.",
"message": "Ooops! It looks like the ressource you were looking for is no were to be found."
},
"403": {
"title": "403, Access Denied.",
"message": "Ooops! It looks like you don't have the right to access this ressource."
},
"502": {
"title": "502, Backend Unavailable.",
"message": "Ooops! The requested backend service is unavailable. This error might be due to an ongoing maintenance or a service disruption. You might want to take a look at our service status page."
},
"503": {
"title": "503, Service Unavailable.",
"message": "Ooops! The requested service is unavailable. This error might be due to an ongoing maintenance or a service disruption. You might want to take a look at our service status page."
},
"500": {
"title": "500, Internal Server Error.",
"message": "Ooops! It looks like something went wrong on our side. We are working on it and will be back shortly."
}
}