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