diff options
-rw-r--r-- | Dockerfile | 8 | ||||
-rw-r--r-- | Makefile | 1 | ||||
-rw-r--r-- | README.md | 6 | ||||
-rw-r--r-- | assets/IBMPlexMono-Regular.woff | bin | 0 -> 50664 bytes | |||
-rw-r--r-- | assets/IBMPlexMono-Regular.woff2 | bin | 0 -> 35536 bytes | |||
-rw-r--r-- | assets/style.css | 1 | ||||
-rw-r--r-- | css/main.scss | 58 | ||||
-rw-r--r-- | go.mod | 2 | ||||
-rw-r--r-- | gopherproxy.go | 18 | ||||
-rw-r--r-- | template.go | 13 |
10 files changed, 92 insertions, 15 deletions
@@ -8,10 +8,10 @@ RUN \ | |||
8 | apk add --update git && \ | 8 | apk add --update git && \ |
9 | rm -rf /var/cache/apk/* | 9 | rm -rf /var/cache/apk/* |
10 | 10 | ||
11 | RUN mkdir -p /go/src/github.com/prologic/gopherproxy | 11 | RUN mkdir -p /go/src/git.feuerfuchs.dev/Feuerfuchs/gopherproxy |
12 | WORKDIR /go/src/github.com/prologic/gopherproxy | 12 | WORKDIR /go/src/git.feuerfuchs.dev/Feuerfuchs/gopherproxy |
13 | 13 | ||
14 | COPY . /go/src/github.com/prologic/gopherproxy | 14 | COPY . /go/src/git.feuerfuchs.dev/Feuerfuchs/gopherproxy |
15 | 15 | ||
16 | RUN go get -v -d | 16 | RUN go get -v -d |
17 | RUN go install -v github.com/prologic/gopherproxy/... | 17 | RUN go install -v git.feuerfuchs.dev/Feuerfuchs/gopherproxy/... |
@@ -6,6 +6,7 @@ dev: build | |||
6 | ./gopherproxy -bind 127.0.0.1:8000 | 6 | ./gopherproxy -bind 127.0.0.1:8000 |
7 | 7 | ||
8 | build: clean | 8 | build: clean |
9 | sassc -t compressed css/main.scss assets/style.css | ||
9 | go build -o ./gopherproxy ./cmd/gopherproxy/main.go | 10 | go build -o ./gopherproxy ./cmd/gopherproxy/main.go |
10 | 11 | ||
11 | profile: | 12 | profile: |
@@ -3,8 +3,8 @@ | |||
3 | [![Build Status](https://cloud.drone.io/api/badges/prologic/gopherproxy/status.svg)](https://cloud.drone.io/prologic/gopherproxy) | 3 | [![Build Status](https://cloud.drone.io/api/badges/prologic/gopherproxy/status.svg)](https://cloud.drone.io/prologic/gopherproxy) |
4 | [![CodeCov](https://codecov.io/gh/prologic/gopherproxy/branch/master/graph/badge.svg)](https://codecov.io/gh/prologic/gopherproxy) | 4 | [![CodeCov](https://codecov.io/gh/prologic/gopherproxy/branch/master/graph/badge.svg)](https://codecov.io/gh/prologic/gopherproxy) |
5 | [![Go Report Card](https://goreportcard.com/badge/prologic/gopherproxy)](https://goreportcard.com/report/prologic/gopherproxy) | 5 | [![Go Report Card](https://goreportcard.com/badge/prologic/gopherproxy)](https://goreportcard.com/report/prologic/gopherproxy) |
6 | [![GoDoc](https://godoc.org/github.com/prologic/gopherproxy?status.svg)](https://godoc.org/github.com/prologic/gopherproxy) | 6 | [![GoDoc](https://godoc.org/git.feuerfuchs.dev/Feuerfuchs/gopherproxy?status.svg)](https://godoc.org/git.feuerfuchs.dev/Feuerfuchs/gopherproxy) |
7 | [![Sourcegraph](https://sourcegraph.com/github.com/prologic/gopherproxy/-/badge.svg)](https://sourcegraph.com/github.com/prologic/gopherproxy?badge) | 7 | [![Sourcegraph](https://sourcegraph.com/git.feuerfuchs.dev/Feuerfuchs/gopherproxy/-/badge.svg)](https://sourcegraph.com/git.feuerfuchs.dev/Feuerfuchs/gopherproxy?badge) |
8 | 8 | ||
9 | gopherproxy is a Gopher (RFC 1436) Web Proxy that acts as a gateway into Gopherspace | 9 | gopherproxy is a Gopher (RFC 1436) Web Proxy that acts as a gateway into Gopherspace |
10 | by proxying standard Web HTTP requests to Gopher requests of the target server. | 10 | by proxying standard Web HTTP requests to Gopher requests of the target server. |
@@ -16,7 +16,7 @@ Demo: https://gopher.mills.io/ | |||
16 | 16 | ||
17 | ## Installation | 17 | ## Installation |
18 | 18 | ||
19 | $ go install github.com/prologic/gopherproxy/... | 19 | $ go install git.feuerfuchs.dev/Feuerfuchs/gopherproxy/... |
20 | 20 | ||
21 | ### Docker | 21 | ### Docker |
22 | 22 | ||
diff --git a/assets/IBMPlexMono-Regular.woff b/assets/IBMPlexMono-Regular.woff new file mode 100644 index 0000000..7d63d89 --- /dev/null +++ b/assets/IBMPlexMono-Regular.woff | |||
Binary files differ | |||
diff --git a/assets/IBMPlexMono-Regular.woff2 b/assets/IBMPlexMono-Regular.woff2 new file mode 100644 index 0000000..d0d7ded --- /dev/null +++ b/assets/IBMPlexMono-Regular.woff2 | |||
Binary files differ | |||
diff --git a/assets/style.css b/assets/style.css new file mode 100644 index 0000000..70b1998 --- /dev/null +++ b/assets/style.css | |||
@@ -0,0 +1 @@ | |||
@font-face{font-family:'IBM Plex Mono';font-style:normal;font-weight:normal;src:url("/assets/IBMPlexMono-Regular.woff2") format("woff2"),url("/assets/IBMPlexMono-Regular.woff") format("woff")}body{background-color:#14171a;color:#cad1d8}.wrap{text-align:center}.content{display:inline-block;min-width:50em;margin:0;padding:2em 1em;text-align:left;font-family:'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace;font-size:1em;line-height:1.5}::selection{color:#000;background-color:#cad1d8}:link{color:#fff}:visited{color:#cad1d8}:link:hover,:visited:hover{color:#fff}.link-type{color:#929ba3} | |||
diff --git a/css/main.scss b/css/main.scss new file mode 100644 index 0000000..dfda503 --- /dev/null +++ b/css/main.scss | |||
@@ -0,0 +1,58 @@ | |||
1 | $background: hsl(210, 14%, 9%); | ||
2 | $text: mix(hsl(210, 60%, 95%), $background, 85%); | ||
3 | $text-minus: mix(hsl(210, 100%, 95%), $background, 60%); | ||
4 | $text-faint: mix(hsl(210, 100%, 95%), $background, 40%); | ||
5 | $text-plus: #fff; | ||
6 | $sel-background: $text; | ||
7 | $sel-text: #000; | ||
8 | |||
9 | @font-face { | ||
10 | font-family: 'IBM Plex Mono'; | ||
11 | font-style: normal; | ||
12 | font-weight: normal; | ||
13 | src: url('/assets/IBMPlexMono-Regular.woff2') format('woff2'), | ||
14 | url('/assets/IBMPlexMono-Regular.woff') format('woff'); | ||
15 | } | ||
16 | |||
17 | body { | ||
18 | background-color: $background; | ||
19 | color: $text; | ||
20 | } | ||
21 | |||
22 | .wrap { | ||
23 | text-align: center; | ||
24 | } | ||
25 | |||
26 | .content { | ||
27 | display: inline-block; | ||
28 | min-width: 50em; | ||
29 | margin: 0; | ||
30 | padding: 2em 1em; | ||
31 | text-align: left; | ||
32 | font-family: 'IBM Plex Mono', 'Fira Code', 'Fira Mono', 'Roboto Mono', 'Droid Sans Mono', Monaco, Consolas, Courier, monospace; | ||
33 | font-size: 1em; | ||
34 | line-height: 1.5; | ||
35 | } | ||
36 | |||
37 | ::selection { | ||
38 | color: $sel-text; | ||
39 | background-color: $sel-background; | ||
40 | } | ||
41 | |||
42 | :link { | ||
43 | color: $text-plus; | ||
44 | } | ||
45 | |||
46 | :visited { | ||
47 | color: $text; | ||
48 | } | ||
49 | |||
50 | :link, :visited { | ||
51 | &:hover { | ||
52 | color: $text-plus; | ||
53 | } | ||
54 | } | ||
55 | |||
56 | .link-type { | ||
57 | color: $text-minus; | ||
58 | } | ||
@@ -1,4 +1,4 @@ | |||
1 | module github.com/prologic/gopherproxy | 1 | module git.feuerfuchs.dev/Feuerfuchs/gopherproxy |
2 | 2 | ||
3 | require ( | 3 | require ( |
4 | github.com/prologic/go-gopher v0.0.0-20181230133552-0c68ed5f58b0 | 4 | github.com/prologic/go-gopher v0.0.0-20181230133552-0c68ed5f58b0 |
diff --git a/gopherproxy.go b/gopherproxy.go index 42f67cf..6f1e8ec 100644 --- a/gopherproxy.go +++ b/gopherproxy.go | |||
@@ -1,6 +1,7 @@ | |||
1 | package gopherproxy | 1 | package gopherproxy |
2 | 2 | ||
3 | import ( | 3 | import ( |
4 | "bytes" | ||
4 | "fmt" | 5 | "fmt" |
5 | "html/template" | 6 | "html/template" |
6 | "io" | 7 | "io" |
@@ -73,7 +74,8 @@ func renderDirectory(w http.ResponseWriter, tpl *template.Template, hostport str | |||
73 | return tpl.Execute(w, struct { | 74 | return tpl.Execute(w, struct { |
74 | Title string | 75 | Title string |
75 | Lines []Item | 76 | Lines []Item |
76 | }{title, out}) | 77 | RawText string |
78 | }{title, out, ""}) | ||
77 | } | 79 | } |
78 | 80 | ||
79 | // GopherHandler returns a Handler that proxies requests | 81 | // GopherHandler returns a Handler that proxies requests |
@@ -125,7 +127,18 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, uri | |||
125 | } | 127 | } |
126 | 128 | ||
127 | if res.Body != nil { | 129 | if res.Body != nil { |
128 | io.Copy(w, res.Body) | 130 | if strings.HasSuffix(uri, ".txt") { |
131 | // handle .txt files | ||
132 | buf := new(bytes.Buffer) | ||
133 | buf.ReadFrom(res.Body) | ||
134 | tpl.Execute(w, struct { | ||
135 | Title string | ||
136 | RawText string | ||
137 | Lines []Item | ||
138 | }{uri, buf.String(), nil}) | ||
139 | } else { | ||
140 | io.Copy(w, res.Body) | ||
141 | } | ||
129 | } else { | 142 | } else { |
130 | if err := renderDirectory(w, tpl, hostport, res.Dir); err != nil { | 143 | if err := renderDirectory(w, tpl, hostport, res.Dir); err != nil { |
131 | io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) | 144 | io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) |
@@ -186,6 +199,7 @@ func ListenAndServe(bind, robotsfile, uri string) error { | |||
186 | 199 | ||
187 | http.HandleFunc("/", GopherHandler(tpl, robotsdata, uri)) | 200 | http.HandleFunc("/", GopherHandler(tpl, robotsdata, uri)) |
188 | http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) | 201 | http.HandleFunc("/robots.txt", RobotsTxtHandler(robotstxtdata)) |
202 | http.Handle("/assets/", http.StripPrefix("/assets/", http.FileServer(http.Dir("assets/")))) | ||
189 | 203 | ||
190 | return http.ListenAndServe(bind, nil) | 204 | return http.ListenAndServe(bind, nil) |
191 | } | 205 | } |
diff --git a/template.go b/template.go index 40b9c31..b42f811 100644 --- a/template.go +++ b/template.go | |||
@@ -6,13 +6,16 @@ var tpltext = `<!doctype html> | |||
6 | <meta charset="utf-8"> | 6 | <meta charset="utf-8"> |
7 | <meta name="viewport" content="width=device-width, initial-scale=1" /> | 7 | <meta name="viewport" content="width=device-width, initial-scale=1" /> |
8 | <title>{{.Title}}</title> | 8 | <title>{{.Title}}</title> |
9 | <link rel="preload" href="/assets/style.css" as="style" /> | ||
10 | <link rel="preload" href="/assets/IBMPlexMono-Regular.woff2" as="font" type="font/woff2" crossorigin="anonymous" /> | ||
11 | <link rel="stylesheet" href="/assets/style.css" /> | ||
9 | </head> | 12 | </head> |
10 | <body> | 13 | <body> |
11 | <section> | 14 | <main class="wrap"> |
12 | <pre> | 15 | <pre class="content"> |
13 | {{range .Lines}} {{if .Link}}({{.Type}}) <a class="{{ .Type }}" href="{{.Link}}">{{.Text}}</a>{{else}} {{.Text}}{{end}} | 16 | {{if .Lines}}{{range .Lines}} {{if .Link}}<span class="link-type">({{.Type}})</span> <a class="link link-{{ .Type }}" href="{{.Link}}">{{.Text}}</a>{{else}} {{.Text}}{{end}} |
14 | {{end}}</pre> | 17 | {{end}}{{else}}{{.RawText}}{{end}}</pre> |
15 | </section> | 18 | </main> |
16 | <script type="text/javascript"> | 19 | <script type="text/javascript"> |
17 | var qry=document.getElementsByClassName('QRY') | 20 | var qry=document.getElementsByClassName('QRY') |
18 | var i=qry.length | 21 | var i=qry.length |