Revision 654ee915 services/keep-web/handler.go

View differences:

services/keep-web/handler.go
24 24
	"git.curoverse.com/arvados.git/sdk/go/health"
25 25
	"git.curoverse.com/arvados.git/sdk/go/httpserver"
26 26
	"git.curoverse.com/arvados.git/sdk/go/keepclient"
27
	"golang.org/x/net/webdav"
27 28
)
28 29

  
29 30
type handler struct {
......
31 32
	clientPool    *arvadosclient.ClientPool
32 33
	setupOnce     sync.Once
33 34
	healthHandler http.Handler
35
	webdavLS      webdav.LockSystem
34 36
}
35 37

  
36 38
// parseCollectionIDFromDNSName returns a UUID or PDH if s begins with
......
79 81
		Token:  h.Config.ManagementToken,
80 82
		Prefix: "/_health/",
81 83
	}
84

  
85
	h.webdavLS = webdav.NewMemLS()
82 86
}
83 87

  
84 88
func (h *handler) serveStatus(w http.ResponseWriter, r *http.Request) {
......
90 94
	json.NewEncoder(w).Encode(status)
91 95
}
92 96

  
97
var (
98
	webdavMethod = map[string]bool{
99
		"OPTIONS":  true,
100
		"PROPFIND": true,
101
		"LOCK":     true,
102
		"UNLOCK":   true,
103
	}
104
	fsMethod = map[string]bool{
105
		"GET":  true,
106
		"HEAD": true,
107
		"POST": true,
108
	}
109
)
110

  
93 111
// ServeHTTP implements http.Handler.
94 112
func (h *handler) ServeHTTP(wOrig http.ResponseWriter, r *http.Request) {
95 113
	h.setupOnce.Do(h.setup)
......
123 141
		return
124 142
	}
125 143

  
126
	if r.Method == "OPTIONS" {
127
		method := r.Header.Get("Access-Control-Request-Method")
128
		if method != "GET" && method != "POST" {
144
	if method := r.Header.Get("Access-Control-Request-Method"); method != "" && r.Method == "OPTIONS" {
145
		if !fsMethod[method] && !webdavMethod[method] {
129 146
			statusCode = http.StatusMethodNotAllowed
130 147
			return
131 148
		}
132 149
		w.Header().Set("Access-Control-Allow-Headers", "Range")
133
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST")
150
		w.Header().Set("Access-Control-Allow-Methods", "GET, POST, OPTIONS, PROPFIND, LOCK, UNLOCK")
134 151
		w.Header().Set("Access-Control-Allow-Origin", "*")
135 152
		w.Header().Set("Access-Control-Max-Age", "86400")
136 153
		statusCode = http.StatusOK
137 154
		return
138 155
	}
139 156

  
140
	if r.Method != "GET" && r.Method != "POST" {
157
	if !fsMethod[r.Method] && !webdavMethod[r.Method] {
141 158
		statusCode, statusText = http.StatusMethodNotAllowed, r.Method
142 159
		return
143 160
	}
......
337 354
		AuthToken: arv.ApiToken,
338 355
		Insecure:  arv.ApiInsecure,
339 356
	}, kc)
357
	if webdavMethod[r.Method] {
358
		h := webdav.Handler{
359
			Prefix:     "/" + strings.Join(pathParts[:stripParts], "/"),
360
			FileSystem: &webdavFS{httpfs: fs},
361
			LockSystem: h.webdavLS,
362
			Logger: func(_ *http.Request, err error) {
363
				if os.IsNotExist(err) {
364
					statusCode, statusText = http.StatusNotFound, err.Error()
365
				} else if err != nil {
366
					statusCode, statusText = http.StatusInternalServerError, err.Error()
367
				}
368
			},
369
		}
370
		h.ServeHTTP(w, r)
371
		return
372
	}
373

  
340 374
	openPath := "/" + strings.Join(targetPath, "/")
341 375
	if f, err := fs.Open(openPath); os.IsNotExist(err) {
342 376
		// Requested non-existent path

Also available in: Unified diff