This repository was archived by the owner on Dec 3, 2022. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathconnection.go
More file actions
executable file
·112 lines (91 loc) · 2.34 KB
/
connection.go
File metadata and controls
executable file
·112 lines (91 loc) · 2.34 KB
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
// connection
package rets
import (
"errors"
"github.com/edmore/goca/auth"
"github.com/mlapping/rets/results"
"net/http"
"net/http/cookiejar"
"net/url"
)
type Session struct {
DialInfo *DialInfo
HttpClient *http.Client
BaseAddress string
LoggedIn bool
Capabilities Capabilities
Authorization string
}
type DialInfo struct {
LoginUrl string
UserName string
Password string
}
func DialWithInfo(info *DialInfo) (*Session, error) {
err := info.validateDialInfo()
if err != nil {
return nil, err
}
// create a new session
session := &Session{}
session.DialInfo = info
// start setting up the capabilities early
loginUrl, err := url.Parse(session.DialInfo.LoginUrl)
if err != nil {
return nil, err
}
session.Capabilities = Capabilities{
Host: loginUrl.Scheme + "://" + loginUrl.Host,
}
// create an http connection with a cookiejar
cookieJar, _ := cookiejar.New(nil)
session.HttpClient = &http.Client{
Jar: cookieJar,
}
// login, set server capabilities
err = session.tryToLogin()
if err != nil {
return nil, err
}
// Login was successful
return session, nil
}
func (sess *Session) tryToLogin() error {
// The first GET will fail, but set our cookie jar
req, err := sess.newRequest("GET", sess.DialInfo.LoginUrl, nil)
if err != nil {
return err
}
// The first GET will fail, but set our cookie jar
res, _ := sess.HttpClient.Do(req)
// The second GET will SHOULD not fail
req, err = sess.newRequest("GET", sess.DialInfo.LoginUrl, nil)
// set our digest auth
req = auth.SetDigestAuth(req, sess.DialInfo.UserName, sess.DialInfo.Password, res, 1)
res, err = sess.HttpClient.Do(req)
if res.StatusCode != http.StatusOK {
return errors.New("login failed: " + err.Error())
}
// grab the authorization string
sess.Authorization = req.Header.Get("Authorization")
// convert the response to a RetsReply Object
retsReply := &results.LoginReply{}
err = results.ConvertServerResponse(res.Body, retsReply)
if err != nil {
return err
}
// setup our capabilities
return sess.Capabilities.setFromLogin(retsReply)
}
func (dial *DialInfo) validateDialInfo() error {
if dial == nil {
return errors.New("passed a nil DialInfo object")
}
if len(dial.Password) == 0 {
return errors.New("passed a blank password")
}
if len(dial.UserName) == 0 {
return errors.New("passed a blank username")
}
return nil
}