diff options
Diffstat (limited to 'gopherproxy.go')
| -rw-r--r-- | gopherproxy.go | 48 |
1 files changed, 29 insertions, 19 deletions
diff --git a/gopherproxy.go b/gopherproxy.go index ab8e906..65c8f89 100644 --- a/gopherproxy.go +++ b/gopherproxy.go | |||
| @@ -10,11 +10,15 @@ import ( | |||
| 10 | "io" | 10 | "io" |
| 11 | "io/ioutil" | 11 | "io/ioutil" |
| 12 | "log" | 12 | "log" |
| 13 | "mime" | ||
| 13 | "net/http" | 14 | "net/http" |
| 14 | "net/url" | 15 | "net/url" |
| 15 | "regexp" | 16 | "regexp" |
| 16 | "strings" | 17 | "strings" |
| 17 | 18 | ||
| 19 | "golang.org/x/net/html/charset" | ||
| 20 | "golang.org/x/text/transform" | ||
| 21 | |||
| 18 | "github.com/temoto/robotstxt" | 22 | "github.com/temoto/robotstxt" |
| 19 | 23 | ||
| 20 | "github.com/prologic/go-gopher" | 24 | "github.com/prologic/go-gopher" |
| @@ -133,7 +137,7 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL | |||
| 133 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, out, "", false, "gopher"}) | 137 | }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, out, "", false, "gopher"}) |
| 134 | } | 138 | } |
| 135 | 139 | ||
| 136 | func parseGeminiDocument(response *GeminiResponse, uri string, hostport string) (items []Item) { | 140 | func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items []Item) { |
| 137 | baseUrl, err := url.Parse(fmt.Sprintf( | 141 | baseUrl, err := url.Parse(fmt.Sprintf( |
| 138 | "gemini://%s/%s", | 142 | "gemini://%s/%s", |
| 139 | hostport, | 143 | hostport, |
| @@ -143,8 +147,7 @@ func parseGeminiDocument(response *GeminiResponse, uri string, hostport string) | |||
| 143 | return []Item{} | 147 | return []Item{} |
| 144 | } | 148 | } |
| 145 | 149 | ||
| 146 | scanner := bufio.NewScanner(response.Body) | 150 | scanner := bufio.NewScanner(body) |
| 147 | scanner.Split(bufio.ScanLines) | ||
| 148 | 151 | ||
| 149 | for scanner.Scan() { | 152 | for scanner.Scan() { |
| 150 | line := strings.Trim(scanner.Text(), "\r\n") | 153 | line := strings.Trim(scanner.Text(), "\r\n") |
| @@ -380,25 +383,32 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
| 380 | } | 383 | } |
| 381 | 384 | ||
| 382 | if strings.HasPrefix(res.Header.Meta, "text/") { | 385 | if strings.HasPrefix(res.Header.Meta, "text/") { |
| 383 | // TODO: Handle encoding | 386 | buf := new(bytes.Buffer) |
| 384 | // https://stackoverflow.com/questions/32518432/how-to-convert-from-an-encoding-to-utf-8-in-go | 387 | |
| 388 | _, params, err := mime.ParseMediaType(res.Header.Meta) | ||
| 389 | if err != nil { | ||
| 390 | buf.ReadFrom(res.Body) | ||
| 391 | } else { | ||
| 392 | encoding, _ := charset.Lookup(params["charset"]) | ||
| 393 | readbuf := new(bytes.Buffer) | ||
| 394 | readbuf.ReadFrom(res.Body) | ||
| 395 | |||
| 396 | writer := transform.NewWriter(buf, encoding.NewDecoder()) | ||
| 397 | writer.Write(readbuf.Bytes()) | ||
| 398 | writer.Close() | ||
| 399 | } | ||
| 400 | |||
| 401 | var ( | ||
| 402 | rawText string | ||
| 403 | items []Item | ||
| 404 | ) | ||
| 385 | 405 | ||
| 386 | if strings.HasPrefix(res.Header.Meta, MIME_GEMINI) { | 406 | if strings.HasPrefix(res.Header.Meta, MIME_GEMINI) { |
| 387 | items := parseGeminiDocument(res, uri, hostport) | 407 | items = parseGeminiDocument(buf, uri, hostport) |
| 388 | tpl.Execute(w, struct { | 408 | } else { |
| 389 | Title string | 409 | rawText = buf.String() |
| 390 | URI string | ||
| 391 | Assets AssetList | ||
| 392 | RawText string | ||
| 393 | Lines []Item | ||
| 394 | Error bool | ||
| 395 | Protocol string | ||
| 396 | }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, "", items, false, "gemini"}) | ||
| 397 | return | ||
| 398 | } | 410 | } |
| 399 | 411 | ||
| 400 | buf := new(bytes.Buffer) | ||
| 401 | buf.ReadFrom(res.Body) | ||
| 402 | tpl.Execute(w, struct { | 412 | tpl.Execute(w, struct { |
| 403 | Title string | 413 | Title string |
| 404 | URI string | 414 | URI string |
| @@ -407,7 +417,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass | |||
| 407 | Lines []Item | 417 | Lines []Item |
| 408 | Error bool | 418 | Error bool |
| 409 | Protocol string | 419 | Protocol string |
| 410 | }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gemini"}) | 420 | }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"}) |
| 411 | } else { | 421 | } else { |
| 412 | io.Copy(w, res.Body) | 422 | io.Copy(w, res.Body) |
| 413 | } | 423 | } |
