-
-
Notifications
You must be signed in to change notification settings - Fork 65
/
dirserver.go
92 lines (80 loc) · 2.31 KB
/
dirserver.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
package chunktest
import (
"net/http"
"net/http/httptest"
"os"
"sync"
"github.com/rusq/slackdump/v3/internal/chunk"
)
// DirServer is a test server that serves files from a chunk.Directory.
type DirServer struct {
baseServer
cd *chunk.Directory
mu sync.Mutex
ptrs map[string]*chunk.Player
}
func NewDirServer(cd *chunk.Directory) *DirServer {
ds := &DirServer{
cd: cd,
ptrs: make(map[string]*chunk.Player),
}
ds.init()
return ds
}
func (s *DirServer) init() {
s.Server = httptest.NewServer(s.dirRouter())
}
func (s *DirServer) Close() {
s.Server.Close()
for _, p := range s.ptrs {
p.Close()
}
}
func (s *DirServer) dirRouter() *http.ServeMux {
mux := http.NewServeMux()
mux.Handle("/api/conversations.info", s.chunkWrapper(handleConversationsInfo))
mux.Handle("/api/conversations.history", s.chunkWrapper(handleConversationsHistory))
mux.Handle("/api/conversations.replies", s.chunkWrapper(handleConversationsReplies))
mux.Handle("/api/conversations.members", s.chunkWrapper(handleConversationsMembers))
mux.Handle("/api/conversations.list", s.chunkfileWrapper(chunk.FChannels, handleConversationsList))
mux.Handle("/api/users.list", s.chunkfileWrapper(chunk.FUsers, handleUsersList))
mux.Handle("/api/auth.test", s.chunkfileWrapper(chunk.FWorkspace, handleAuthTest))
return mux
}
func (s *DirServer) chunkWrapper(fn func(p *chunk.Player) http.HandlerFunc) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
channel := r.FormValue("channel")
if channel == "" {
http.Error(w, "no_channel", http.StatusBadRequest)
return
}
s.mu.Lock()
p, ok := s.ptrs[channel]
s.mu.Unlock()
id := chunk.ToFileID(channel, "", false)
if !ok {
cf, err := s.cd.Open(id)
if err != nil {
if os.IsNotExist(err) {
http.NotFound(w, r)
return
}
lg.Printf("error while opening chunk file for %s: %s", channel, err)
http.Error(w, http.StatusText(http.StatusUnprocessableEntity), http.StatusUnprocessableEntity)
return
}
p = chunk.NewPlayerFromFile(cf)
s.mu.Lock()
s.ptrs[channel] = p
s.mu.Unlock()
}
fn(p)(w, r)
})
}
func (s *DirServer) chunkfileWrapper(name chunk.FileID, fn func(p *chunk.Player) http.HandlerFunc) http.Handler {
rs, err := s.cd.Open(name)
if err != nil {
panic(err)
}
return fn(chunk.NewPlayerFromFile(rs))
}