diff options
-rw-r--r-- | gopherproxy/gopherproxy.go | 203 |
1 files changed, 103 insertions, 100 deletions
diff --git a/gopherproxy/gopherproxy.go b/gopherproxy/gopherproxy.go index 6556845..4a7d972 100644 --- a/gopherproxy/gopherproxy.go +++ b/gopherproxy/gopherproxy.go | |||
@@ -49,6 +49,16 @@ type AssetList struct { | |||
49 | PropFontW2 string | 49 | PropFontW2 string |
50 | } | 50 | } |
51 | 51 | ||
52 | type TemplateVariables struct { | ||
53 | Title string | ||
54 | URI string | ||
55 | Assets AssetList | ||
56 | RawText string | ||
57 | Lines []Item | ||
58 | Error bool | ||
59 | Protocol string | ||
60 | } | ||
61 | |||
52 | func resolveURI(uri string, baseURL *url.URL) (resolvedURI string) { | 62 | func resolveURI(uri string, baseURL *url.URL) (resolvedURI string) { |
53 | if strings.HasPrefix(uri, "//") { | 63 | if strings.HasPrefix(uri, "//") { |
54 | resolvedURI = "/gemini/" + strings.TrimPrefix(uri, "//") | 64 | resolvedURI = "/gemini/" + strings.TrimPrefix(uri, "//") |
@@ -144,15 +154,13 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL | |||
144 | } | 154 | } |
145 | } | 155 | } |
146 | 156 | ||
147 | return tpl.Execute(w, struct { | 157 | return tpl.Execute(w, TemplateVariables{ |
148 | Title string | 158 | Title: title, |
149 | URI string | 159 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
150 | Assets AssetList | 160 | Assets: assetList, |
151 | Lines []Item | 161 | Lines: out, |
152 | RawText string | 162 | Protocol: "gopher", |
153 | Error bool | 163 | }) |
154 | Protocol string | ||
155 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, out, "", false, "gopher"}) | ||
156 | } | 164 | } |
157 | 165 | ||
158 | func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items []Item) { | 166 | func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items []Item) { |
@@ -193,15 +201,12 @@ func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items | |||
193 | 201 | ||
194 | func DefaultHandler(tpl *template.Template, startpagetext string, assetList AssetList) http.HandlerFunc { | 202 | func DefaultHandler(tpl *template.Template, startpagetext string, assetList AssetList) http.HandlerFunc { |
195 | return func(w http.ResponseWriter, req *http.Request) { | 203 | return func(w http.ResponseWriter, req *http.Request) { |
196 | if err := tpl.Execute(w, struct { | 204 | if err := tpl.Execute(w, TemplateVariables{ |
197 | Title string | 205 | Title: "Gopher/Gemini proxy", |
198 | URI string | 206 | Assets: assetList, |
199 | Assets AssetList | 207 | RawText: startpagetext, |
200 | RawText string | 208 | Protocol: "startpage", |
201 | Lines []Item | 209 | }); err != nil { |
202 | Error bool | ||
203 | Protocol string | ||
204 | }{"Gopher/Gemini proxy", "", assetList, startpagetext, nil, false, "startpage"}); err != nil { | ||
205 | log.Println("Template error: " + err.Error()) | 210 | log.Println("Template error: " + err.Error()) |
206 | } | 211 | } |
207 | } | 212 | } |
@@ -239,15 +244,14 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
239 | 244 | ||
240 | uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) | 245 | uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) |
241 | if err != nil { | 246 | if err != nil { |
242 | if e := tpl.Execute(w, struct { | 247 | if e := tpl.Execute(w, TemplateVariables{ |
243 | Title string | 248 | Title: title, |
244 | URI string | 249 | URI: hostport, |
245 | Assets AssetList | 250 | Assets: assetList, |
246 | RawText string | 251 | RawText: fmt.Sprintf("Error: %s", err), |
247 | Lines []Item | 252 | Error: true, |
248 | Error bool | 253 | Protocol: "gopher", |
249 | Protocol string | 254 | }); e != nil { |
250 | }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}); e != nil { | ||
251 | log.Println("Template error: " + e.Error()) | 255 | log.Println("Template error: " + e.Error()) |
252 | log.Println(err.Error()) | 256 | log.Println(err.Error()) |
253 | } | 257 | } |
@@ -268,15 +272,14 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
268 | ) | 272 | ) |
269 | 273 | ||
270 | if err != nil { | 274 | if err != nil { |
271 | if e := tpl.Execute(w, struct { | 275 | if e := tpl.Execute(w, TemplateVariables{ |
272 | Title string | 276 | Title: title, |
273 | URI string | 277 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
274 | Assets AssetList | 278 | Assets: assetList, |
275 | RawText string | 279 | RawText: fmt.Sprintf("Error: %s", err), |
276 | Lines []Item | 280 | Error: true, |
277 | Error bool | 281 | Protocol: "gopher", |
278 | Protocol string | 282 | }); e != nil { |
279 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}); e != nil { | ||
280 | log.Println("Template error: " + e.Error()) | 283 | log.Println("Template error: " + e.Error()) |
281 | } | 284 | } |
282 | return | 285 | return |
@@ -288,15 +291,14 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
288 | } else if strings.HasPrefix(parts[1], "0") && !strings.HasSuffix(uri, ".xml") && !strings.HasSuffix(uri, ".asc") { | 291 | } else if strings.HasPrefix(parts[1], "0") && !strings.HasSuffix(uri, ".xml") && !strings.HasSuffix(uri, ".asc") { |
289 | buf := new(bytes.Buffer) | 292 | buf := new(bytes.Buffer) |
290 | buf.ReadFrom(res.Body) | 293 | buf.ReadFrom(res.Body) |
291 | if err := tpl.Execute(w, struct { | 294 | |
292 | Title string | 295 | if err := tpl.Execute(w, TemplateVariables{ |
293 | URI string | 296 | Title: title, |
294 | Assets AssetList | 297 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
295 | RawText string | 298 | Assets: assetList, |
296 | Lines []Item | 299 | RawText: buf.String(), |
297 | Error bool | 300 | Protocol: "gopher", |
298 | Protocol string | 301 | }); err != nil { |
299 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gopher"}); err != nil { | ||
300 | log.Println("Template error: " + err.Error()) | 302 | log.Println("Template error: " + err.Error()) |
301 | } | 303 | } |
302 | } else if strings.HasPrefix(parts[1], "T") { | 304 | } else if strings.HasPrefix(parts[1], "T") { |
@@ -312,15 +314,14 @@ func GopherHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
312 | } | 314 | } |
313 | } else { | 315 | } else { |
314 | if err := renderGopherDirectory(w, tpl, assetList, uri, hostport, res.Dir); err != nil { | 316 | if err := renderGopherDirectory(w, tpl, assetList, uri, hostport, res.Dir); err != nil { |
315 | if e := tpl.Execute(w, struct { | 317 | if e := tpl.Execute(w, TemplateVariables{ |
316 | Title string | 318 | Title: title, |
317 | URI string | 319 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
318 | Assets AssetList | 320 | Assets: assetList, |
319 | RawText string | 321 | RawText: fmt.Sprintf("Error: %s", err), |
320 | Lines []Item | 322 | Error: true, |
321 | Error bool | 323 | Protocol: "gopher", |
322 | Protocol string | 324 | }); e != nil { |
323 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gopher"}); e != nil { | ||
324 | log.Println("Template error: " + e.Error()) | 325 | log.Println("Template error: " + e.Error()) |
325 | log.Println(e.Error()) | 326 | log.Println(e.Error()) |
326 | } | 327 | } |
@@ -356,15 +357,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
356 | 357 | ||
357 | uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) | 358 | uri, err := url.QueryUnescape(strings.Join(parts[1:], "/")) |
358 | if err != nil { | 359 | if err != nil { |
359 | if e := tpl.Execute(w, struct { | 360 | if e := tpl.Execute(w, TemplateVariables{ |
360 | Title string | 361 | Title: title, |
361 | URI string | 362 | URI: hostport, |
362 | Assets AssetList | 363 | Assets: assetList, |
363 | RawText string | 364 | RawText: fmt.Sprintf("Error: %s", err), |
364 | Lines []Item | 365 | Error: true, |
365 | Error bool | 366 | Protocol: "gemini", |
366 | Protocol string | 367 | }); e != nil { |
367 | }{title, hostport, assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}); e != nil { | ||
368 | log.Println("Template error: " + e.Error()) | 368 | log.Println("Template error: " + e.Error()) |
369 | log.Println(err.Error()) | 369 | log.Println(err.Error()) |
370 | } | 370 | } |
@@ -385,15 +385,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
385 | ) | 385 | ) |
386 | 386 | ||
387 | if err != nil { | 387 | if err != nil { |
388 | if e := tpl.Execute(w, struct { | 388 | if e := tpl.Execute(w, TemplateVariables{ |
389 | Title string | 389 | Title: title, |
390 | URI string | 390 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
391 | Assets AssetList | 391 | Assets: assetList, |
392 | RawText string | 392 | RawText: fmt.Sprintf("Error: %s", err), |
393 | Lines []Item | 393 | Error: true, |
394 | Error bool | 394 | Protocol: "gemini", |
395 | Protocol string | 395 | }); e != nil { |
396 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}); e != nil { | ||
397 | log.Println("Template error: " + e.Error()) | 396 | log.Println("Template error: " + e.Error()) |
398 | log.Println(err.Error()) | 397 | log.Println(err.Error()) |
399 | } | 398 | } |
@@ -407,15 +406,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
407 | uri, | 406 | uri, |
408 | )) | 407 | )) |
409 | if err != nil { | 408 | if err != nil { |
410 | if e := tpl.Execute(w, struct { | 409 | if e := tpl.Execute(w, TemplateVariables{ |
411 | Title string | 410 | Title: title, |
412 | URI string | 411 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
413 | Assets AssetList | 412 | Assets: assetList, |
414 | RawText string | 413 | RawText: fmt.Sprintf("Error: %s", err), |
415 | Lines []Item | 414 | Error: true, |
416 | Error bool | 415 | Protocol: "gemini", |
417 | Protocol string | 416 | }); e != nil { |
418 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error: %s", err), nil, true, "gemini"}); e != nil { | ||
419 | log.Println("Template error: " + e.Error()) | 417 | log.Println("Template error: " + e.Error()) |
420 | log.Println(err.Error()) | 418 | log.Println(err.Error()) |
421 | } | 419 | } |
@@ -427,15 +425,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
427 | } | 425 | } |
428 | 426 | ||
429 | if int(res.Header.Status/10) != 2 { | 427 | if int(res.Header.Status/10) != 2 { |
430 | if err := tpl.Execute(w, struct { | 428 | if err := tpl.Execute(w, TemplateVariables{ |
431 | Title string | 429 | Title: title, |
432 | URI string | 430 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
433 | Assets AssetList | 431 | Assets: assetList, |
434 | RawText string | 432 | RawText: fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), |
435 | Lines []Item | 433 | Error: true, |
436 | Error bool | 434 | Protocol: "gemini", |
437 | Protocol string | 435 | }); err != nil { |
438 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, fmt.Sprintf("Error %d: %s", res.Header.Status, res.Header.Meta), nil, true, "gemini"}); err != nil { | ||
439 | log.Println("Template error: " + err.Error()) | 436 | log.Println("Template error: " + err.Error()) |
440 | } | 437 | } |
441 | return | 438 | return |
@@ -468,15 +465,14 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
468 | rawText = buf.String() | 465 | rawText = buf.String() |
469 | } | 466 | } |
470 | 467 | ||
471 | if err := tpl.Execute(w, struct { | 468 | if err := tpl.Execute(w, TemplateVariables{ |
472 | Title string | 469 | Title: title, |
473 | URI string | 470 | URI: fmt.Sprintf("%s/%s", hostport, uri), |
474 | Assets AssetList | 471 | Assets: assetList, |
475 | RawText string | 472 | Lines: items, |
476 | Lines []Item | 473 | RawText: rawText, |
477 | Error bool | 474 | Protocol: "gemini", |
478 | Protocol string | 475 | }); err != nil { |
479 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"}); err != nil { | ||
480 | log.Println("Template error: " + err.Error()) | 476 | log.Println("Template error: " + err.Error()) |
481 | } | 477 | } |
482 | } else { | 478 | } else { |
@@ -678,7 +674,14 @@ func ListenAndServe(bind, startpagefile string, robotsfile string, robotsdebug b | |||
678 | ConcurrencyLevel: vipsconcurrency, | 674 | ConcurrencyLevel: vipsconcurrency, |
679 | }) | 675 | }) |
680 | 676 | ||
681 | assets := AssetList{styleAsset, jsAsset, fontwAsset, fontw2Asset, propfontwAsset, propfontw2Asset} | 677 | assets := AssetList{ |
678 | Style: styleAsset, | ||
679 | JS: jsAsset, | ||
680 | FontW: fontwAsset, | ||
681 | FontW2: fontw2Asset, | ||
682 | PropFontW: propfontwAsset, | ||
683 | PropFontW2: propfontw2Asset, | ||
684 | } | ||
682 | 685 | ||
683 | http.Handle("/", gziphandler.GzipHandler(DefaultHandler(tpl, startpagetext, assets))) | 686 | http.Handle("/", gziphandler.GzipHandler(DefaultHandler(tpl, startpagetext, assets))) |
684 | http.Handle("/gopher/", gziphandler.GzipHandler(GopherHandler(tpl, robotsdata, assets, robotsdebug))) | 687 | http.Handle("/gopher/", gziphandler.GzipHandler(GopherHandler(tpl, robotsdata, assets, robotsdebug))) |