aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeuerfuchs <git@feuerfuchs.dev>2019-11-16 10:42:19 +0100
committerFeuerfuchs <git@feuerfuchs.dev>2019-11-16 10:42:19 +0100
commit18349a7a00d778738381ef3b1c1d2e30be879327 (patch)
treef6e6d3376cb767fb77a12db28dbb1901add402de
parentGemini: Add support for charset MIME parameter (diff)
downloadgopherproxy-18349a7a00d778738381ef3b1c1d2e30be879327.tar.gz
gopherproxy-18349a7a00d778738381ef3b1c1d2e30be879327.tar.bz2
gopherproxy-18349a7a00d778738381ef3b1c1d2e30be879327.zip
Display proper HTML title
-rw-r--r--gopherproxy.go71
-rw-r--r--template.go2
2 files changed, 45 insertions, 28 deletions
diff --git a/gopherproxy.go b/gopherproxy.go
index 65c8f89..751cebf 100644
--- a/gopherproxy.go
+++ b/gopherproxy.go
@@ -50,25 +50,25 @@ type AssetList struct {
50 PropFontW2 string 50 PropFontW2 string
51} 51}
52 52
53func resolveURI(uri string, baseUrl *url.URL) (resolvedUri string) { 53func resolveURI(uri string, baseURL *url.URL) (resolvedURI string) {
54 if strings.HasPrefix(uri, "//") { 54 if strings.HasPrefix(uri, "//") {
55 resolvedUri = "/gemini/" + strings.TrimPrefix(uri, "//") 55 resolvedURI = "/gemini/" + strings.TrimPrefix(uri, "//")
56 } else if strings.HasPrefix(uri, "gemini://") { 56 } else if strings.HasPrefix(uri, "gemini://") {
57 resolvedUri = "/gemini/" + strings.TrimPrefix(uri, "gemini://") 57 resolvedURI = "/gemini/" + strings.TrimPrefix(uri, "gemini://")
58 } else if strings.HasPrefix(uri, "gopher://") { 58 } else if strings.HasPrefix(uri, "gopher://") {
59 resolvedUri = "/gopher/" + strings.TrimPrefix(uri, "gopher://") 59 resolvedURI = "/gopher/" + strings.TrimPrefix(uri, "gopher://")
60 } else { 60 } else {
61 url, err := url.Parse(uri) 61 url, err := url.Parse(uri)
62 if err != nil { 62 if err != nil {
63 return "" 63 return ""
64 } 64 }
65 adjustedUrl := baseUrl.ResolveReference(url) 65 adjustedURI := baseURL.ResolveReference(url)
66 if adjustedUrl.Scheme == "gemini" { 66 if adjustedURI.Scheme == "gemini" {
67 resolvedUri = "/gemini/" + adjustedUrl.Host + adjustedUrl.Path 67 resolvedURI = "/gemini/" + adjustedURI.Host + adjustedURI.Path
68 } else if adjustedUrl.Scheme == "gopher" { 68 } else if adjustedURI.Scheme == "gopher" {
69 resolvedUri = "/gopher/" + adjustedUrl.Host + adjustedUrl.Path 69 resolvedURI = "/gopher/" + adjustedURI.Host + adjustedURI.Path
70 } else { 70 } else {
71 resolvedUri = adjustedUrl.String() 71 resolvedURI = adjustedURI.String()
72 } 72 }
73 } 73 }
74 74
@@ -123,7 +123,11 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL
123 } 123 }
124 124
125 if title == "" { 125 if title == "" {
126 title = hostport 126 if uri != "" {
127 title = fmt.Sprintf("%s/%s", hostport, uri)
128 } else {
129 title = hostport
130 }
127 } 131 }
128 132
129 return tpl.Execute(w, struct { 133 return tpl.Execute(w, struct {
@@ -138,7 +142,7 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL
138} 142}
139 143
140func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items []Item) { 144func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items []Item) {
141 baseUrl, err := url.Parse(fmt.Sprintf( 145 baseURL, err := url.Parse(fmt.Sprintf(
142 "gemini://%s/%s", 146 "gemini://%s/%s",
143 hostport, 147 hostport,
144 uri, 148 uri,
@@ -160,7 +164,7 @@ func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items
160 linkMatch := GeminiLinkPattern.FindStringSubmatch(line) 164 linkMatch := GeminiLinkPattern.FindStringSubmatch(line)
161 if len(linkMatch) != 0 && linkMatch[0] != "" { 165 if len(linkMatch) != 0 && linkMatch[0] != "" {
162 item.Type = ITEM_TYPE_GEMINI_LINK 166 item.Type = ITEM_TYPE_GEMINI_LINK
163 item.Link = template.URL(resolveURI(linkMatch[1], baseUrl)) 167 item.Link = template.URL(resolveURI(linkMatch[1], baseURL))
164 item.Text = linkMatch[2] 168 item.Text = linkMatch[2]
165 if item.Text == "" { 169 if item.Text == "" {
166 item.Text = linkMatch[1] 170 item.Text = linkMatch[1]
@@ -201,6 +205,8 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
201 return 205 return
202 } 206 }
203 207
208 title := hostport
209
204 var qs string 210 var qs string
205 211
206 if req.URL.RawQuery != "" { 212 if req.URL.RawQuery != "" {
@@ -217,10 +223,14 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
217 Lines []Item 223 Lines []Item
218 Error bool 224 Error bool
219 Protocol string 225 Protocol string
220 }{"", hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}) 226 }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"})
221 return 227 return
222 } 228 }
223 229
230 if uri != "" {
231 title = fmt.Sprintf("%s/%s", hostport, uri)
232 }
233
224 res, err := gopher.Get( 234 res, err := gopher.Get(
225 fmt.Sprintf( 235 fmt.Sprintf(
226 "gopher://%s/%s%s", 236 "gopher://%s/%s%s",
@@ -239,15 +249,14 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
239 Lines []Item 249 Lines []Item
240 Error bool 250 Error bool
241 Protocol string 251 Protocol string
242 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}) 252 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"})
243 return 253 return
244 } 254 }
245 255
246 if res.Body != nil { 256 if res.Body != nil {
247 if len(parts) < 2 { 257 if len(parts) < 2 {
248 io.Copy(w, res.Body) 258 io.Copy(w, res.Body)
249 } else if strings.HasPrefix(parts[1], "0") && !strings.HasSuffix(uri, ".xml") && !strings.HasSuffix(uri, ".asc") { //strings.HasSuffix(uri, ".txt") || strings.HasSuffix(uri, ".md") { 259 } else if strings.HasPrefix(parts[1], "0") && !strings.HasSuffix(uri, ".xml") && !strings.HasSuffix(uri, ".asc") {
250 // handle .txt files
251 buf := new(bytes.Buffer) 260 buf := new(bytes.Buffer)
252 buf.ReadFrom(res.Body) 261 buf.ReadFrom(res.Body)
253 tpl.Execute(w, struct { 262 tpl.Execute(w, struct {
@@ -258,7 +267,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
258 Lines []Item 267 Lines []Item
259 Error bool 268 Error bool
260 Protocol string 269 Protocol string
261 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gopher"}) 270 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gopher"})
262 } else if strings.HasPrefix(parts[1], "T") { 271 } else if strings.HasPrefix(parts[1], "T") {
263 _, _, err = vips.NewTransform(). 272 _, _, err = vips.NewTransform().
264 Load(res.Body). 273 Load(res.Body).
@@ -280,8 +289,7 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
280 Lines []Item 289 Lines []Item
281 Error bool 290 Error bool
282 Protocol string 291 Protocol string
283 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}) 292 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"})
284 return
285 } 293 }
286 } 294 }
287 } 295 }
@@ -304,6 +312,8 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
304 return 312 return
305 } 313 }
306 314
315 title := hostport
316
307 var qs string 317 var qs string
308 318
309 if req.URL.RawQuery != "" { 319 if req.URL.RawQuery != "" {
@@ -320,10 +330,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
320 Lines []Item 330 Lines []Item
321 Error bool 331 Error bool
322 Protocol string 332 Protocol string
323 }{"", hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}) 333 }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"})
324 return 334 return
325 } 335 }
326 336
337 if uri != "" {
338 title = fmt.Sprintf("%s/%s", hostport, uri)
339 }
340
327 res, err := GeminiGet( 341 res, err := GeminiGet(
328 fmt.Sprintf( 342 fmt.Sprintf(
329 "gemini://%s/%s%s", 343 "gemini://%s/%s%s",
@@ -342,12 +356,12 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
342 Lines []Item 356 Lines []Item
343 Error bool 357 Error bool
344 Protocol string 358 Protocol string
345 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}) 359 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"})
346 return 360 return
347 } 361 }
348 362
349 if int(res.Header.Status/10) == 3 { 363 if int(res.Header.Status/10) == 3 {
350 baseUrl, err := url.Parse(fmt.Sprintf( 364 baseURL, err := url.Parse(fmt.Sprintf(
351 "gemini://%s/%s", 365 "gemini://%s/%s",
352 hostport, 366 hostport,
353 uri, 367 uri,
@@ -361,11 +375,11 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
361 Lines []Item 375 Lines []Item
362 Error bool 376 Error bool
363 Protocol string 377 Protocol string
364 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}) 378 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"})
365 return 379 return
366 } 380 }
367 381
368 http.Redirect(w, req, resolveURI(res.Header.Meta, baseUrl), http.StatusFound) 382 http.Redirect(w, req, resolveURI(res.Header.Meta, baseURL), http.StatusFound)
369 return 383 return
370 } 384 }
371 385
@@ -378,7 +392,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
378 Lines []Item 392 Lines []Item
379 Error bool 393 Error bool
380 Protocol string 394 Protocol string
381 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), nil, true, "gemini"}) 395 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), nil, true, "gemini"})
382 return 396 return
383 } 397 }
384 398
@@ -417,7 +431,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass
417 Lines []Item 431 Lines []Item
418 Error bool 432 Error bool
419 Protocol string 433 Protocol string
420 }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"}) 434 }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"})
421 } else { 435 } else {
422 io.Copy(w, res.Body) 436 io.Copy(w, res.Body)
423 } 437 }
@@ -594,6 +608,9 @@ func ListenAndServe(bind, robotsfile string, robotsdebug bool, vipsconcurrency i
594 "hasPrefix": func(s string, prefix string) bool { 608 "hasPrefix": func(s string, prefix string) bool {
595 return strings.HasPrefix(s, prefix) 609 return strings.HasPrefix(s, prefix)
596 }, 610 },
611 "title": func(s string) string {
612 return strings.Title(s)
613 },
597 } 614 }
598 615
599 tpl, err = template.New("gophermenu").Funcs(funcMap).Parse(tpltext) 616 tpl, err = template.New("gophermenu").Funcs(funcMap).Parse(tpltext)
diff --git a/template.go b/template.go
index 6a9c6fe..3bd8950 100644
--- a/template.go
+++ b/template.go
@@ -5,7 +5,7 @@ var tpltext = `<!doctype html>
5 <head> 5 <head>
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 }} - {{ .Protocol | title }} proxy</title>
9 <link rel="stylesheet" href="{{ .Assets.Style }}" /> 9 <link rel="stylesheet" href="{{ .Assets.Style }}" />
10 <style> 10 <style>
11 @font-face { 11 @font-face {