From f8623282a5e1be785b2e81280dfc8b4c9a52b6b0 Mon Sep 17 00:00:00 2001 From: alex Date: Mon, 28 Nov 2016 09:59:14 +0000 Subject: [PATCH] [fix] fix #14. Fetched URI matched the mortyurl. Query parameters in requested URI were parsed and set again. Unfortunately a query ?a&b were changed into ?a=b= which can lead to 404 errors. git-svn-id: file:///srv/svn/repo/yukari/trunk@44 f3bd38d9-da89-464d-a02a-eb04e43141b5 --- morty.go | 79 +++++++++++++++++++------------------------------------- 1 file changed, 27 insertions(+), 52 deletions(-) diff --git a/morty.go b/morty.go index ce18bd3..0351a2a 100644 --- a/morty.go +++ b/morty.go @@ -17,8 +17,7 @@ import ( "github.com/valyala/fasthttp" "golang.org/x/net/html" - "golang.org/x/net/html/charset" - "golang.org/x/text/encoding" + "golang.org/x/text/encoding/charmap" ) const ( @@ -123,8 +122,6 @@ input[type=checkbox]#mortytoggle:checked ~ div { display: none; } ` -var HTML_META_CONTENT_TYPE string = "" - func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) { if appRequestHandler(ctx) { @@ -166,18 +163,11 @@ func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) { defer fasthttp.ReleaseRequest(req) req.SetConnectionClose() - reqQuery := parsedURI.Query() - ctx.QueryArgs().VisitAll(func(key, value []byte) { - reqQuery.Add(string(key), string(value)) - }) + requestURIStr := string(requestURI) - parsedURI.RawQuery = reqQuery.Encode() + log.Println("getting", requestURIStr) - uriStr := parsedURI.String() - - log.Println("getting", uriStr) - - req.SetRequestURI(uriStr) + req.SetRequestURI(requestURIStr) req.Header.SetUserAgentBytes([]byte("Mozilla/5.0 (Windows NT 6.1; WOW64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/53.0.2785.143 Safari/537.36")) resp := fasthttp.AcquireResponse() @@ -216,7 +206,7 @@ func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) { } } } - error_message := fmt.Sprintf("invalid response: %d", resp.StatusCode()) + error_message := fmt.Sprintf("invalid response: %d (%s)", resp.StatusCode(), requestURIStr) p.serveMainPage(ctx, resp.StatusCode(), errors.New(error_message)) return } @@ -239,17 +229,13 @@ func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) { var responseBody []byte - if len(contentInfo) == 2 && bytes.Contains(contentInfo[0], []byte("text")) { - e, ename, _ := charset.DetermineEncoding(resp.Body(), string(contentType)) - if (e != encoding.Nop) && (!strings.EqualFold("utf-8", ename)) { - responseBody, err = e.NewDecoder().Bytes(resp.Body()) - if err != nil { - // HTTP status code 503 : Service Unavailable - p.serveMainPage(ctx, 503, err) - return - } - } else { - responseBody = resp.Body() + if len(contentInfo) == 2 && bytes.Contains(contentInfo[1], []byte("ISO-8859-2")) && bytes.Contains(contentInfo[0], []byte("text")) { + var err error + responseBody, err = charmap.ISO8859_2.NewDecoder().Bytes(resp.Body()) + if err != nil { + // HTTP status code 503 : Service Unavailable + p.serveMainPage(ctx, 503, err) + return } } else { responseBody = resp.Body() @@ -332,6 +318,7 @@ func sanitizeHTML(rc *RequestConfig, out io.Writer, htmlDoc []byte) { unsafeElements := make([][]byte, 0, 8) state := STATE_DEFAULT + for { token := decoder.Next() if token == html.ErrorToken { @@ -359,11 +346,12 @@ func sanitizeHTML(rc *RequestConfig, out io.Writer, htmlDoc []byte) { if bytes.Equal(tag, []byte("base")) { for { attrName, attrValue, moreAttr := decoder.TagAttr() - if bytes.Equal(attrName, []byte("href")) { - parsedURI, err := url.Parse(string(attrValue)) - if err == nil { - rc.BaseURL = parsedURI - } + if !bytes.Equal(attrName, []byte("href")) { + continue + } + parsedURI, err := url.Parse(string(attrValue)) + if err == nil { + rc.BaseURL = parsedURI } if !moreAttr { break @@ -394,15 +382,14 @@ func sanitizeHTML(rc *RequestConfig, out io.Writer, htmlDoc []byte) { break } - if bytes.Equal(tag, []byte("meta")) { - sanitizeMetaTag(rc, out, attrs) - break - } - fmt.Fprintf(out, "<%s", tag) if hasAttrs { - sanitizeAttrs(rc, out, attrs) + if bytes.Equal(tag, []byte("meta")) { + sanitizeMetaAttrs(rc, out, attrs) + } else { + sanitizeAttrs(rc, out, attrs) + } } if token == html.SelfClosingTagToken { @@ -414,10 +401,6 @@ func sanitizeHTML(rc *RequestConfig, out io.Writer, htmlDoc []byte) { } } - if bytes.Equal(tag, []byte("head")) { - fmt.Fprintf(out, HTML_META_CONTENT_TYPE) - } - if bytes.Equal(tag, []byte("form")) { var formURL *url.URL for _, attr := range attrs { @@ -515,7 +498,7 @@ func sanitizeLinkTag(rc *RequestConfig, out io.Writer, attrs [][][]byte) { } } -func sanitizeMetaTag(rc *RequestConfig, out io.Writer, attrs [][][]byte) { +func sanitizeMetaAttrs(rc *RequestConfig, out io.Writer, attrs [][][]byte) { var http_equiv []byte var content []byte @@ -528,17 +511,8 @@ func sanitizeMetaTag(rc *RequestConfig, out io.Writer, attrs [][][]byte) { if bytes.Equal(attrName, []byte("content")) { content = attrValue } - if bytes.Equal(attrName, []byte("charset")) { - // exclude - return - } } - if bytes.Equal(http_equiv, []byte("content-type")) { - return - } - - out.Write([]byte("")) + } func sanitizeAttrs(rc *RequestConfig, out io.Writer, attrs [][][]byte) { @@ -612,6 +586,7 @@ func (rc *RequestConfig) ProxifyURI(uri string) (string, error) { if rc.Key == nil { return fmt.Sprintf("./?mortyurl=%s", url.QueryEscape(uri)), nil } + return fmt.Sprintf("./?mortyhash=%s&mortyurl=%s", hash(uri, rc.Key), url.QueryEscape(uri)), nil }