-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.go
143 lines (110 loc) · 3.5 KB
/
main.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
package main
import (
"embed"
"encoding/json"
"fmt"
"html/template"
"log"
"net/http"
"os"
"strings"
"time"
"golang.org/x/net/publicsuffix"
)
var (
//go:embed template/*
embededTemplateFileSystem embed.FS
//go:embed static/*
embededStaticFileSystem embed.FS
)
func redirectHttpHandler(url string) func(httpResponseWriter http.ResponseWriter, httpRequest *http.Request) {
return func(httpResponseWriter http.ResponseWriter, httpRequest *http.Request) {
http.Redirect(httpResponseWriter, httpRequest, url, 302)
}
}
func indexHttpHandler(httpResponseWriter http.ResponseWriter, httpRequest *http.Request) {
if httpRequest.URL.Path != "/" {
http.NotFound(httpResponseWriter, httpRequest)
return
}
template := template.Must(template.ParseFS(embededTemplateFileSystem, "template/index.html"))
type TemplateData struct {
DateTime string
Year int
}
templateData := TemplateData{
DateTime: time.Now().Format("2006-01-02 15:04:05"),
Year: time.Now().Year(),
}
template.Execute(httpResponseWriter, templateData)
}
func publicSuffixHttpHandler(httpResponseWriter http.ResponseWriter, httpRequest *http.Request) {
if httpRequest.URL.Path != "/publicsuffix" {
http.NotFound(httpResponseWriter, httpRequest)
return
}
type PublicSuffixHttpResponse struct {
Domain string `json:"domain"`
PublicSuffix string `json:"publicSuffix"`
IsManagedBy string `json:"isManagedBy"`
}
publicSuffixHttpResponse := func(domain string) PublicSuffixHttpResponse {
publicSuffix, isIcannManaged := publicsuffix.PublicSuffix(domain)
isManagedBy := ""
// See: https://pkg.go.dev/golang.org/x/net/publicsuffix#example-PublicSuffix-Manager
if isIcannManaged {
isManagedBy = "ICANN"
} else if strings.IndexByte(publicSuffix, '.') >= 0 {
isManagedBy = "PRIVATE_ENTITY"
} else {
isManagedBy = "NONE"
}
return PublicSuffixHttpResponse{
Domain: domain,
PublicSuffix: publicSuffix,
IsManagedBy: isManagedBy,
}
}
domain := httpRequest.URL.Query().Get("domain")
httpResponseWriter.Header().Add("Content-Type", "application/json; charset=utf-8")
if domain == "" {
httpResponseWriter.WriteHeader(http.StatusBadRequest)
json.NewEncoder(httpResponseWriter).Encode(struct {
ErrorCode int `json:"errorCode"`
ErrorType string `json:"errorType"`
ErrorMessage string `json:"errorMessage"`
}{
ErrorCode: http.StatusBadRequest,
ErrorType: http.StatusText(http.StatusBadRequest),
ErrorMessage: "Malformed URL query parameter `domain`",
})
return
}
json.NewEncoder(httpResponseWriter).Encode(publicSuffixHttpResponse(domain))
}
func faviconHttpHandler(httpResponseWriter http.ResponseWriter, httpRequest *http.Request) {
favicon, _ := embededStaticFileSystem.ReadFile("static/favicon.ico")
httpResponseWriter.Write(favicon)
}
// See: https://pkg.go.dev/os#example-LookupEnv
func getEnv(key string, fallback string) string {
value, exists := os.LookupEnv(key)
if exists {
return value
}
return fallback
}
func main() {
// Static
http.Handle("/static/", http.FileServer(http.FS(embededStaticFileSystem)))
http.HandleFunc("/favicon.ico", faviconHttpHandler)
// Dynamic
http.HandleFunc("/publicsuffix", publicSuffixHttpHandler)
// Redirects
http.HandleFunc("/github", redirectHttpHandler("https://github.com/stefankuehnel/publicsuffix.stefan-dev.de"))
// Templates
http.HandleFunc("/", indexHttpHandler)
port := getEnv("PORT", "80")
log.Printf("listening on http://localhost:%s", port)
http.ListenAndServe(fmt.Sprintf(":%s", port), nil)
}