我最近从C#迁移并希望创建一些旧的应用程序。因此,我需要找到一种方法来管理Go Web请求中的会话。我找到了这个代码形式的解决方案:
// Jar is session object struct - cookie jar including mutex for syncing
type Jar struct {
sync.Mutex
cookies map[string][]*http.Cookie
}
// NewJar is a function for creating cookie jar for use
func NewJar() *Jar {
jar := new(Jar)
jar.cookies = make(map[string][]*http.Cookie)
return jar
}
// SetCookies sets the cookies for the jar
func (jar *Jar) SetCookies(u *url.URL, cookies []*http.Cookie) {
jar.Lock()
if _, ok := jar.cookies[u.Host]; ok {
for _, c := range cookies {
jar.cookies[u.Host] = append(jar.cookies[u.Host], c)
}
} else {
jar.cookies[u.Host] = cookies
}
jar.Unlock()
}
// Cookies returns cookies for each host
func (jar *Jar) Cookies(u *url.URL) []*http.Cookie {
return jar.cookies[u.Host]
}
// NewJarClient creates new client, utilising a NewJar()
func NewJarClient() *http.Client {
proxyURL, _ := url.Parse("http://127.0.0.1:8888")
tr := &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
Proxy: http.ProxyURL(proxyURL),
}
return &http.Client{
Jar: NewJar(),
Transport: tr,
}
}
我遇到的问题是了解它是如何工作的。我创建了一个客户端,执行以下操作
client := NewJarClient()
但是当我发布使用它的网络功能(例如获取请求)时,cookie会自动继续运行,并且一切都按计划运行。问题是我不知道为什么。我没有看到像一个或一个SetCookies
一个被调用的方法,它似乎只是通过神奇地运行函数来处理每个方法。有人可以逐行或以某种方式注释或解释给定的方法,以便他们能够更好地理解我从C#背景中走过来。谢谢:)
答案 0 :(得分:0)
NewJar
分配并返回类型*Jar
的新实例,现在键入*Jar
,由于其上定义的方法,隐式实现了名为CookieJar
的接口。
http.Client
类型有一个名为Jar
的字段,其定义为CookieJar
类型,这意味着您可以将http.Client.Jar
设置为实现CookieJar
的任何内容1}}接口,包括*Jar
类型。 NewJarClient
函数返回一个新的*http.Client
实例,其Jar
字段设置为*Jar
返回的NewJar
实例。
这允许返回的客户端值使用*Jar
的方法而不知道它是*Jar
,它只知道其Jar
中的值field具有与CookieJar
接口定义的方法相同的方法集。
因此http.Client
实例在发送请求时,通过调用提供参数和处理返回值的方法来使用*Jar
。客户使用*Jar
的方式是http.Client
类型的实施细节,您不必担心这一点。您只需确保实现CookieJar
接口的方法执行您希望它们执行的操作,调用它们的方式和时间取决于客户端。
但是,如果您对客户端的实施细节感兴趣,可以查看http.Client的源文件。
答案 1 :(得分:0)
由于一些过时的博客文章形式的错误信息,我的印象是我无法在请求中维护cookie - 出于某种奇怪的原因。考虑到这一点,我研究并研究了创建我自己的实现,可以在上面看到。引起我注意的是,我的实现完全破坏和存在缺陷,标准的http库本身可以完美地处理维护cookie,只需在创建客户端时包含Jar
的值即可。例如:
jar, _ := cookiejar.New(nil)
proxyURL, _ := url.Parse("http://127.0.0.1:8888")
tr := &http.Transport{
MaxIdleConns: 10,
IdleConnTimeout: 30 * time.Second,
DisableCompression: true,
Proxy: http.ProxyURL(proxyURL),
}
c := &http.Client{
Jar: jar,
Transport: tr,
}