-
-
Notifications
You must be signed in to change notification settings - Fork 9
/
handler.go
114 lines (97 loc) · 2.71 KB
/
handler.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
package purge
import (
"encoding/json"
"net/http"
"net/url"
"os"
"golang.org/x/net/context"
"github.com/ironsmile/nedomi/config"
"github.com/ironsmile/nedomi/contexts"
"github.com/ironsmile/nedomi/types"
"github.com/ironsmile/nedomi/utils/httputils"
)
// Handler is a simple handler that handles the server purge page.
type Handler struct {
logger types.Logger
}
type purgeRequest config.StringSlice
type purgeResult map[string]bool
// RequestHandle servers the purge page.
func (ph *Handler) RequestHandle(ctx context.Context, w http.ResponseWriter, r *http.Request) {
reqID, _ := contexts.GetRequestID(ctx)
//!TODO authentication
if r.Method != "POST" {
httputils.Error(w, http.StatusMethodNotAllowed)
return
}
var pr = new(purgeRequest)
if err := json.NewDecoder(r.Body).Decode(pr); err != nil {
http.Error(w, err.Error(), http.StatusBadRequest)
ph.logger.Errorf("[%s] error on parsing request %s",
reqID, err)
return
}
var app, ok = contexts.GetApp(ctx)
if !ok {
httputils.Error(w, http.StatusInternalServerError)
ph.logger.Errorf("[%s] no app in context", reqID)
return
}
var res, err = ph.purgeAll(reqID, app, *pr)
if err != nil {
httputils.Error(w, http.StatusInternalServerError)
// previosly logged
return
}
if err := json.NewEncoder(w).Encode(res); err != nil {
ph.logger.Errorf("[%s] error while encoding response %s",
reqID, err)
}
}
func (ph *Handler) purgeAll(reqID types.RequestID, app types.App, pr purgeRequest) (purgeResult, error) {
var pres = purgeResult(make(map[string]bool))
for _, uString := range pr {
pres[uString] = false
var u, err = url.Parse(uString)
if err != nil {
continue
}
var location = app.GetLocationFor(u.Host, u.Path)
if location == nil {
ph.logger.Logf(
"[%s] got request to purge an object (%s) that is for a not configured location",
reqID, uString)
continue
}
var oid = location.NewObjectIDForURL(u)
parts, err := location.Cache.Storage.GetAvailableParts(oid)
if err != nil {
if !os.IsNotExist(err) {
ph.logger.Errorf(
"[%s] got error while gettings parts of object '%s' - %s",
reqID, oid, err)
return nil, err
}
}
if len(parts) == 0 {
continue
}
if err = location.Cache.Storage.Discard(oid); err != nil {
if !os.IsNotExist(err) {
ph.logger.Errorf(
"[%s] got error while purging object '%s' - %s",
reqID, oid, err)
return nil, err
}
}
location.Cache.Algorithm.Remove(parts...)
pres[uString] = err == nil // err is os.ErrNotExist
}
return pres, nil
}
// New creates and returns a ready to used ServerPurgeHandler.
func New(cfg *config.Handler, l *types.Location, next types.RequestHandler) (*Handler, error) {
return &Handler{
logger: l.Logger,
}, nil
}