Changeset 42 in code for trunk/morty.go


Ignore:
Timestamp:
Nov 26, 2016, 12:45:12 PM (9 years ago)
Author:
alex
Message:

[enh] support different encodings (all encoding are convert to UTF-8 as before)

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/morty.go

    r41 r42  
    1818        "github.com/valyala/fasthttp"
    1919        "golang.org/x/net/html"
    20         "golang.org/x/text/encoding/charmap"
     20        "golang.org/x/net/html/charset"
     21        "golang.org/x/text/encoding"
    2122)
    2223
     
    123124`
    124125
     126var HTML_META_CONTENT_TYPE string = "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\">"
     127
    125128func (p *Proxy) RequestHandler(ctx *fasthttp.RequestCtx) {
    126129
     
    237240        var responseBody []byte
    238241
    239         if len(contentInfo) == 2 && bytes.Contains(contentInfo[1], []byte("ISO-8859-2")) && bytes.Contains(contentInfo[0], []byte("text")) {
    240                 var err error
    241                 responseBody, err = charmap.ISO8859_2.NewDecoder().Bytes(resp.Body())
    242                 if err != nil {
    243                         // HTTP status code 503 : Service Unavailable
    244                         p.serveMainPage(ctx, 503, err)
    245                         return
     242        if len(contentInfo) == 2 && bytes.Contains(contentInfo[0], []byte("text")) {
     243                e, ename, _ := charset.DetermineEncoding(resp.Body(), string(contentType))
     244                if (e != encoding.Nop) && (!strings.EqualFold("utf-8", ename)) {
     245                        responseBody, err = e.NewDecoder().Bytes(resp.Body())
     246                        if err != nil {
     247                                // HTTP status code 503 : Service Unavailable
     248                                p.serveMainPage(ctx, 503, err)
     249                                return
     250                        }
     251                } else {
     252                        responseBody = resp.Body()
    246253                }
    247254        } else {
     
    326333        unsafeElements := make([][]byte, 0, 8)
    327334        state := STATE_DEFAULT
    328 
    329335        for {
    330336                token := decoder.Next()
     
    354360                                        for {
    355361                                                attrName, attrValue, moreAttr := decoder.TagAttr()
    356                                                 if bytes.Equal(attrName, []byte("href")) {
    357                                                         parsedURI, err := url.Parse(string(attrValue))
    358                                                         if err == nil {
    359                                                                 rc.BaseURL = parsedURI
    360                                                         }
     362                                                if !bytes.Equal(attrName, []byte("href")) {
     363                                                        continue
     364                                                }
     365                                                parsedURI, err := url.Parse(string(attrValue))
     366                                                if err == nil {
     367                                                        rc.BaseURL = parsedURI
    361368                                                }
    362369                                                if !moreAttr {
     
    389396                                }
    390397
     398                                if bytes.Equal(tag, []byte("meta")) {
     399                                        sanitizeMetaTag(rc, out, attrs)
     400                                        break
     401                                }
     402
    391403                                fmt.Fprintf(out, "<%s", tag)
    392404
    393405                                if hasAttrs {
    394                                         if bytes.Equal(tag, []byte("meta")) {
    395                                                 sanitizeMetaAttrs(rc, out, attrs)
    396                                         } else {
    397                                                 sanitizeAttrs(rc, out, attrs)
    398                                         }
     406                                        sanitizeAttrs(rc, out, attrs)
    399407                                }
    400408
     
    406414                                                state = STATE_IN_STYLE
    407415                                        }
     416                                }
     417
     418                                if bytes.Equal(tag, []byte("head")) {
     419                                        fmt.Fprintf(out, HTML_META_CONTENT_TYPE)
    408420                                }
    409421
     
    505517}
    506518
    507 func sanitizeMetaAttrs(rc *RequestConfig, out io.Writer, attrs [][][]byte) {
     519func sanitizeMetaTag(rc *RequestConfig, out io.Writer, attrs [][][]byte) {
    508520        var http_equiv []byte
    509521        var content []byte
     
    518530                        content = attrValue
    519531                }
    520         }
    521 
     532                if bytes.Equal(attrName, []byte("charset")) {
     533                        // exclude <meta charset="...">
     534                        return
     535                }
     536        }
     537
     538        if bytes.Equal(http_equiv, []byte("content-type")) {
     539                return
     540        }
     541
     542        out.Write([]byte("<meta"))
    522543        urlIndex := bytes.Index(bytes.ToLower(content), []byte("url="))
    523544        if bytes.Equal(http_equiv, []byte("refresh")) && urlIndex != -1 {
     
    536557                sanitizeAttrs(rc, out, attrs)
    537558        }
    538 
     559        out.Write([]byte(">"))
    539560}
    540561
Note: See TracChangeset for help on using the changeset viewer.