Return url for new file resources
This commit is contained in:
parent
3abd71b6c0
commit
18cffb2b03
|
@ -5,6 +5,7 @@ import (
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
"os"
|
"os"
|
||||||
|
"path"
|
||||||
"strings"
|
"strings"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
@ -38,7 +39,7 @@ func NewHandler(config HandlerConfig) (*Handler, error) {
|
||||||
|
|
||||||
return &Handler{
|
return &Handler{
|
||||||
store: newDataStore(config.Dir, config.MaxSize),
|
store: newDataStore(config.Dir, config.MaxSize),
|
||||||
basePath: config.BasePath,
|
config: config,
|
||||||
Error: errChan,
|
Error: errChan,
|
||||||
sendError: errChan,
|
sendError: errChan,
|
||||||
}, nil
|
}, nil
|
||||||
|
@ -47,7 +48,7 @@ func NewHandler(config HandlerConfig) (*Handler, error) {
|
||||||
// Handler is a http.Handler that implements tus resumable upload protocol.
|
// Handler is a http.Handler that implements tus resumable upload protocol.
|
||||||
type Handler struct {
|
type Handler struct {
|
||||||
store *DataStore
|
store *DataStore
|
||||||
basePath string
|
config HandlerConfig
|
||||||
|
|
||||||
// Error provides error events for logging purposes.
|
// Error provides error events for logging purposes.
|
||||||
Error <-chan error
|
Error <-chan error
|
||||||
|
@ -56,30 +57,51 @@ type Handler struct {
|
||||||
}
|
}
|
||||||
|
|
||||||
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
||||||
|
// Verify that url matches BasePath
|
||||||
absPath := r.URL.Path
|
absPath := r.URL.Path
|
||||||
if !strings.HasPrefix(absPath, h.basePath) {
|
if !strings.HasPrefix(absPath, h.config.BasePath) {
|
||||||
err := errors.New("invalid url path: " + absPath + " - does not match basePath: " + h.basePath)
|
err := errors.New("unknown url: " + absPath + " - does not match BasePath: " + h.config.BasePath)
|
||||||
h.err(err, w, http.StatusNotFound)
|
h.err(err, w, http.StatusNotFound)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
relPath := absPath[len(h.basePath)-1:]
|
// example relPath results: "/", "/f81d4fae7dec11d0a765-00a0c91e6bf6", etc.
|
||||||
|
relPath := absPath[len(h.config.BasePath)-1:]
|
||||||
|
|
||||||
// File creation request
|
// file creation request
|
||||||
if relPath == "/" {
|
if relPath == "/" {
|
||||||
// Must use POST method according to tus protocol
|
if r.Method == "POST" {
|
||||||
if r.Method != "POST" {
|
h.createFile(w, r)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// handle invalid method
|
||||||
w.Header().Set("Allow", "POST")
|
w.Header().Set("Allow", "POST")
|
||||||
err := errors.New(r.Method + " used against file creation url. Only POST is allowed.")
|
err := errors.New(r.Method + " used against file creation url. Only POST is allowed.")
|
||||||
h.err(err, w, http.StatusMethodNotAllowed)
|
h.err(err, w, http.StatusMethodNotAllowed)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
err := errors.New("invalid url path: " + absPath + " - does not match file pattern")
|
// handle unknown url
|
||||||
|
err := errors.New("unknown url: " + absPath + " - does not match file pattern")
|
||||||
h.err(err, w, http.StatusNotFound)
|
h.err(err, w, http.StatusNotFound)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (h *Handler) createFile(w http.ResponseWriter, r *http.Request) {
|
||||||
|
id := uid()
|
||||||
|
w.Header().Set("Location", h.absUrl(r, "/"+id))
|
||||||
|
}
|
||||||
|
|
||||||
|
// absUrl turn a relPath (e.g. "/foo") into an absolute url (e.g.
|
||||||
|
// "http://example.com/foo").
|
||||||
|
//
|
||||||
|
// @TODO: Look at r.TLS to determine the url scheme.
|
||||||
|
// @TODO: Make url prefix user configurable (optional) to deal with reverse
|
||||||
|
// proxies.
|
||||||
|
func (h *Handler) absUrl(r *http.Request, relPath string) string {
|
||||||
|
return "http://" + r.Host + path.Clean(h.config.BasePath+relPath)
|
||||||
|
}
|
||||||
|
|
||||||
// err sends a http error response and publishes to the Error channel.
|
// err sends a http error response and publishes to the Error channel.
|
||||||
func (h *Handler) err(err error, w http.ResponseWriter, status int) {
|
func (h *Handler) err(err error, w http.ResponseWriter, status int) {
|
||||||
w.WriteHeader(status)
|
w.WriteHeader(status)
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
package main
|
package http
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"crypto/rand"
|
"crypto/rand"
|
Loading…
Reference in New Issue