Skip to content

Commit

Permalink
Return url for new file resources
Browse files Browse the repository at this point in the history
  • Loading branch information
felixge committed May 3, 2013
1 parent 3abd71b commit 18cffb2
Show file tree
Hide file tree
Showing 2 changed files with 36 additions and 14 deletions.
48 changes: 35 additions & 13 deletions src/http/handler.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import (
"io"
"net/http"
"os"
"path"
"strings"
)

Expand Down Expand Up @@ -38,16 +39,16 @@ func NewHandler(config HandlerConfig) (*Handler, error) {

return &Handler{
store: newDataStore(config.Dir, config.MaxSize),
basePath: config.BasePath,
config: config,
Error: errChan,
sendError: errChan,
}, nil
}

// Handler is a http.Handler that implements tus resumable upload protocol.
type Handler struct {
store *DataStore
basePath string
store *DataStore
config HandlerConfig

// Error provides error events for logging purposes.
Error <-chan error
Expand All @@ -56,30 +57,51 @@ type Handler struct {
}

func (h *Handler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
// Verify that url matches BasePath
absPath := r.URL.Path
if !strings.HasPrefix(absPath, h.basePath) {
err := errors.New("invalid url path: " + absPath + " - does not match basePath: " + h.basePath)
if !strings.HasPrefix(absPath, h.config.BasePath) {
err := errors.New("unknown url: " + absPath + " - does not match BasePath: " + h.config.BasePath)
h.err(err, w, http.StatusNotFound)
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 == "/" {
// Must use POST method according to tus protocol
if r.Method != "POST" {
w.Header().Set("Allow", "POST")
err := errors.New(r.Method + " used against file creation url. Only POST is allowed.")
h.err(err, w, http.StatusMethodNotAllowed)
if r.Method == "POST" {
h.createFile(w, r)
return
}

// handle invalid method
w.Header().Set("Allow", "POST")
err := errors.New(r.Method + " used against file creation url. Only POST is allowed.")
h.err(err, w, http.StatusMethodNotAllowed)
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)
}

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.
func (h *Handler) err(err error, w http.ResponseWriter, status int) {
w.WriteHeader(status)
Expand Down
2 changes: 1 addition & 1 deletion src/cmd/tusd/uid.go → src/http/uid.go
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
package main
package http

import (
"crypto/rand"
Expand Down

0 comments on commit 18cffb2

Please sign in to comment.