WIP: Refractor code / remove html engine / new restapi #21

Draft
Phil wants to merge 2 commits from backend/rework-restapi into main
10 changed files with 58 additions and 257 deletions

View file

@ -18,4 +18,4 @@ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
SOFTWARE.

4
go.mod
View file

@ -7,7 +7,6 @@ toolchain go1.24.2
require (
github.com/go-redis/redis/v8 v8.11.5
github.com/gofiber/fiber/v2 v2.52.6
github.com/gofiber/template/html/v2 v2.1.3
github.com/joho/godotenv v1.5.1
github.com/matoous/go-nanoid/v2 v2.1.0
)
@ -16,8 +15,6 @@ require (
github.com/andybalholm/brotli v1.1.1 // indirect
github.com/cespare/xxhash/v2 v2.3.0 // indirect
github.com/dgryski/go-rendezvous v0.0.0-20200823014737-9f7001d12a5f // indirect
github.com/gofiber/template v1.8.3 // indirect
github.com/gofiber/utils v1.1.0 // indirect
github.com/google/uuid v1.6.0 // indirect
github.com/klauspost/compress v1.18.0 // indirect
github.com/mattn/go-colorable v0.1.14 // indirect
@ -25,6 +22,7 @@ require (
github.com/mattn/go-runewidth v0.0.16 // indirect
github.com/philhofer/fwd v1.1.3-0.20240916144458-20a13a1f6b7c // indirect
github.com/rivo/uniseg v0.4.7 // indirect
github.com/stretchr/testify v1.10.0 // indirect
github.com/tinylib/msgp v1.2.5 // indirect
github.com/valyala/bytebufferpool v1.0.0 // indirect
github.com/valyala/fasthttp v1.60.0 // indirect

6
go.sum
View file

@ -12,12 +12,6 @@ github.com/go-redis/redis/v8 v8.11.5 h1:AcZZR7igkdvfVmQTPnu9WE37LRrO/YrBH5zWyjDC
github.com/go-redis/redis/v8 v8.11.5/go.mod h1:gREzHqY1hg6oD9ngVRbLStwAWKhA0FEgq8Jd4h5lpwo=
github.com/gofiber/fiber/v2 v2.52.6 h1:Rfp+ILPiYSvvVuIPvxrBns+HJp8qGLDnLJawAu27XVI=
github.com/gofiber/fiber/v2 v2.52.6/go.mod h1:YEcBbO/FB+5M1IZNBP9FO3J9281zgPAreiI1oqg8nDw=
github.com/gofiber/template v1.8.3 h1:hzHdvMwMo/T2kouz2pPCA0zGiLCeMnoGsQZBTSYgZxc=
github.com/gofiber/template v1.8.3/go.mod h1:bs/2n0pSNPOkRa5VJ8zTIvedcI/lEYxzV3+YPXdBvq8=
github.com/gofiber/template/html/v2 v2.1.3 h1:n1LYBtmr9C0V/k/3qBblXyMxV5B0o/gpb6dFLp8ea+o=
github.com/gofiber/template/html/v2 v2.1.3/go.mod h1:U5Fxgc5KpyujU9OqKzy6Kn6Qup6Tm7zdsISR+VpnHRE=
github.com/gofiber/utils v1.1.0 h1:vdEBpn7AzIUJRhe+CiTOJdUcTg4Q9RK+pEa0KPbLdrM=
github.com/gofiber/utils v1.1.0/go.mod h1:poZpsnhBykfnY1Mc0KeEa6mSHrS3dV0+oBWyeQmb2e0=
github.com/google/uuid v1.6.0 h1:NIvaJDMOsjHA8n1jAhLSgzrAzy1Hgr+hNrb57e+94F0=
github.com/google/uuid v1.6.0/go.mod h1:TIyPZe4MgqvfeYDBFedMoGGpEw/LqOeaOT+nhxU+yHo=
github.com/joho/godotenv v1.5.1 h1:7eLL/+HRGLY0ldzfGMeQkb7vMd0as4CfYvUVzLqw0N0=

View file

@ -1,21 +1,15 @@
package main
import (
"embed"
"log"
"net/http"
"git.hackmi.ch/Phil/goshorly/db"
"git.hackmi.ch/Phil/goshorly/routes"
"git.hackmi.ch/Phil/goshorly/utils"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/middleware/limiter"
"github.com/gofiber/template/html/v2"
)
//go:embed views/*
var viewsfs embed.FS
func main() {
utils.Print_Starting_Screen()
utils.Init_env_file()
@ -24,11 +18,8 @@ func main() {
db.Init_redis()
engine := html.NewFileSystem(http.FS(viewsfs), ".html")
app := fiber.New(fiber.Config{
CaseSensitive: true,
Views: engine,
})
app.Get("/", routes.Gethome)

View file

@ -1,19 +1,9 @@
package routes
import (
"git.hackmi.ch/Phil/goshorly/db"
"git.hackmi.ch/Phil/goshorly/utils"
"github.com/gofiber/fiber/v2"
)
func Gethome(c *fiber.Ctx) error {
return c.Render("views/home", fiber.Map{
"CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
"CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
"CI_TAGGED": utils.CI_TAGGED,
"CI_BUILD": utils.CI_BUILD,
"TotalLinks": db.GetTotalLinks(),
"TotalViews": db.GetTotalViews(),
})
return c.SendString("Homepage")
}

View file

@ -4,7 +4,6 @@ import (
"log"
"git.hackmi.ch/Phil/goshorly/db"
"git.hackmi.ch/Phil/goshorly/utils"
"github.com/gofiber/fiber/v2"
)
@ -18,9 +17,7 @@ func ID(c *fiber.Ctx) error {
"url": "URL not found",
})
} else {
return c.Render("views/404", fiber.Map{
"BASEURL": utils.URL,
})
return c.SendStatus(404)
}
}

View file

@ -27,16 +27,16 @@ func Posthome(c *fiber.Ctx) error {
})
}
return c.Status(500).Render("views/home", fiber.Map{
"ERR": "Parsing Error",
"CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
"CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
"CI_TAGGED": utils.CI_TAGGED,
"CI_BUILD": utils.CI_BUILD,
"TotalLinks": db.GetTotalLinks(),
"TotalViews": db.GetTotalViews(),
})
// return c.Status(500).Render("views/home", fiber.Map{
// "ERR": "Parsing Error",
// "CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
// "CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
// "CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
// "CI_TAGGED": utils.CI_TAGGED,
// "CI_BUILD": utils.CI_BUILD,
// "TotalLinks": db.GetTotalLinks(),
// "TotalViews": db.GetTotalViews(),
// })
}
if !regexp.MustCompile(`^(http|https|mailto|ts3server)://`).MatchString(u.URL) {
@ -48,16 +48,16 @@ func Posthome(c *fiber.Ctx) error {
})
}
return c.Status(424).Render("views/home", fiber.Map{
"ERR": "Invalid URL, please check and try again.",
"CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
"CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
"CI_TAGGED": utils.CI_TAGGED,
"CI_BUILD": utils.CI_BUILD,
"TotalLinks": db.GetTotalLinks(),
"TotalViews": db.GetTotalViews(),
})
// return c.Status(424).Render("views/home", fiber.Map{
// "ERR": "Invalid URL, please check and try again.",
// "CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
// "CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
// "CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
// "CI_TAGGED": utils.CI_TAGGED,
// "CI_BUILD": utils.CI_BUILD,
// "TotalLinks": db.GetTotalLinks(),
// "TotalViews": db.GetTotalViews(),
// })
}
id, err := gonanoid.New(8)
@ -71,16 +71,16 @@ func Posthome(c *fiber.Ctx) error {
})
}
return c.Status(500).Render("views/home", fiber.Map{
"ERR": err.Error(),
"CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
"CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
"CI_TAGGED": utils.CI_TAGGED,
"CI_BUILD": utils.CI_BUILD,
"TotalLinks": db.GetTotalLinks(),
"TotalViews": db.GetTotalViews(),
})
// return c.Status(500).Render("views/home", fiber.Map{
// "ERR": err.Error(),
// "CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
// "CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
// "CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
// "CI_TAGGED": utils.CI_TAGGED,
// "CI_BUILD": utils.CI_BUILD,
// "TotalLinks": db.GetTotalLinks(),
// "TotalViews": db.GetTotalViews(),
// })
}
err = db.Set(id, u.URL, 1296000*time.Second)
@ -93,16 +93,16 @@ func Posthome(c *fiber.Ctx) error {
})
}
return c.Status(500).Render("views/home", fiber.Map{
"ERR": err.Error(),
"CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
"CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
"CI_TAGGED": utils.CI_TAGGED,
"CI_BUILD": utils.CI_BUILD,
"TotalLinks": db.GetTotalLinks(),
"TotalViews": db.GetTotalViews(),
})
// return c.Status(500).Render("views/home", fiber.Map{
// "ERR": err.Error(),
// "CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
// "CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
// "CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
// "CI_TAGGED": utils.CI_TAGGED,
// "CI_BUILD": utils.CI_BUILD,
// "TotalLinks": db.GetTotalLinks(),
// "TotalViews": db.GetTotalViews(),
// })
}
fURL := utils.URL + id
@ -121,14 +121,16 @@ func Posthome(c *fiber.Ctx) error {
})
}
return c.Status(201).Render("views/home", fiber.Map{
"URL": fURL,
"CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
"CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
"CI_TAGGED": utils.CI_TAGGED,
"CI_BUILD": utils.CI_BUILD,
"TotalLinks": db.GetTotalLinks(),
"TotalViews": db.GetTotalViews(),
})
// return c.Status(201).Render("views/home", fiber.Map{
// "URL": fURL,
// "CI_COMMIT_SHA": utils.CI_COMMIT_SHA,
// "CI_COMMIT_BRANCH": utils.CI_COMMIT_BRANCH,
// "CI_COMMIT_TAG": utils.CI_COMMIT_TAG,
// "CI_TAGGED": utils.CI_TAGGED,
// "CI_BUILD": utils.CI_BUILD,
// "TotalLinks": db.GetTotalLinks(),
// "TotalViews": db.GetTotalViews(),
// })
return c.SendStatus(200)
}

