krz/skunky-art

Alternative privacy frontend for DeviantArt.

clone: git clone https://gitbay.org/krz/skunky-art.git

v1.3.2: app/router.go · raw

  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}