util.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980
  1. package v4
  2. import (
  3. "net/url"
  4. "strings"
  5. )
  6. const doubleSpace = " "
  7. // StripExcessSpaces will rewrite the passed in slice's string values to not
  8. // contain multiple side-by-side spaces.
  9. func StripExcessSpaces(str string) string {
  10. var j, k, l, m, spaces int
  11. // Trim trailing spaces
  12. for j = len(str) - 1; j >= 0 && str[j] == ' '; j-- {
  13. }
  14. // Trim leading spaces
  15. for k = 0; k < j && str[k] == ' '; k++ {
  16. }
  17. str = str[k : j+1]
  18. // Strip multiple spaces.
  19. j = strings.Index(str, doubleSpace)
  20. if j < 0 {
  21. return str
  22. }
  23. buf := []byte(str)
  24. for k, m, l = j, j, len(buf); k < l; k++ {
  25. if buf[k] == ' ' {
  26. if spaces == 0 {
  27. // First space.
  28. buf[m] = buf[k]
  29. m++
  30. }
  31. spaces++
  32. } else {
  33. // End of multiple spaces.
  34. spaces = 0
  35. buf[m] = buf[k]
  36. m++
  37. }
  38. }
  39. return string(buf[:m])
  40. }
  41. // GetURIPath returns the escaped URI component from the provided URL.
  42. func GetURIPath(u *url.URL) string {
  43. var uriPath string
  44. if len(u.Opaque) > 0 {
  45. const schemeSep, pathSep, queryStart = "//", "/", "?"
  46. opaque := u.Opaque
  47. // Cut off the query string if present.
  48. if idx := strings.Index(opaque, queryStart); idx >= 0 {
  49. opaque = opaque[:idx]
  50. }
  51. // Cutout the scheme separator if present.
  52. if strings.Index(opaque, schemeSep) == 0 {
  53. opaque = opaque[len(schemeSep):]
  54. }
  55. // capture URI path starting with first path separator.
  56. if idx := strings.Index(opaque, pathSep); idx >= 0 {
  57. uriPath = opaque[idx:]
  58. }
  59. } else {
  60. uriPath = u.EscapedPath()
  61. }
  62. if len(uriPath) == 0 {
  63. uriPath = "/"
  64. }
  65. return uriPath
  66. }