aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorFeuerfuchs <git@feuerfuchs.dev>2019-11-16 09:59:03 +0100
committerFeuerfuchs <git@feuerfuchs.dev>2019-11-16 09:59:03 +0100
commit67571c49c119993ce553bec68c87e59332b5e03c (patch)
tree458efc711f3cf99a55a4ab3aba4f8cdf1cc3ac5d
parentFixed some issues with Gemini (diff)
downloadgopherproxy-67571c49c119993ce553bec68c87e59332b5e03c.tar.gz
gopherproxy-67571c49c119993ce553bec68c87e59332b5e03c.tar.bz2
gopherproxy-67571c49c119993ce553bec68c87e59332b5e03c.zip
Gemini: Add support for charset MIME parameter
-rw-r--r--go.mod2
-rw-r--r--go.sum1
-rw-r--r--gopherproxy.go48
-rw-r--r--libgemini.go14
4 files changed, 40 insertions, 25 deletions
diff --git a/go.mod b/go.mod
index b8e8baf..503bb87 100644
--- a/go.mod
+++ b/go.mod
@@ -7,6 +7,8 @@ require (
7 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646 7 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646
8 github.com/prologic/go-gopher v0.0.0-20181230133552-0c68ed5f58b0 8 github.com/prologic/go-gopher v0.0.0-20181230133552-0c68ed5f58b0
9 github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea 9 github.com/temoto/robotstxt v0.0.0-20180810133444-97ee4a9ee6ea
10 golang.org/x/net v0.0.0-20190311183353-d8887717615a
11 golang.org/x/text v0.3.0
10) 12)
11 13
12go 1.13 14go 1.13
diff --git a/go.sum b/go.sum
index 544eee6..7f255e0 100644
--- a/go.sum
+++ b/go.sum
@@ -83,6 +83,7 @@ golang.org/x/sync v0.0.0-20190412183630-56d357773e84/go.mod h1:RxMgew5VJxzue5/jJ
83golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 83golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
84golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU= 84golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a h1:1BGLXjeY4akVXGgbC9HugT3Jv3hCI0z56oJR5vAMgBU=
85golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= 85golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
86golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
86golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= 87golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
87golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= 88golang.org/x/tools v0.0.0-20190329151228-23e29df326fe/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs=
88golang.org/x/tools v0.0.0-20190404132500-923d25813098 h1:MtqjsZmyGRgMmLUgxnmMJ6RYdvd2ib8ipiayHhqSxs4= 89golang.org/x/tools v0.0.0-20190404132500-923d25813098 h1:MtqjsZmyGRgMmLUgxnmMJ6RYdvd2ib8ipiayHhqSxs4=
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
136func parseGeminiDocument(response *GeminiResponse, uri string, hostport string) (items []Item) { 140func 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 }
diff --git a/libgemini.go b/libgemini.go
index 56e1463..20fc137 100644
--- a/libgemini.go
+++ b/libgemini.go
@@ -5,6 +5,7 @@ import (
5 "crypto/tls" 5 "crypto/tls"
6 "errors" 6 "errors"
7 "io" 7 "io"
8 "mime"
8 "net/url" 9 "net/url"
9 "regexp" 10 "regexp"
10 "strconv" 11 "strconv"
@@ -134,13 +135,14 @@ func ParseGeminiHeader(line string) (header *GeminiHeader, err error) {
134 meta := matches[2] 135 meta := matches[2]
135 136
136 if int(status/10) == 2 { 137 if int(status/10) == 2 {
137 if meta == "" { 138 mediaType, params, err := mime.ParseMediaType(meta)
138 meta = DEFAULT_MIME + ";charset=" + DEFAULT_CHARSET
139 }
140 139
141 mimeType := MimeTypePattern.FindString(meta) 140 if err != nil {
142 if strings.HasPrefix(mimeType, "text/") && MimeCharsetPattern.FindString(meta) == "" { 141 meta = DEFAULT_MIME + ";charset=" + DEFAULT_CHARSET
143 meta += ";charset=" + DEFAULT_CHARSET 142 } else if strings.HasPrefix(mediaType, "text/") {
143 if _, ok := params["charset"]; !ok {
144 meta += ";charset=" + DEFAULT_CHARSET
145 }
144 } 146 }
145 } 147 }
146 148