github.com/zhongdalu/gf@v1.0.0/g/net/ghttp/ghttp_server_cookie.go (about) 1 // Copyright 2017 gf Author(https://github.com/zhongdalu/gf). 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/zhongdalu/gf. 6 // 7 // HTTP Cookie管理对象, 8 // 由于Cookie是和HTTP请求挂钩的,因此被包含到 ghttp 包中进行管理。 9 10 package ghttp 11 12 import ( 13 "github.com/zhongdalu/gf/g/os/gtime" 14 "net/http" 15 "time" 16 ) 17 18 // COOKIE对象 19 type Cookie struct { 20 data map[string]CookieItem // 数据项 21 path string // 默认的cookie path 22 domain string // 默认的cookie domain 23 maxage int // 默认的cookie maxage 24 server *Server // 所属Server 25 request *Request // 所属HTTP请求对象 26 response *Response // 所属HTTP返回对象 27 } 28 29 // cookie项 30 type CookieItem struct { 31 value string 32 domain string // 有效域名 33 path string // 有效路径 34 expire int // 过期时间 35 httpOnly bool 36 } 37 38 // 获取或者创建一个COOKIE对象,与传入的请求对应(延迟初始化) 39 func GetCookie(r *Request) *Cookie { 40 if r.Cookie != nil { 41 return r.Cookie 42 } 43 return &Cookie{ 44 request: r, 45 server: r.Server, 46 } 47 } 48 49 // 从请求流中初始化,无锁,延迟初始化 50 func (c *Cookie) init() { 51 if c.data == nil { 52 c.data = make(map[string]CookieItem) 53 c.path = c.request.Server.GetCookiePath() 54 c.domain = c.request.Server.GetCookieDomain() 55 c.maxage = c.request.Server.GetCookieMaxAge() 56 c.response = c.request.Response 57 // 如果没有设置COOKIE有效域名,那么设置HOST为默认有效域名 58 if c.domain == "" { 59 c.domain = c.request.GetHost() 60 } 61 for _, v := range c.request.Cookies() { 62 c.data[v.Name] = CookieItem{ 63 v.Value, v.Domain, v.Path, v.Expires.Second(), v.HttpOnly, 64 } 65 } 66 } 67 } 68 69 // 获取所有的Cookie并构造成map[string]string返回. 70 func (c *Cookie) Map() map[string]string { 71 c.init() 72 m := make(map[string]string) 73 for k, v := range c.data { 74 m[k] = v.value 75 } 76 return m 77 } 78 79 // 获取SessionId,不存在时则创建 80 func (c *Cookie) SessionId() string { 81 c.init() 82 id := c.Get(c.server.GetSessionIdName()) 83 if id == "" { 84 id = makeSessionId() 85 c.SetSessionId(id) 86 } 87 return id 88 } 89 90 // 获取SessionId,不存在时则创建 91 func (c *Cookie) MakeSessionId() string { 92 c.init() 93 id := makeSessionId() 94 c.SetSessionId(id) 95 return id 96 } 97 98 // 判断Cookie中是否存在制定键名(并且没有过期) 99 func (c *Cookie) Contains(key string) bool { 100 c.init() 101 if r, ok := c.data[key]; ok { 102 if r.expire >= 0 { 103 return true 104 } 105 } 106 return false 107 } 108 109 // 设置cookie,使用默认参数 110 func (c *Cookie) Set(key, value string) { 111 c.SetCookie(key, value, c.domain, c.path, c.server.GetCookieMaxAge()) 112 } 113 114 // 设置cookie,带详细cookie参数 115 func (c *Cookie) SetCookie(key, value, domain, path string, maxAge int, httpOnly ...bool) { 116 c.init() 117 isHttpOnly := false 118 if len(httpOnly) > 0 { 119 isHttpOnly = httpOnly[0] 120 } 121 c.data[key] = CookieItem{ 122 value, domain, path, int(gtime.Second()) + maxAge, isHttpOnly, 123 } 124 } 125 126 // 获得客户端提交的SessionId 127 func (c *Cookie) GetSessionId() string { 128 return c.Get(c.server.GetSessionIdName()) 129 } 130 131 // 设置SessionId 132 func (c *Cookie) SetSessionId(id string) { 133 c.Set(c.server.GetSessionIdName(), id) 134 } 135 136 // 查询cookie 137 func (c *Cookie) Get(key string, def ...string) string { 138 c.init() 139 if r, ok := c.data[key]; ok { 140 if r.expire >= 0 { 141 return r.value 142 } 143 } 144 if len(def) > 0 { 145 return def[0] 146 } 147 return "" 148 } 149 150 // 删除COOKIE,使用默认的domain&path 151 func (c *Cookie) Remove(key string) { 152 c.SetCookie(key, "", c.domain, c.path, -86400) 153 } 154 155 // 标记该cookie在对应的域名和路径失效 156 // 删除cookie的重点是需要通知浏览器客户端cookie已过期 157 func (c *Cookie) RemoveCookie(key, domain, path string) { 158 c.SetCookie(key, "", domain, path, -86400) 159 } 160 161 // 输出到客户端 162 func (c *Cookie) Output() { 163 if len(c.data) == 0 { 164 return 165 } 166 for k, v := range c.data { 167 // 只有 expire != 0 的才是服务端在本次请求中设置的cookie 168 if v.expire == 0 { 169 continue 170 } 171 http.SetCookie( 172 c.response.Writer, 173 &http.Cookie{ 174 Name: k, 175 Value: v.value, 176 Domain: v.domain, 177 Path: v.path, 178 Expires: time.Unix(int64(v.expire), 0), 179 HttpOnly: v.httpOnly, 180 }, 181 ) 182 } 183 }