-
Notifications
You must be signed in to change notification settings - Fork 24
/
Copy pathconfig.go
127 lines (115 loc) · 3.13 KB
/
config.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
package proxy
import (
"context"
"fmt"
"io"
"log"
"github.com/jpfielding/gorets/pkg/rets"
"github.com/jpfielding/gowirelog/wirelog"
"golang.org/x/net/proxy"
)
// Config sets up a connection
type Config struct {
Service string
URL string
User, Password string
UserAgent, UserAgentPassword string
Version string
Proxy string
}
// Sources is a indexer for looking up sessions
type Sources map[string]Sessions
// NewSources creates the index for sessions/users
func NewSources(cfgs []Config) Sources {
srcs := Sources{}
for _, c := range cfgs {
if _, ok := srcs[c.Service]; !ok {
srcs[c.Service] = Sessions{}
}
srcs[c.Service][c.User] = Session{config: c}
}
return srcs
}
// Sessions a wrapper to manage requests
type Sessions map[string]Session
// Session holds the state for an established session
type Session struct {
config Config
requester rets.Requester
urls *rets.CapabilityURLs
closer io.Closer // holds the wirelog output
}
// Clear the current session
func (l *Session) Clear() {
if l.requester == nil {
return
}
ctx := context.Background()
req := rets.LogoutRequest{URL: l.urls.Logout}
rets.Logout(ctx, l.requester, req)
if l.closer != nil {
l.closer.Close()
}
l.requester = nil
}
// Get returns the cached rets session
func (l *Session) Get() (rets.Requester, *rets.CapabilityURLs, error) {
if l.requester == nil {
req, closer, urls, err := l.create()
if err != nil {
return nil, nil, fmt.Errorf("rets session create")
}
l.requester = req
l.urls = urls
l.closer = closer
}
return l.requester, l.urls, nil
}
func (l *Session) create() (rets.Requester, io.Closer, *rets.CapabilityURLs, error) {
// should we throw an err here too?
session, closer, err := NewSession(l.config)
if err != nil {
return nil, nil, nil, fmt.Errorf("rets session setup")
}
// login and get our urls
req := rets.LoginRequest{URL: l.config.URL}
ctx := context.Background()
capability, err := rets.Login(ctx, session, req)
if err != nil {
return nil, nil, nil, fmt.Errorf("rets session login")
}
return session, closer, capability, nil
}
// NewSession creates a Rets session from the given config
func NewSession(c Config) (rets.Requester, io.Closer, error) {
// start with the default Dialer from http.DefaultTransport
transport := wirelog.NewHTTPTransport()
// if there is a need to proxy
if c.Proxy != "" {
log.Printf("Using proxy %s", c.Proxy)
d, err := proxy.SOCKS5("tcp", c.Proxy, nil, proxy.Direct)
if err != nil {
return nil, nil, fmt.Errorf("rets proxy: '%s'", c.Proxy)
}
transport.Dial = d.Dial
}
var closer io.Closer
var err error
// wire logging
logFile := fmt.Sprintf("/tmp/rets/wirelog/%s-%s.log", c.Service, c.User)
closer, err = wirelog.LogToFile(transport, logFile, true, true)
if err != nil {
return nil, nil, fmt.Errorf("wirelog setup")
}
log.Printf("wire logging enabled %s", logFile)
// should we throw an err here too?
sess, err := rets.DefaultSession(
c.User,
c.Password,
c.UserAgent,
c.UserAgentPassword,
c.Version,
transport,
)
return sess, closer, err
}