From 67571c49c119993ce553bec68c87e59332b5e03c Mon Sep 17 00:00:00 2001 From: Feuerfuchs Date: Sat, 16 Nov 2019 09:59:03 +0100 Subject: Gemini: Add support for charset MIME parameter --- gopherproxy.go | 48 +++++++++++++++++++++++++++++------------------- 1 file changed, 29 insertions(+), 19 deletions(-) (limited to 'gopherproxy.go') diff --git a/gopherproxy.go b/gopherproxy.go index ab8e906..65c8f89 100644 --- a/gopherproxy.go +++ b/gopherproxy.go @@ -10,11 +10,15 @@ import ( "io" "io/ioutil" "log" + "mime" "net/http" "net/url" "regexp" "strings" + "golang.org/x/net/html/charset" + "golang.org/x/text/transform" + "github.com/temoto/robotstxt" "github.com/prologic/go-gopher" @@ -133,7 +137,7 @@ func renderGopherDirectory(w http.ResponseWriter, tpl *template.Template, assetL }{title, fmt.Sprintf("%s/%s", hostport, uri), assetList, out, "", false, "gopher"}) } -func parseGeminiDocument(response *GeminiResponse, uri string, hostport string) (items []Item) { +func parseGeminiDocument(body *bytes.Buffer, uri string, hostport string) (items []Item) { baseUrl, err := url.Parse(fmt.Sprintf( "gemini://%s/%s", hostport, @@ -143,8 +147,7 @@ func parseGeminiDocument(response *GeminiResponse, uri string, hostport string) return []Item{} } - scanner := bufio.NewScanner(response.Body) - scanner.Split(bufio.ScanLines) + scanner := bufio.NewScanner(body) for scanner.Scan() { line := strings.Trim(scanner.Text(), "\r\n") @@ -380,25 +383,32 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass } if strings.HasPrefix(res.Header.Meta, "text/") { - // TODO: Handle encoding - // https://stackoverflow.com/questions/32518432/how-to-convert-from-an-encoding-to-utf-8-in-go + buf := new(bytes.Buffer) + + _, params, err := mime.ParseMediaType(res.Header.Meta) + if err != nil { + buf.ReadFrom(res.Body) + } else { + encoding, _ := charset.Lookup(params["charset"]) + readbuf := new(bytes.Buffer) + readbuf.ReadFrom(res.Body) + + writer := transform.NewWriter(buf, encoding.NewDecoder()) + writer.Write(readbuf.Bytes()) + writer.Close() + } + + var ( + rawText string + items []Item + ) if strings.HasPrefix(res.Header.Meta, MIME_GEMINI) { - items := parseGeminiDocument(res, uri, hostport) - tpl.Execute(w, struct { - Title string - URI string - Assets AssetList - RawText string - Lines []Item - Error bool - Protocol string - }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, "", items, false, "gemini"}) - return + items = parseGeminiDocument(buf, uri, hostport) + } else { + rawText = buf.String() } - buf := new(bytes.Buffer) - buf.ReadFrom(res.Body) tpl.Execute(w, struct { Title string URI string @@ -407,7 +417,7 @@ func GeminiHandler(tpl *template.Template, robotsdata *robotstxt.RobotsData, ass Lines []Item Error bool Protocol string - }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, buf.String(), nil, false, "gemini"}) + }{uri, fmt.Sprintf("%s/%s", hostport, uri), assetList, rawText, items, false, "gemini"}) } else { io.Copy(w, res.Body) } -- cgit v1.2.3-54-g00ecf