krz/skunky-art
Alternative privacy frontend for DeviantArt.
clone: git clone https://gitbay.org/krz/skunky-art.git
1package app
2
3import (
4 "io"
5 "net/http"
6 url "net/url"
7 "skunkyart/static"
8 "strconv"
9 "strings"
10)
11
12var Host, Path string
13
14func Router() {
15 parsepath := func(path string) map[int]string {
16 if l := len(CFG.URI); len(path) > l {
17 path = path[l-1:]
18 } else {
19 path = "/"
20 }
21
22 parsedpath := make(map[int]string)
23 for x := 0; true; x++ {
24 slash := strings.Index(path, "/") + 1
25 content := path[:slash]
26 path = path[slash:]
27 if slash == 0 {
28 parsedpath[x] = path
29 break
30 }
31 parsedpath[x] = content[:slash-1]
32 }
33 return parsedpath
34 }
35
36 next := func(path map[int]string, from int) (out string) {
37 for x, l := from, len(path)-1; x <= l; x++ {
38 out += path[x]
39 if x != l {
40 out += "/"
41 }
42 }
43 return
44 }
45
46 open := func(name string) []byte {
47 file, err := static.Templates.Open(name)
48 try(err)
49 fileReaded, err := io.ReadAll(file)
50 try(err)
51
52 return fileReaded
53 }
54
55 // функция, что управляет всем
56 handle := func(w http.ResponseWriter, r *http.Request) {
57 Path = r.URL.Path
58 path := parsepath(Path)
59 Host = "http://" + r.Host
60
61 if h := r.Header["X-Forwarded-Proto"]; len(h) != 0 && h[0] == "https" {
62 Host = "https://" + r.Host
63 }
64
65 var skunky = skunkyart{Version: Release.Version}
66
67 skunky.Args = r.URL.Query()
68 arg := skunky.Args.Get
69 p, _ := strconv.Atoi(arg("p"))
70
71 skunky.Endpoint = path[1]
72 skunky.API.main = &skunky
73 skunky.Writer = w
74 skunky.BasePath = CFG.URI
75 skunky.QueryRaw = arg("q")
76 skunky.Query = url.QueryEscape(skunky.QueryRaw)
77 skunky.Page = p
78
79 if t := arg("type"); len(t) > 0 {
80 skunky.Type = rune(t[0])
81 }
82
83 if arg("atom") == "true" {
84 skunky.Atom = true
85 }
86
87 if CFG.Proxy {
88 w.Header().Add("Content-Security-Policy", "default-src 'self'; script-src 'none'; style-src 'self' 'unsafe-inline'")
89 } else {
90 w.Header().Add("Content-Security-Policy", "default-src 'self'; img-src 'self' *.wixmp.com; script-src 'none'; style-src 'self' 'unsafe-inline'")
91 }
92
93 w.Header().Add("X-Frame-Options", "DENY")
94
95 switch skunky.Endpoint {
96 // main
97 case "":
98 skunky.ExecuteTemplate("index.htm", "html", &CFG.URI)
99 case "about":
100 skunky.Templates.About = About
101 skunky.ExecuteTemplate("about.htm", "html", &skunky)
102 case "post":
103 skunky.Deviation(path[2], path[3])
104 case "search":
105 skunky.Search()
106 case "dd":
107 skunky.DD()
108 case "group_user":
109 skunky.GRUser()
110
111 // media
112 case "media":
113 switch path[2] {
114 case "file":
115 if a := arg("filename"); a != "" {
116 skunky.SetFilename(a)
117 }
118 skunky.DownloadAndSendMedia(path[3], next(path, 4))
119 case "emojitar":
120 skunky.Emojitar(path[3])
121 }
122 case "stylesheet":
123 w.Header().Add("content-type", "text/css")
124 w.Write(open("css/skunky.css"))
125 case "favicon.ico":
126 w.Write(open("images/logo.png"))
127
128 // API
129 case "api":
130 w.Header().Add("Content-Type", "application/json")
131 switch path[2] {
132 case "instance":
133 skunky.API.Info()
134 case "random":
135 skunky.API.Random()
136 default:
137 skunky.API.Error("Not Found", 404)
138 }
139
140 // 404
141 default:
142 skunky.ReturnHTTPError(404)
143 }
144 }
145
146 http.HandleFunc("/", handle)
147 println("SkunkyArt is listening on", CFG.Listen)
148
149 tryWithExitStatus(http.ListenAndServe(CFG.Listen, nil), 1)
150}