url.go 2.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990
  1. package optionsparser
  2. import (
  3. "encoding/base64"
  4. "fmt"
  5. "net/url"
  6. "strings"
  7. )
  8. const urlTokenPlain = "plain"
  9. func (p *Parser) preprocessURL(u string) string {
  10. for _, repl := range p.config.URLReplacements {
  11. u = repl.Regexp.ReplaceAllString(u, repl.Replacement)
  12. }
  13. if len(p.config.BaseURL) == 0 || strings.HasPrefix(u, p.config.BaseURL) {
  14. return u
  15. }
  16. return fmt.Sprintf("%s%s", p.config.BaseURL, u)
  17. }
  18. func (p *Parser) decodeBase64URL(parts []string) (string, string, error) {
  19. var format string
  20. if len(parts) > 1 && p.config.Base64URLIncludesFilename {
  21. parts = parts[:len(parts)-1]
  22. }
  23. encoded := strings.Join(parts, "")
  24. urlParts := strings.Split(encoded, ".")
  25. if len(urlParts[0]) == 0 {
  26. return "", "", newInvalidURLError("Image URL is empty")
  27. }
  28. if len(urlParts) > 2 {
  29. return "", "", newInvalidURLError("Multiple formats are specified: %s", encoded)
  30. }
  31. if len(urlParts) == 2 && len(urlParts[1]) > 0 {
  32. format = urlParts[1]
  33. }
  34. imageURL, err := base64.RawURLEncoding.DecodeString(strings.TrimRight(urlParts[0], "="))
  35. if err != nil {
  36. return "", "", newInvalidURLError("Invalid url encoding: %s", encoded)
  37. }
  38. return p.preprocessURL(string(imageURL)), format, nil
  39. }
  40. func (p *Parser) decodePlainURL(parts []string) (string, string, error) {
  41. var format string
  42. encoded := strings.Join(parts, "/")
  43. urlParts := strings.Split(encoded, "@")
  44. if len(urlParts[0]) == 0 {
  45. return "", "", newInvalidURLError("Image URL is empty")
  46. }
  47. if len(urlParts) > 2 {
  48. return "", "", newInvalidURLError("Multiple formats are specified: %s", encoded)
  49. }
  50. if len(urlParts) == 2 && len(urlParts[1]) > 0 {
  51. format = urlParts[1]
  52. }
  53. unescaped, err := url.PathUnescape(urlParts[0])
  54. if err != nil {
  55. return "", "", newInvalidURLError("Invalid url encoding: %s", encoded)
  56. }
  57. return p.preprocessURL(unescaped), format, nil
  58. }
  59. func (p *Parser) DecodeURL(parts []string) (string, string, error) {
  60. if len(parts) == 0 {
  61. return "", "", newInvalidURLError("Image URL is empty")
  62. }
  63. if parts[0] == urlTokenPlain && len(parts) > 1 {
  64. return p.decodePlainURL(parts[1:])
  65. }
  66. return p.decodeBase64URL(parts)
  67. }