diff options
Diffstat (limited to 'main.go')
| -rw-r--r-- | main.go | 70 |
1 files changed, 60 insertions, 10 deletions
| @@ -3,7 +3,9 @@ package main | |||
| 3 | import ( | 3 | import ( |
| 4 | "flag" | 4 | "flag" |
| 5 | "fmt" | 5 | "fmt" |
| 6 | "html/template" | ||
| 6 | "io" | 7 | "io" |
| 8 | "io/ioutil" | ||
| 7 | "log" | 9 | "log" |
| 8 | "net/http" | 10 | "net/http" |
| 9 | "strings" | 11 | "strings" |
| @@ -17,31 +19,79 @@ var ( | |||
| 17 | port = flag.Int("port", 70, "port to proxy to") | 19 | port = flag.Int("port", 70, "port to proxy to") |
| 18 | ) | 20 | ) |
| 19 | 21 | ||
| 20 | func proxy(res http.ResponseWriter, req *http.Request) { | 22 | type tplRow struct { |
| 23 | Link template.URL | ||
| 24 | Type string | ||
| 25 | Text string | ||
| 26 | } | ||
| 27 | |||
| 28 | func renderDirectory(w http.ResponseWriter, tpl *template.Template, d gopher.Directory) error { | ||
| 29 | out := make([]tplRow, len(d)) | ||
| 30 | |||
| 31 | for i, x := range d { | ||
| 32 | tr := tplRow{ | ||
| 33 | Text: x.Description, | ||
| 34 | Type: x.Type.String(), | ||
| 35 | } | ||
| 36 | |||
| 37 | if x.Type == gopher.INFO { | ||
| 38 | out[i] = tr | ||
| 39 | continue | ||
| 40 | } | ||
| 41 | |||
| 42 | if strings.HasPrefix(x.Selector, "URL:") { | ||
| 43 | tr.Link = template.URL(x.Selector[4:]) | ||
| 44 | } else { | ||
| 45 | tr.Link = template.URL( | ||
| 46 | fmt.Sprintf( | ||
| 47 | "%s%s", string(byte(x.Type)), x.Selector, | ||
| 48 | ), | ||
| 49 | ) | ||
| 50 | } | ||
| 51 | |||
| 52 | out[i] = tr | ||
| 53 | } | ||
| 54 | |||
| 55 | return tpl.Execute(w, struct { | ||
| 56 | Title string | ||
| 57 | Lines []tplRow | ||
| 58 | }{"XXX", out}) | ||
| 59 | } | ||
| 60 | |||
| 61 | func proxy(w http.ResponseWriter, req *http.Request) { | ||
| 21 | path := strings.TrimPrefix(req.URL.Path, "/") | 62 | path := strings.TrimPrefix(req.URL.Path, "/") |
| 22 | 63 | ||
| 23 | gr, err := gopher.Get(fmt.Sprintf("gopher://%s:%d/%s", *host, *port, path)) | 64 | res, err := gopher.Get(fmt.Sprintf("gopher://%s:%d/%s", *host, *port, path)) |
| 24 | if err != nil { | 65 | if err != nil { |
| 25 | io.WriteString(res, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) | 66 | io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) |
| 26 | return | 67 | return |
| 27 | } | 68 | } |
| 28 | 69 | ||
| 29 | if gr.Body != nil { | 70 | if res.Body != nil { |
| 30 | io.Copy(res, gr.Body) | 71 | io.Copy(w, res.Body) |
| 31 | } else { | 72 | } else { |
| 32 | bytes, err := gr.Dir.ToText() | 73 | if err := renderDirectory(w, tpl, res.Dir); err != nil { |
| 33 | if err != nil { | 74 | io.WriteString(w, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) |
| 34 | io.WriteString(res, fmt.Sprintf("<b>Error:</b><pre>%s</pre>", err)) | ||
| 35 | return | 75 | return |
| 36 | } | 76 | } |
| 37 | |||
| 38 | io.WriteString(res, string(bytes)) | ||
| 39 | } | 77 | } |
| 40 | } | 78 | } |
| 41 | 79 | ||
| 80 | var tpl *template.Template | ||
| 81 | |||
| 42 | func main() { | 82 | func main() { |
| 43 | flag.Parse() | 83 | flag.Parse() |
| 44 | 84 | ||
| 85 | tpldata, err := ioutil.ReadFile(".template") | ||
| 86 | if err == nil { | ||
| 87 | tpltext = string(tpldata) | ||
| 88 | } | ||
| 89 | |||
| 90 | tpl, err = template.New("gophermenu").Parse(tpltext) | ||
| 91 | if err != nil { | ||
| 92 | log.Fatal(err) | ||
| 93 | } | ||
| 94 | |||
| 45 | http.HandleFunc("/", proxy) | 95 | http.HandleFunc("/", proxy) |
| 46 | log.Fatal(http.ListenAndServe(*bind, nil)) | 96 | log.Fatal(http.ListenAndServe(*bind, nil)) |
| 47 | } | 97 | } |
