From 9da9e37f32e0e06f99d18c62540d0d9d44f3ce44 Mon Sep 17 00:00:00 2001 From: Jan-Lukas Else Date: Tue, 22 Dec 2020 22:15:29 +0100 Subject: [PATCH] Short URLs --- databaseMigrations.go | 9 ++++++ http.go | 3 ++ posts.go | 1 + postsFuncs.go | 8 ++++++ render.go | 3 ++ shortPath.go | 64 +++++++++++++++++++++++++++++++++++++++++++ telegram.go | 2 +- templates/post.gohtml | 1 + 8 files changed, 90 insertions(+), 1 deletion(-) create mode 100644 shortPath.go diff --git a/databaseMigrations.go b/databaseMigrations.go index b2e23cf..f238f66 100644 --- a/databaseMigrations.go +++ b/databaseMigrations.go @@ -97,6 +97,15 @@ func migrateDb() error { return err }, }, + &migrator.Migration{ + Name: "00008", + Func: func(tx *sql.Tx) error { + _, err := tx.Exec(` + create table shortpath (id integer primary key autoincrement, path text not null, unique(path)); + `) + return err + }, + }, ), ) if err != nil { diff --git a/http.go b/http.go index 1c516a9..8d684a0 100644 --- a/http.go +++ b/http.go @@ -173,6 +173,9 @@ func buildHandler() (http.Handler, error) { r.With(cacheMiddleware).Get(path, serveAsset) } + // Short paths + r.With(cacheMiddleware).Get("/s/{id:[0-9a-fA-F]+}", redirectToLongPath) + paginationPath := "/page/{page:[0-9-]+}" feedPath := ".{feed:rss|json|atom}" diff --git a/posts.go b/posts.go index d558f47..ce8af11 100644 --- a/posts.go +++ b/posts.go @@ -51,6 +51,7 @@ func servePost(w http.ResponseWriter, r *http.Request) { if canonical == "" { canonical = p.fullURL() } + w.Header().Add("Link", fmt.Sprintf("<%s>; rel=shortlink", p.shortURL())) render(w, templatePost, &renderData{ blogString: p.Blog, Canonical: canonical, diff --git a/postsFuncs.go b/postsFuncs.go index a0a69ed..e3092bb 100644 --- a/postsFuncs.go +++ b/postsFuncs.go @@ -12,6 +12,14 @@ func (p *post) fullURL() string { return appConfig.Server.PublicAddress + p.Path } +func (p *post) shortURL() string { + s, err := shortenPath(p.Path) + if err != nil { + return "" + } + return appConfig.Server.PublicAddress + s +} + func (p *post) firstParameter(parameter string) (result string) { if pp := p.Parameters[parameter]; len(pp) > 0 { result = pp[0] diff --git a/render.go b/render.go index df2064e..64b4ae0 100644 --- a/render.go +++ b/render.go @@ -85,6 +85,9 @@ func initRendering() error { }) return mentions }, + "shorturl": func(p *post) string { + return p.shortURL() + }, // Others "dateformat": func(date string, format string) string { d, err := dateparse.ParseLocal(date) diff --git a/shortPath.go b/shortPath.go new file mode 100644 index 0000000..04dfa62 --- /dev/null +++ b/shortPath.go @@ -0,0 +1,64 @@ +package main + +import ( + "database/sql" + "errors" + "fmt" + "net/http" + "strconv" + + "github.com/go-chi/chi" +) + +func shortenPath(p string) (string, error) { + if p == "" { + return "", errors.New("empty path") + } + id := getShortPathID(p) + if id == -1 { + _, err := appDbExec("insert or ignore into shortpath (path) values (@path)", sql.Named("path", p)) + if err != nil { + return "", err + } + id = getShortPathID(p) + } + if id == -1 { + return "", errors.New("failed to retrieve short path for " + p) + } + return fmt.Sprintf("/s/%x", id), nil +} + +func getShortPathID(p string) (id int) { + if p == "" { + return -1 + } + row, err := appDbQueryRow("select id from shortpath where path = @path", sql.Named("path", p)) + if err != nil { + return -1 + } + err = row.Scan(&id) + if err != nil { + return -1 + } + return id +} + +func redirectToLongPath(rw http.ResponseWriter, r *http.Request) { + id, err := strconv.ParseInt(chi.URLParam(r, "id"), 16, 64) + if err != nil { + serve404(rw, r) + return + } + row, err := appDbQueryRow("select path from shortpath where id = @id", sql.Named("id", id)) + if err != nil { + serve404(rw, r) + return + } + var path string + err = row.Scan(&path) + if err != nil { + serve404(rw, r) + return + } + http.Redirect(rw, r, path, http.StatusFound) +} diff --git a/telegram.go b/telegram.go index eab36b7..7731151 100644 --- a/telegram.go +++ b/telegram.go @@ -35,7 +35,7 @@ func (p *post) tgPost() { message.WriteString(title) message.WriteString("\n\n") } - message.WriteString(p.fullURL()) + message.WriteString(p.shortURL()) sendTelegramMessage(message.String(), tg.BotToken, tg.ChatID) } diff --git a/templates/post.gohtml b/templates/post.gohtml index 6e01a4a..5dc516a 100644 --- a/templates/post.gohtml +++ b/templates/post.gohtml @@ -1,6 +1,7 @@ {{ define "title" }} {{ with p .Data "title" }}{{ . }} - {{end}}{{ .Blog.Title }} {{ include "postheadmeta" . }} + {{ with shorturl .Data }}{{ end }} {{ end }} {{ define "main" }}