url.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149
  1. package dara
  2. import (
  3. "fmt"
  4. "net/url"
  5. "strings"
  6. )
  7. // PortMap maps protocols to their corresponding ports.
  8. var portMap = map[string]string{
  9. "ftp": "21",
  10. "gopher": "70",
  11. "http": "80",
  12. "https": "443",
  13. "ws": "80",
  14. "wss": "443",
  15. }
  16. // URL is a wrapper around the URL type.
  17. type URL struct {
  18. _url *url.URL
  19. }
  20. // NewURL constructs a new URL from a string.
  21. func NewURL(str string) (*URL, error) {
  22. parsedURL, err := url.Parse(str)
  23. if err != nil {
  24. return nil, err
  25. }
  26. return &URL{_url: parsedURL}, nil
  27. }
  28. // Path returns the path and query of the URL.
  29. func (t *URL) Path() string {
  30. if t._url.RawQuery == "" {
  31. return t._url.Path
  32. }
  33. return t._url.Path + "?" + t._url.RawQuery
  34. }
  35. // Pathname returns the pathname of the URL.
  36. func (t *URL) Pathname() string {
  37. return t._url.Path
  38. }
  39. // Protocol returns the protocol of the URL.
  40. func (t *URL) Protocol() string {
  41. return strings.TrimSuffix(t._url.Scheme, ":")
  42. }
  43. // Hostname returns the hostname of the URL.
  44. func (t *URL) Hostname() string {
  45. return t._url.Hostname()
  46. }
  47. // Host returns the host (host:port) of the URL.
  48. func (t *URL) Host() string {
  49. return t._url.Host
  50. }
  51. // Port returns the port of the URL, or the default for the protocol if not specified.
  52. func (t *URL) Port() string {
  53. if p := t._url.Port(); p != "" {
  54. return p
  55. }
  56. return portMap[t.Protocol()]
  57. }
  58. // Hash returns the hash of the URL without the #.
  59. func (t *URL) Hash() string {
  60. return strings.TrimPrefix(t._url.Fragment, "#")
  61. }
  62. // Search returns the search part of the URL without the ?.
  63. func (t *URL) Search() string {
  64. return strings.TrimPrefix(t._url.RawQuery, "?")
  65. }
  66. // Href returns the full URL.
  67. func (t *URL) Href() string {
  68. return t._url.String()
  69. }
  70. // Auth returns the username and password of the URL.
  71. func (t *URL) Auth() string {
  72. password := getPassword(t._url.User)
  73. username := t._url.User.Username()
  74. if username == "" && password == "" {
  75. return ""
  76. }
  77. return fmt.Sprintf("%s:%s", username, password)
  78. }
  79. // getPassword retrieves the password from a URL.User.
  80. func getPassword(user *url.Userinfo) string {
  81. if password, ok := user.Password(); ok {
  82. return password
  83. }
  84. return ""
  85. }
  86. // Parse constructs a new URL from a string.
  87. func ParseURL(urlStr string) (*URL, error) {
  88. return NewURL(urlStr)
  89. }
  90. // EncodeURL encodes a URL string.
  91. func EncodeURL(urlStr string) string {
  92. if urlStr == "" {
  93. return ""
  94. }
  95. strs := strings.Split(urlStr, "/")
  96. for i, v := range strs {
  97. strs[i] = url.QueryEscape(v)
  98. }
  99. urlStr = strings.Join(strs, "/")
  100. urlStr = strings.Replace(urlStr, "+", "%20", -1)
  101. urlStr = strings.Replace(urlStr, "*", "%2A", -1)
  102. urlStr = strings.Replace(urlStr, "%7E", "~", -1)
  103. return urlStr
  104. }
  105. // PercentEncode encodes a string for use in URLs, replacing certain characters.
  106. func PercentEncode(uri string) string {
  107. if uri == "" {
  108. return ""
  109. }
  110. uri = url.QueryEscape(uri)
  111. uri = strings.Replace(uri, "+", "%20", -1)
  112. uri = strings.Replace(uri, "*", "%2A", -1)
  113. uri = strings.Replace(uri, "%7E", "~", -1)
  114. return uri
  115. }
  116. // PathEncode encodes each segment of a path.
  117. func PathEncode(path string) string {
  118. if path == "" || path == "/" {
  119. return path
  120. }
  121. strs := strings.Split(path, "/")
  122. for i, v := range strs {
  123. strs[i] = url.QueryEscape(v)
  124. }
  125. path = strings.Join(strs, "/")
  126. path = strings.Replace(path, "+", "%20", -1)
  127. path = strings.Replace(path, "*", "%2A", -1)
  128. path = strings.Replace(path, "%7E", "~", -1)
  129. return path
  130. }