View file

@ -12,16 +12,11 @@ var ConfigLimiter limiter.Config = limiter.Config{
Expiration: 60 * time.Second,
LimitReached: func(c *fiber.Ctx) error {
if c.Get("content-type") == "application/json" {
return c.Status(418).JSON(fiber.Map{
return c.Status(429).JSON(fiber.Map{
"msg": "Too many requests, slow down I'm a teapot (10 requests per minute)",
"success": false,
})
}
return c.Render("views/home", fiber.Map{
"ERR": "You have reached the limit of requests! Please check back later. (1 minute)",
"CI_COMMIT_SHA": CI_COMMIT_SHA,
"CI_COMMIT_BRANCH": CI_COMMIT_BRANCH,
"CI_BUILD": CI_BUILD,
})
return c.SendStatus(429)
},
}

View file

@ -1,68 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>Uff 404</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/css/bootstrap.min.css" rel="stylesheet"
integrity="sha384-F3w7mX95PdgyTmZZMECAngseQB83DfGTowi0iMjiWaeVhAn4FJkqJByhZMI3AhiU" crossorigin="anonymous">
<style>
@import url('https://fonts.googleapis.com/css?family=Montserrat:300');
body {
background: #3498DB;
color: #fff;
font-family: 'Montserrat', sans-serif;
font-size: 16px;
}
h1 {
font-size: 20vh;
}
h2 span {
font-size: 4rem;
font-weight: 600;
}
a:link,
a:visited {
text-decoration: none;
color: #fff;
}
h3 a:hover {
text-decoration: none;
background: #fff;
color: #3498DB;
cursor: pointer;
}
</style>
</head>
<body>
<div class="container">
<h1>:(</h1><br>
<h2>A <span>404</span> error occured, Page not found, check the URL and try again.</h2>
<hr>
<h2>Ein <span>404</span> Fehler ist aufgetreten, Seite nicht gefunden, überprüfen Sie die URL und versuchen Sie es erneut.</h2>
<hr>
<h2><span>404</span> エラーが発生しました。ページが見つかりません。URLを確認して、再試行してください。</h2>
<hr>
<h2>发生 <span>404</span> 错误,找不到页面,请检查 URL 并重试。</h2>
<br><br>
<h3><a href="{{ .BASEURL }}">Return to home</a>&nbsp;|&nbsp;<a href="javascript:history.back()">Go Back</a>
</h3>
</div>
</main>
<!-- Bootstrap JS -->
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>
</body>
</html>

View file

@ -1,98 +0,0 @@
<!doctype html>
<html lang="en">
<head>
<title>goshorly</title>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
<link href="https://cdnjs.cloudflare.com/ajax/libs/font-awesome/6.7.2/css/all.min.css" rel="stylesheet">
<link href="https://bootswatch.com/4/darkly/bootstrap.min.css" rel="stylesheet">
</head>
<style>
html {
height: 100%;
}
body {
height: 100%;
display: grid;
grid-template-rows: auto 1fr auto;
}
footer {
background-color: #303030;
padding: 10px;
}
</style>
<body>
<br><br>
<div class="container">
<div class="jumbotron">
<h1>goshorly</h1>
<p>An dead simple & fast URL shortener. <br>
All shorten URLs will be available for 30days!
</p>
{{ if and .TotalLinks .TotalViews }}
<p>This Instance has served over {{ .TotalLinks }} URLs and {{ .TotalViews }} total Views!</p>
{{ end }}
<hr>
<form method="post" action="#">
<fieldset>
<input type="text" class="form-control" id="surl" name="surl" placeholder="https://google.de"
required>
<br>
<center>
<button type="submit" class="btn btn-primary btn-lg">Submit</button>
</center>
</fieldset>
</form>
</div>
<!-- URL PASS CHECK -->
{{ if .URL }}
<div style="padding-right: 20px;" class="alert alert-dismissible alert-success">
<input id="foo" class="form-control" value="{{ .URL }}" readonly>
<br>
<center>
<button class="btn-copy btn btn-success" data-clipboard-target="#foo">
Copy to clipboard
</button>
</center>
</div>
{{ end }}
<!-- URL FAIL CHECK -->
{{ if .ERR }}
<div style="padding-right: 20px;" class="alert alert-dismissible alert-danger">
<p style="margin-bottom: 0px;">{{ .ERR }}</p>
</div>
{{ end }}
</div>
<!-- Footer with Build-Check -->
<footer>
<center>
Made with <a href="https://git.hackmi.ch/Phil/goshorly"><i class="fas fa-code-branch"></i>
Phil/goshorly</a>
{{ if .CI_BUILD }}
{{ if .CI_COMMIT_TAG }}
| {{ .CI_COMMIT_TAG }}
{{ else }}
| {{ .CI_COMMIT_SHA }}/{{ .CI_COMMIT_BRANCH }}
{{ end }}
{{ end }}
</center>
</footer>
<script src="https://cdn.jsdelivr.net/npm/bootstrap@5.1.1/dist/js/bootstrap.bundle.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/clipboard@2.0.8/dist/clipboard.min.js"></script>
<script>
new ClipboardJS('body > div > div.alert.alert-dismissible.alert-success > center > button');
</script>
</body>
</html>