Changeset 60 in code for trunk/morty.go
- Timestamp:
- Dec 1, 2016, 12:45:38 PM (9 years ago)
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/morty.go
r59 r60 15 15 "strings" 16 16 "time" 17 "unicode/utf8" 17 18 18 19 "github.com/valyala/fasthttp" … … 208 209 209 210 req.SetRequestURI(requestURIStr) 210 req.Header.SetUserAgentBytes([]byte("Mozilla/5.0 (Windows NT 10.0; WOW64; rv:50.0) Gecko/20100101 Firefox/50.0"))211 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")) 211 212 212 213 resp := fasthttp.AcquireResponse() … … 237 238 if loc != nil { 238 239 rc := &RequestConfig{Key: p.Key, BaseURL: parsedURI} 239 url, err := rc.ProxifyURI( string(loc))240 url, err := rc.ProxifyURI(loc) 240 241 if err == nil { 241 242 ctx.SetStatusCode(resp.StatusCode()) … … 346 347 urlEnd := s[5] 347 348 348 if uri, err := rc.ProxifyURI( string(css[urlStart:urlEnd])); err == nil {349 if uri, err := rc.ProxifyURI(css[urlStart:urlEnd]); err == nil { 349 350 out.Write(css[startIndex:urlStart]) 350 351 out.Write([]byte(uri)) … … 500 501 } 501 502 502 case html.CommentToken: 503 // ignore comment. TODO : parse IE conditional comment 504 505 case html.DoctypeToken: 503 case html.DoctypeToken, html.CommentToken: 506 504 out.Write(decoder.Raw()) 507 505 } … … 586 584 } 587 585 // output proxify result 588 if uri, err := rc.ProxifyURI( string(contentUrl)); err == nil {586 if uri, err := rc.ProxifyURI(contentUrl); err == nil { 589 587 fmt.Fprintf(out, ` http-equiv="refresh" content="%surl=%s"`, content[:urlIndex], uri) 590 588 } … … 611 609 switch string(attrName) { 612 610 case "src", "href", "action": 613 if uri, err := rc.ProxifyURI( string(attrValue)); err == nil {611 if uri, err := rc.ProxifyURI(attrValue); err == nil { 614 612 fmt.Fprintf(out, " %s=\"%s\"", attrName, uri) 615 613 } else { … … 627 625 } 628 626 629 func (rc *RequestConfig) ProxifyURI(uri string) (string, error) { 627 // Sanitized URI : removes all runes bellow 32 (included) as the begining and end of URI, and lower case the scheme. 628 // avoid memory allocation (except for the scheme) 629 func sanitizeURI(uri []byte) ([]byte, string) { 630 first_rune_index := 0 631 first_rune_seen := false 632 scheme_last_index := -1 633 buffer := bytes.NewBuffer(make([]byte, 0, 10)) 634 635 // remove trailing space and special characters 636 uri = bytes.TrimRight(uri, "\x00\x01\x02\x03\x04\x05\x06\x07\x08\x09\x0A\x0B\x0C\x0D\x0E\x0F\x10\x11\x12\x13\x14\x15\x16\x17\x18\x19\x1A\x1B\x1C\x1D\x1E\x1F\x20") 637 638 // loop over byte by byte 639 for i, c := range uri { 640 // ignore special characters and space (c <= 32) 641 if c > 32 { 642 // append to the lower case of the rune to buffer 643 if c < utf8.RuneSelf && 'A' <= c && c <= 'Z' { 644 c = c + 'a' - 'A' 645 } 646 647 buffer.WriteByte(c) 648 649 // update the first rune index that is not a special rune 650 if !first_rune_seen { 651 first_rune_index = i 652 first_rune_seen = true 653 } 654 655 if c == ':' { 656 // colon rune found, we have found the scheme 657 scheme_last_index = i 658 break 659 } else if c == '/' || c == '?' || c == '\\' || c == '#' { 660 // special case : most probably a relative URI 661 break 662 } 663 } 664 } 665 666 if scheme_last_index != -1 { 667 // scheme found 668 // copy the "lower case without special runes scheme" before the ":" rune 669 scheme_start_index := scheme_last_index - buffer.Len() + 1 670 copy(uri[scheme_start_index:], buffer.Bytes()) 671 // and return the result 672 return uri[scheme_start_index:], buffer.String() 673 } else { 674 // scheme NOT found 675 return uri[first_rune_index:], "" 676 } 677 } 678 679 func (rc *RequestConfig) ProxifyURI(uri []byte) (string, error) { 680 // sanitize URI 681 uri, scheme := sanitizeURI(uri) 682 630 683 // remove javascript protocol 631 if s trings.HasPrefix(uri, "javascript:"){684 if scheme == "javascript:" { 632 685 return "", nil 633 686 } 634 687 635 688 // TODO check malicious data: - e.g. data:script 636 if s trings.HasPrefix(uri, "data:"){637 return uri, nil689 if scheme == "data:" { 690 return string(uri), nil 638 691 } 639 692 640 693 // parse the uri 641 u, err := url.Parse( uri)694 u, err := url.Parse(string(uri)) 642 695 if err != nil { 643 696 return "", err … … 668 721 669 722 // return full URI and fragment (if not empty) 670 uri= u.String()723 morty_uri := u.String() 671 724 672 725 if rc.Key == nil { 673 return fmt.Sprintf("./?mortyurl=%s%s", url.QueryEscape( uri), fragment), nil674 } 675 return fmt.Sprintf("./?mortyhash=%s&mortyurl=%s%s", hash( uri, rc.Key), url.QueryEscape(uri), fragment), nil726 return fmt.Sprintf("./?mortyurl=%s%s", url.QueryEscape(morty_uri), fragment), nil 727 } 728 return fmt.Sprintf("./?mortyhash=%s&mortyurl=%s%s", hash(morty_uri, rc.Key), url.QueryEscape(morty_uri), fragment), nil 676 729 } 677 730
Note:
See TracChangeset
for help on using the changeset viewer.