uribuilder.go 3.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114
  1. package uri
  2. import (
  3. "net/url"
  4. "strconv"
  5. "strings"
  6. "time"
  7. "github.com/kataras/iris/cache/cfg"
  8. )
  9. // URIBuilder is the requested url builder
  10. // which keeps all the information the server
  11. // should know to save or retrieve a cached entry's response
  12. // used on client-side only
  13. // both from net/http and valyala/fasthttp
  14. type URIBuilder struct {
  15. serverAddr,
  16. clientMethod,
  17. clientURI string
  18. cacheLifetime time.Duration
  19. cacheStatuscode int
  20. cacheContentType string
  21. }
  22. // ServerAddr sets the server address for the final request url
  23. func (r *URIBuilder) ServerAddr(s string) *URIBuilder {
  24. r.serverAddr = s
  25. return r
  26. }
  27. // ClientMethod sets the method which the client should call the remote server's handler
  28. // used to build the final request url too
  29. func (r *URIBuilder) ClientMethod(s string) *URIBuilder {
  30. r.clientMethod = s
  31. return r
  32. }
  33. // ClientURI sets the client path for the final request url
  34. func (r *URIBuilder) ClientURI(s string) *URIBuilder {
  35. r.clientURI = s
  36. return r
  37. }
  38. // Lifetime sets the cache lifetime for the final request url
  39. func (r *URIBuilder) Lifetime(d time.Duration) *URIBuilder {
  40. r.cacheLifetime = d
  41. return r
  42. }
  43. // StatusCode sets the cache status code for the final request url
  44. func (r *URIBuilder) StatusCode(code int) *URIBuilder {
  45. r.cacheStatuscode = code
  46. return r
  47. }
  48. // ContentType sets the cache content type for the final request url
  49. func (r *URIBuilder) ContentType(s string) *URIBuilder {
  50. r.cacheContentType = s
  51. return r
  52. }
  53. // String returns the full url which should be passed to get a cache entry response back
  54. // (it could be setted by server too but we need some client-freedom on the requested key)
  55. // in order to be sure that the registered cache entries are unique among different clients with the same key
  56. // note1: we do it manually*,
  57. // note2: on fasthttp that is not required because the query args added as expected but we will use it there too to be align with net/http
  58. func (r URIBuilder) String() string {
  59. return r.build()
  60. }
  61. func (r URIBuilder) build() string {
  62. remoteURL := r.serverAddr
  63. // fasthttp appends the "/" in the last uri (with query args also, that's probably a fasthttp bug which I'll fix later)
  64. // for now lets make that check:
  65. if !strings.HasSuffix(remoteURL, "/") {
  66. remoteURL += "/"
  67. }
  68. scheme := "http://"
  69. // validate the remoteURL, should contains a scheme, if not then check if the client has given a scheme and if so
  70. // use that for the server too
  71. if !strings.Contains(remoteURL, "://") {
  72. if strings.Contains(remoteURL, ":443") || strings.Contains(remoteURL, ":https") {
  73. remoteURL = "https://" + remoteURL
  74. } else {
  75. remoteURL = scheme + "://" + remoteURL
  76. }
  77. }
  78. var cacheDurationStr, statusCodeStr string
  79. if r.cacheLifetime.Seconds() > 0 {
  80. cacheDurationStr = strconv.Itoa(int(r.cacheLifetime.Seconds()))
  81. }
  82. if r.cacheStatuscode > 0 {
  83. statusCodeStr = strconv.Itoa(r.cacheStatuscode)
  84. }
  85. s := remoteURL + "?" + cfg.QueryCacheKey + "=" + url.QueryEscape(r.clientMethod+scheme+r.clientURI)
  86. if cacheDurationStr != "" {
  87. s += "&" + cfg.QueryCacheDuration + "=" + url.QueryEscape(cacheDurationStr)
  88. }
  89. if statusCodeStr != "" {
  90. s += "&" + cfg.QueryCacheStatusCode + "=" + url.QueryEscape(statusCodeStr)
  91. }
  92. if r.cacheContentType != "" {
  93. s += "&" + cfg.QueryCacheContentType + "=" + url.QueryEscape(r.cacheContentType)
  94. }
  95. return s
  96. }