mirror of https://github.com/jlelse/GoBlog
Reimplement redirects
This commit is contained in:
parent
53c55c9a6b
commit
352c0f4d82
18
api.go
18
api.go
|
@ -29,20 +29,30 @@ func apiPostCreateHugo(w http.ResponseWriter, r *http.Request) {
|
|||
p.Path = path
|
||||
p.Section = section
|
||||
p.Slug = slug
|
||||
aliases = append(aliases, alias)
|
||||
err = p.replace()
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
for _, alias := range aliases {
|
||||
aliases = append(aliases, alias)
|
||||
for i, alias := range aliases {
|
||||
// Fix relativ paths
|
||||
if !strings.HasPrefix(alias, "/") {
|
||||
splittedPostPath := strings.Split(p.Path, "/")
|
||||
alias = strings.TrimSuffix(p.Path, splittedPostPath[len(splittedPostPath)-1]) + alias
|
||||
}
|
||||
if alias != "" {
|
||||
_ = createOrReplaceRedirect(alias, p.Path)
|
||||
alias = strings.TrimSuffix(alias, "/")
|
||||
if alias == p.Path {
|
||||
alias = ""
|
||||
}
|
||||
aliases[i] = alias
|
||||
}
|
||||
if len(aliases) > 0 {
|
||||
p.Parameters["aliases"] = aliases
|
||||
err = p.replace()
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusBadRequest)
|
||||
return
|
||||
}
|
||||
}
|
||||
w.Header().Set("Location", appConfig.Server.PublicAddress+p.Path)
|
||||
|
|
|
@ -19,7 +19,6 @@ func migrateDb() error {
|
|||
CREATE TABLE post_parameters (id integer primary key autoincrement, path text not null, parameter text not null, value text);
|
||||
CREATE INDEX index_pp_path on post_parameters (path);
|
||||
CREATE TRIGGER AFTER DELETE on posts BEGIN delete from post_parameters where path = old.path; END;
|
||||
CREATE TABLE redirects (fromPath text not null, toPath text not null, primary key (fromPath, toPath));
|
||||
CREATE TABLE indieauthauth (time text not null, code text not null, me text not null, client text not null, redirect text not null, scope text not null);
|
||||
CREATE TABLE indieauthtoken (time text not null, token text not null, me text not null, client text not null, scope text not null);
|
||||
CREATE INDEX index_iat_token on indieauthtoken (token);
|
||||
|
|
8
http.go
8
http.go
|
@ -174,14 +174,14 @@ func buildHandler() (http.Handler, error) {
|
|||
}
|
||||
}
|
||||
|
||||
// Redirects
|
||||
allRedirectPaths, err := allRedirectPaths()
|
||||
// Post aliases
|
||||
allPostAliases, err := allPostAliases()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for _, path := range allRedirectPaths {
|
||||
for _, path := range allPostAliases {
|
||||
if path != "" {
|
||||
r.With(cacheMiddleware, minifier.Middleware).Get(path, serveRedirect)
|
||||
r.With(cacheMiddleware).Get(path, servePostAlias)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -0,0 +1,39 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"net/http"
|
||||
)
|
||||
|
||||
func allPostAliases() ([]string, error) {
|
||||
var aliases []string
|
||||
rows, err := appDbQuery("select distinct value from post_parameters where parameter = 'aliases' and value != path")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var path string
|
||||
_ = rows.Scan(&path)
|
||||
aliases = append(aliases, path)
|
||||
}
|
||||
return aliases, nil
|
||||
}
|
||||
|
||||
func servePostAlias(w http.ResponseWriter, r *http.Request) {
|
||||
row, err := appDbQueryRow("select path from post_parameters where parameter = 'aliases' and value = @alias", sql.Named("alias", r.URL.Path))
|
||||
if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
var path string
|
||||
err = row.Scan(&path)
|
||||
if err == sql.ErrNoRows {
|
||||
serve404(w, r)
|
||||
return
|
||||
} else if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
http.Redirect(w, r, path, http.StatusFound)
|
||||
return
|
||||
}
|
72
redirects.go
72
redirects.go
|
@ -1,72 +0,0 @@
|
|||
package main
|
||||
|
||||
import (
|
||||
"database/sql"
|
||||
"errors"
|
||||
"net/http"
|
||||
"strings"
|
||||
)
|
||||
|
||||
var errRedirectNotFound = errors.New("redirect not found")
|
||||
|
||||
func serveRedirect(w http.ResponseWriter, r *http.Request) {
|
||||
redirect, err := getRedirect(r.URL.Path)
|
||||
if err == errRedirectNotFound {
|
||||
serve404(w, r)
|
||||
return
|
||||
} else if err != nil {
|
||||
http.Error(w, err.Error(), http.StatusInternalServerError)
|
||||
return
|
||||
}
|
||||
// Send redirect
|
||||
w.Header().Set("Location", redirect)
|
||||
render(w, templateRedirect, &renderData{
|
||||
Data: redirect,
|
||||
})
|
||||
w.WriteHeader(http.StatusFound)
|
||||
}
|
||||
|
||||
func getRedirect(fromPath string) (string, error) {
|
||||
var toPath string
|
||||
row, err := appDbQueryRow("with recursive f (i, fp, tp) as (select 1, fromPath, toPath from redirects where fromPath = ? union all select f.i + 1, r.fromPath, r.toPath from redirects as r join f on f.tp = r.fromPath) select tp from f order by i desc limit 1", fromPath)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
err = row.Scan(&toPath)
|
||||
if err == sql.ErrNoRows {
|
||||
return "", errRedirectNotFound
|
||||
} else if err != nil {
|
||||
return "", err
|
||||
}
|
||||
return toPath, nil
|
||||
}
|
||||
|
||||
func allRedirectPaths() ([]string, error) {
|
||||
var redirectPaths []string
|
||||
rows, err := appDbQuery("select fromPath from redirects")
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
for rows.Next() {
|
||||
var path string
|
||||
_ = rows.Scan(&path)
|
||||
redirectPaths = append(redirectPaths, path)
|
||||
}
|
||||
return redirectPaths, nil
|
||||
}
|
||||
|
||||
func createOrReplaceRedirect(from, to string) error {
|
||||
if from == "" || to == "" {
|
||||
return errors.New("empty path")
|
||||
}
|
||||
if from == to {
|
||||
// Don't need a redirect
|
||||
return nil
|
||||
}
|
||||
from = strings.TrimSuffix(from, "/")
|
||||
_, err := appDbExec("insert or replace into redirects (fromPath, toPath) values (?, ?)", from, to)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return reloadRouter()
|
||||
}
|
Loading…
Reference in New Issue