-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcookies.go
173 lines (149 loc) · 3.4 KB
/
cookies.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
package main
import (
"encoding/gob"
"encoding/json"
"fmt"
"net/http"
"net/url"
"os"
)
type CookieJarType int8
const (
JarMemory CookieJarType = iota
JarJson
JarGob
)
// JarOption used to configure how cookies data saved
//
type JarOption struct {
// JarType specify the which way used to save the cookies
// JarMemory : just in memory without persist
// JarGob: persist by module encoding/gob
JarType CookieJarType
// Filename holds the file to use for storage of the cookies.
// If it is empty, JarMemory will be used.
Filename string
}
// SimpleJar implement http.CookieJar to handle cookies
//
type SimpleJar struct {
filename string
jarType CookieJarType
cookies []*http.Cookie
}
// NewSimpleJar return SimpleJar object with sepecified option
// example:
// jar := NewSimpleJar(JarOption{
// JarType: JarMemory,
// Filename: "d:\\cookies.jar",
// })
//
func NewSimpleJar(option JarOption) *SimpleJar {
if option.Filename == "" {
option.JarType = JarMemory
}
return &SimpleJar{
filename: option.Filename,
jarType: option.JarType,
cookies: make([]*http.Cookie, 0, 10),
}
}
// SetCookies handles the receipt of the cookies in a reply for the
// given URL. It may or may not choose to save the cookies, depending
// on the jar's policy and implementation.
//
func (jar *SimpleJar) SetCookies(u *url.URL, cookies []*http.Cookie) {
if cookies == nil || len(cookies) == 0 {
return
}
for _, newone := range cookies {
var cookie *http.Cookie
for _, old := range jar.cookies {
if newone.Name == old.Name {
cookie = old
break
}
}
if cookie == nil {
cookie = new(http.Cookie)
jar.cookies = append(jar.cookies, cookie)
}
*cookie = *newone
}
}
// Cookies returns the cookies to send in a request for the given URL.
// It is up to the implementation to honor the standard cookie use
// restrictions such as in RFC 6265.
//
func (jar *SimpleJar) Cookies(u *url.URL) []*http.Cookie {
s := len(jar.cookies)
return jar.cookies[0:s]
}
// Load used to deserialization cookies data from file
//
func (jar *SimpleJar) Load() error {
switch jar.jarType {
case JarGob:
fd, err := os.Open(jar.filename)
if err == nil {
err = gob.NewDecoder(fd).Decode(&jar.cookies)
} else if os.IsNotExist(err) {
err = nil
}
return err
case JarJson:
fd, err := os.Open(jar.filename)
if err == nil {
err = json.NewDecoder(fd).Decode(&jar.cookies)
} else if os.IsNotExist(err) {
err = nil
}
return err
case JarMemory:
return nil
default:
return fmt.Errorf("jar type %d not implement yet", jar.jarType)
}
}
// Persist used to serialization cookies data into file
//
func (jar *SimpleJar) Persist() error {
if len(jar.cookies) == 0 {
return nil
}
switch jar.jarType {
case JarGob:
fd, err := os.Create(jar.filename)
if err == nil {
err = gob.NewEncoder(fd).Encode(jar.cookies)
}
return err
case JarJson:
fd, err := os.Create(jar.filename)
if err == nil {
enc := json.NewEncoder(fd)
enc.SetIndent("", " ")
err = enc.Encode(jar.cookies)
}
return err
case JarMemory:
return nil
default:
return fmt.Errorf("jar type %d not implement yet", jar.jarType)
}
}
// Clean cookies if not valid anymore
//
func (jar *SimpleJar) Clean() {
jar.cookies = jar.cookies[0:0]
}
// Get cookie vlue by name
//
func (jar *SimpleJar) Get(name string) string {
for _, v := range jar.cookies {
if v.Name == name {
return v.Value
}
}
return ""
}