diff options
author | Feuerfuchs <git@feuerfuchs.dev> | 2019-11-16 09:59:03 +0100 |
---|---|---|
committer | Feuerfuchs <git@feuerfuchs.dev> | 2019-11-16 09:59:03 +0100 |
commit | 67571c49c119993ce553bec68c87e59332b5e03c (patch) | |
tree | 458efc711f3cf99a55a4ab3aba4f8cdf1cc3ac5d /gopherproxy.go | |
parent | Fixed some issues with Gemini (diff) | |
download | gopherproxy-67571c49c119993ce553bec68c87e59332b5e03c.tar.gz gopherproxy-67571c49c119993ce553bec68c87e59332b5e03c.tar.bz2 gopherproxy-67571c49c119993ce553bec68c87e59332b5e03c.zip |
Gemini: Add support for charset MIME parameter
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 | } |