Compare commits

...

8 commits

4 changed files with 31 additions and 13 deletions

View file

@ -0,0 +1,7 @@
on: [push]
jobs:
test:
runs-on: docker
steps:
- uses: actions/checkout@v3
- run: go build

View file

@ -6,4 +6,6 @@
Environmental variables:
- `SHORTEN_HOST` - hostname
- `SHORTEN_BIND` - bind address (default: `127.0.0.1:4488`)
- `SHORTEN_MAIL` - optional email for support/abuse reports
- `POSTGRES_URI` - lib/pq connection string (see [here](https://pkg.go.dev/github.com/lib/pq#section-documentation))

View file

@ -10,6 +10,7 @@
height: calc(100vh - 32px);
justify-content: center;
align-items: center;
font-family: sans-serif;
}
form {
display: flex;
@ -31,10 +32,15 @@
font-size: 30px;
}
a {
font-family: sans-serif;
color: #dddddd;
text-decoration: none;
}
footer {
width: 100vw;
position: absolute;
bottom: 10px;
text-align: center;
}
</style>
</head>
<body>
@ -45,5 +51,8 @@
<input type="text" {{ with .error }}placeholder="{{ . }}"{{ end }} name="url" autocomplete="off" autocapitalize="off">
</form>
{{ end }}
{{ if .mail }}
<footer>support, takedown, abuse reports: {{ .mail }}</footer>
{{ end }}
</body>
</html>

24
main.go
View file

@ -12,6 +12,7 @@ import (
"time"
"database/sql"
"github.com/asaskevich/govalidator"
_ "github.com/lib/pq"
)
@ -70,7 +71,11 @@ func main() {
panic(err)
}
panic(http.ListenAndServe("127.0.0.1:4488", &Handler{db: db}))
bind := os.Getenv("SHORTEN_BIND")
if bind == "" {
bind = "127.0.0.1:4488"
}
panic(http.ListenAndServe(bind, &Handler{db: db}))
}
type Handler struct {
@ -91,8 +96,6 @@ func (h *Handler) ServeHTTP(wr http.ResponseWriter, req *http.Request) {
}
func (h *Handler) HomepageHandler(wr http.ResponseWriter, req *http.Request) {
log.Println("HomepageHandler")
url := req.URL.Query().Get("url")
if url != "" {
code, err := h.GetCode(url, req.RemoteAddr)
@ -104,12 +107,10 @@ func (h *Handler) HomepageHandler(wr http.ResponseWriter, req *http.Request) {
wr.Write([]byte("https://" + os.Getenv("SHORTEN_HOST") + "/" + code))
}
Render(wr, nil)
Render(wr, map[string]string{})
}
func (h *Handler) CreateHandler(wr http.ResponseWriter, req *http.Request) {
log.Println("CreateHandler")
ip := req.RemoteAddr
if strings.HasPrefix(ip, "127.0.0.1") {
proxyIp := strings.Split(req.Header.Get("X-Forwarded-For"), ",")[0]
@ -119,7 +120,7 @@ func (h *Handler) CreateHandler(wr http.ResponseWriter, req *http.Request) {
}
req.ParseForm()
code, err := h.GetCode(req.Form.Get("url"), req.RemoteAddr)
code, err := h.GetCode(req.Form.Get("url"), ip)
if err != nil {
Render(wr, map[string]string{"error": err.Error()})
} else {
@ -128,8 +129,6 @@ func (h *Handler) CreateHandler(wr http.ResponseWriter, req *http.Request) {
}
func (h *Handler) RedirectHandler(wr http.ResponseWriter, req *http.Request) {
log.Println("RedirectHandler")
code := req.URL.Path[1:]
var url string
var hits uint64
@ -138,12 +137,12 @@ func (h *Handler) RedirectHandler(wr http.ResponseWriter, req *http.Request) {
log.Println("hits query error:", err)
}
wr.Header().Set("Location", "/")
wr.WriteHeader(http.StatusMovedPermanently)
wr.WriteHeader(http.StatusFound)
return
}
go func() {
_, _ = h.db.Exec(`UPDATE urls SET hits = $1 WHERE code = $2`, hits + 1, code)
_, _ = h.db.Exec(`UPDATE urls SET hits = $1 WHERE code = $2`, hits+1, code)
}()
wr.Header().Set("Location", url)
@ -164,7 +163,6 @@ func (h *Handler) CodeExists(code string) bool {
}
func (h *Handler) GetCode(url string, ip string) (string, error) {
log.Printf("url: %#v\n", url)
if !strings.HasPrefix(url, "http") || !govalidator.IsURL(url) {
return "", fmt.Errorf("invalid URL")
}
@ -175,6 +173,7 @@ func (h *Handler) GetCode(url string, ip string) (string, error) {
return code, nil
}
if err != sql.ErrNoRows {
log.Println("sql error:", err)
return "", fmt.Errorf("query: %w", err)
}
@ -196,6 +195,7 @@ func (h *Handler) GetCode(url string, ip string) (string, error) {
func Render(wr http.ResponseWriter, data map[string]string) {
wr.Header().Set("Content-Type", "text/html")
data["host"] = os.Getenv("SHORTEN_HOST")
data["mail"] = os.Getenv("SHORTEN_MAIL")
err := tmpl.Execute(wr, data)
if err != nil {
log.Println("error writing template:", err)