github.com/gogf/gf@v1.16.9/net/ghttp/ghttp_server_cookie.go (about) 1 // Copyright GoFrame Author(https://goframe.org). All Rights Reserved. 2 // 3 // This Source Code Form is subject to the terms of the MIT License. 4 // If a copy of the MIT was not distributed with this file, 5 // You can obtain one at https://github.com/gogf/gf. 6 7 package ghttp 8 9 import ( 10 "net/http" 11 "time" 12 ) 13 14 // Cookie for HTTP COOKIE management. 15 type Cookie struct { 16 data map[string]*cookieItem // Underlying cookie items. 17 server *Server // Belonged HTTP server 18 request *Request // Belonged HTTP request. 19 response *Response // Belonged HTTP response. 20 } 21 22 // cookieItem is the item stored in Cookie. 23 type cookieItem struct { 24 *http.Cookie // Underlying cookie items. 25 FromClient bool // Mark this cookie received from client. 26 } 27 28 // GetCookie creates or retrieves a cookie object with given request. 29 // It retrieves and returns an existing cookie object if it already exists with given request. 30 // It creates and returns a new cookie object if it does not exist with given request. 31 func GetCookie(r *Request) *Cookie { 32 if r.Cookie != nil { 33 return r.Cookie 34 } 35 return &Cookie{ 36 request: r, 37 server: r.Server, 38 } 39 } 40 41 // init does lazy initialization for cookie object. 42 func (c *Cookie) init() { 43 if c.data != nil { 44 return 45 } 46 c.data = make(map[string]*cookieItem) 47 c.response = c.request.Response 48 // DO NOT ADD ANY DEFAULT COOKIE DOMAIN! 49 //if c.request.Server.GetCookieDomain() == "" { 50 // c.request.Server.GetCookieDomain() = c.request.GetHost() 51 //} 52 for _, v := range c.request.Cookies() { 53 c.data[v.Name] = &cookieItem{ 54 Cookie: v, 55 FromClient: true, 56 } 57 } 58 } 59 60 // Map returns the cookie items as map[string]string. 61 func (c *Cookie) Map() map[string]string { 62 c.init() 63 m := make(map[string]string) 64 for k, v := range c.data { 65 m[k] = v.Value 66 } 67 return m 68 } 69 70 // Contains checks if given key exists and not expired in cookie. 71 func (c *Cookie) Contains(key string) bool { 72 c.init() 73 if r, ok := c.data[key]; ok { 74 if r.Expires.IsZero() || r.Expires.After(time.Now()) { 75 return true 76 } 77 } 78 return false 79 } 80 81 // Set sets cookie item with default domain, path and expiration age. 82 func (c *Cookie) Set(key, value string) { 83 c.SetCookie( 84 key, 85 value, 86 c.request.Server.GetCookieDomain(), 87 c.request.Server.GetCookiePath(), 88 c.request.Server.GetCookieMaxAge(), 89 ) 90 } 91 92 // SetCookie sets cookie item given given domain, path and expiration age. 93 // The optional parameter <httpOnly> specifies if the cookie item is only available in HTTP, 94 // which is usually empty. 95 func (c *Cookie) SetCookie(key, value, domain, path string, maxAge time.Duration, httpOnly ...bool) { 96 c.init() 97 isHttpOnly := false 98 if len(httpOnly) > 0 { 99 isHttpOnly = httpOnly[0] 100 } 101 httpCookie := &http.Cookie{ 102 Name: key, 103 Value: value, 104 Path: path, 105 Domain: domain, 106 HttpOnly: isHttpOnly, 107 } 108 if maxAge != 0 { 109 httpCookie.Expires = time.Now().Add(maxAge) 110 } 111 c.data[key] = &cookieItem{ 112 Cookie: httpCookie, 113 } 114 } 115 116 // SetHttpCookie sets cookie with *http.Cookie. 117 func (c *Cookie) SetHttpCookie(httpCookie *http.Cookie) { 118 c.init() 119 c.data[httpCookie.Name] = &cookieItem{ 120 Cookie: httpCookie, 121 } 122 } 123 124 // GetSessionId retrieves and returns the session id from cookie. 125 func (c *Cookie) GetSessionId() string { 126 return c.Get(c.server.GetSessionIdName()) 127 } 128 129 // SetSessionId sets session id in the cookie. 130 func (c *Cookie) SetSessionId(id string) { 131 c.SetCookie( 132 c.server.GetSessionIdName(), 133 id, 134 c.request.Server.GetCookieDomain(), 135 c.request.Server.GetCookiePath(), 136 c.server.GetSessionCookieMaxAge(), 137 ) 138 } 139 140 // Get retrieves and returns the value with specified key. 141 // It returns <def> if specified key does not exist and <def> is given. 142 func (c *Cookie) Get(key string, def ...string) string { 143 c.init() 144 if r, ok := c.data[key]; ok { 145 if r.Expires.IsZero() || r.Expires.After(time.Now()) { 146 return r.Value 147 } 148 } 149 if len(def) > 0 { 150 return def[0] 151 } 152 return "" 153 } 154 155 // Remove deletes specified key and its value from cookie using default domain and path. 156 // It actually tells the http client that the cookie is expired, do not send it to server next time. 157 func (c *Cookie) Remove(key string) { 158 c.SetCookie( 159 key, 160 "", 161 c.request.Server.GetCookieDomain(), 162 c.request.Server.GetCookiePath(), 163 -24*time.Hour, 164 ) 165 } 166 167 // RemoveCookie deletes specified key and its value from cookie using given domain and path. 168 // It actually tells the http client that the cookie is expired, do not send it to server next time. 169 func (c *Cookie) RemoveCookie(key, domain, path string) { 170 c.SetCookie(key, "", domain, path, -24*time.Hour) 171 } 172 173 // Flush outputs the cookie items to client. 174 func (c *Cookie) Flush() { 175 if len(c.data) == 0 { 176 return 177 } 178 for _, v := range c.data { 179 if v.FromClient { 180 continue 181 } 182 http.SetCookie(c.response.Writer, v.Cookie) 183 } 184 }