Browse Source

upload expiry/barename respect, random fixes

pull/12/head
andreimarcu 9 years ago
parent
commit
c32a698cbc
  1. 4
      display.go
  2. 10
      expiry.go
  3. 28
      fileserve.go
  4. 1
      meta.go
  5. 4
      server.go
  6. 20
      templates/index.html
  7. 95
      upload.go

4
display.go

@ -22,13 +22,11 @@ func fileDisplayHandler(c web.C, w http.ResponseWriter, r *http.Request) {
filePath := path.Join(Config.filesDir, fileName)
fileInfo, err := os.Stat(filePath)
if os.IsNotExist(err) {
if !fileExistsAndNotExpired(fileName) {
notFoundHandler(c, w, r)
return
}
// file expiry checking
if err := magicmime.Open(magicmime.MAGIC_MIME_TYPE |
magicmime.MAGIC_SYMLINK |
magicmime.MAGIC_ERROR); err != nil {

10
expiry.go

@ -33,12 +33,8 @@ func isTsExpired(ts int32) (expired bool) {
}
// Determine if the given filename is expired
func isFileExpired(filename string) (bool, error) {
exp, err := metadataGetExpiry(filename)
func isFileExpired(filename string) bool {
exp, _ := metadataGetExpiry(filename)
if err != nil {
return true, err
} else {
return isTsExpired(exp), err
}
return isTsExpired(exp)
}

28
fileserve.go

@ -11,24 +11,28 @@ import (
func fileServeHandler(c web.C, w http.ResponseWriter, r *http.Request) {
fileName := c.URLParams["name"]
filePath := path.Join(Config.filesDir, fileName)
_, err := os.Stat(filePath)
if os.IsNotExist(err) {
if isFileExpired(fileName) {
notFoundHandler(c, w, r)
return
}
expired, expErr := isFileExpired(fileName)
http.ServeFile(w, r, filePath)
}
if expErr != nil {
// Error reading metadata, pretend it's expired
notFoundHandler(c, w, r)
// TODO log error internally
return
} else if expired {
notFoundHandler(c, w, r)
// TODO delete the file
func fileExistsAndNotExpired(filename string) bool {
filePath := path.Join(Config.filesDir, filename)
_, err := os.Stat(filePath)
if err != nil {
return false
}
http.ServeFile(w, r, filePath)
if isFileExpired(filename) {
os.Remove(path.Join(Config.filesDir, filename))
os.Remove(path.Join(Config.metaDir, filename))
return false
}
return true
}

1
meta.go

@ -24,7 +24,6 @@ func metadataWrite(filename string, upload *Upload) error {
fmt.Fprintln(w, upload.Expiry)
fmt.Fprintln(w, upload.DeleteKey)
fmt.Fprintln(w, upload.DebugInfo)
return w.Flush()
}

4
server.go

@ -47,13 +47,13 @@ func main() {
err = os.MkdirAll(Config.filesDir, 0755)
if err != nil {
fmt.Printf("Error: could not create files directory\n")
fmt.Println("Error: could not create files directory")
os.Exit(1)
}
err = os.MkdirAll(Config.metaDir, 0700)
if err != nil {
fmt.Printf("Error: could not create metadata directory\n")
fmt.Println("Error: could not create metadata directory")
os.Exit(1)
}

20
templates/index.html

@ -18,20 +18,20 @@
<div id="choices">
<div id="expiry">
<label>File expiry:
<select name="expires" id="expires">
<select name="expires" id="expires" onchange="uploader.setParams({expires: $('#expires').val(), randomize: $('#randomize').is(':checked')})">
</label>
<option value="never">never</option>
<option value="a minute">a minute</option>
<option value="5 minutes">5 minutes</option>
<option value="an hour">an hour</option>
<option value="a day">a day</option>
<option value="a week">a week</option>
<option value="a month">a month</option>
<option value="a year">a year</option>
<option value="0">never</option>
<option value="60">a minute</option>
<option value="300">5 minutes</option>
<option value="3600">an hour</option>
<option value="86400">a day</option>
<option value="604800">a week</option>
<option value="2419200">a month</option>
<option value="29030400">a year</option>
</select>
</div>
<label><input name="randomize" id="randomize" type="checkbox" checked /> Randomize filename</label>
<label><input name="randomize" id="randomize" type="checkbox" checked onclick="uploader.setParams({expires: $('#expires').val(), randomize: $('#randomize').is(':checked')})" /> Randomize filename</label>
</div>

95
upload.go

@ -30,35 +30,6 @@ type Upload struct {
Size int64
Expiry int32 // Unix timestamp of expiry, 0=never
DeleteKey string // Deletion key, one generated if not provided
DebugInfo string // Optional field to store whatever
}
func uploadHeaderProcess(r *http.Request, upReq *UploadRequest) {
// For legacy reasons
upReq.randomBarename = false
if r.Header.Get("X-Randomized-Filename") == "yes" {
upReq.randomBarename = true
}
if r.Header.Get("X-Randomized-Barename") == "yes" {
upReq.randomBarename = true
}
upReq.deletionKey = r.Header.Get("X-Delete-Key")
// Get seconds until expiry. Non-integer responses never expire.
expStr := r.Header.Get("X-File-Expiry")
if expStr == "" {
upReq.expiry = 0
} else {
expiry, err := strconv.ParseInt(expStr, 10, 32)
if err != nil {
upReq.expiry = 0
} else {
upReq.expiry = int32(expiry)
}
}
}
func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
@ -66,6 +37,11 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
uploadHeaderProcess(r, &upReq)
if r.Header.Get("Content-Type") == "application/octet-stream" {
if r.URL.Query().Get("randomize") == "true" {
upReq.randomBarename = true
}
upReq.expiry = parseExpiry(r.URL.Query().Get("expires"))
defer r.Body.Close()
upReq.src = r.Body
upReq.filename = r.URL.Query().Get("qqfile")
@ -78,6 +54,11 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
}
defer file.Close()
r.ParseForm()
if r.Form.Get("randomize") == "true" {
upReq.randomBarename = true
}
upReq.expiry = parseExpiry(r.Form.Get("expires"))
upReq.src = file
upReq.filename = headers.Filename
}
@ -89,14 +70,9 @@ func uploadPostHandler(c web.C, w http.ResponseWriter, r *http.Request) {
}
if strings.EqualFold("application/json", r.Header.Get("Accept")) {
js, _ := json.Marshal(map[string]string{
"filename": upload.Filename,
"url": Config.siteURL + upload.Filename,
})
js := generateJSONresponse(upload)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write(js)
} else {
http.Redirect(w, r, "/"+upload.Filename, 301)
}
@ -117,7 +93,29 @@ func uploadPutHandler(c web.C, w http.ResponseWriter, r *http.Request) {
return
}
fmt.Fprintf(w, Config.siteURL+upload.Filename)
if strings.EqualFold("application/json", r.Header.Get("Accept")) {
js := generateJSONresponse(upload)
w.Header().Set("Content-Type", "application/json; charset=UTF-8")
w.Write(js)
} else {
fmt.Fprintf(w, Config.siteURL+upload.Filename)
}
}
func uploadHeaderProcess(r *http.Request, upReq *UploadRequest) {
// For legacy reasons
if r.Header.Get("X-Randomized-Filename") == "yes" {
upReq.randomBarename = true
} else if r.Header.Get("X-Randomized-Barename") == "yes" {
upReq.randomBarename = true
}
upReq.deletionKey = r.Header.Get("X-Delete-Key")
// Get seconds until expiry. Non-integer responses never expire.
expStr := r.Header.Get("X-File-Expiry")
upReq.expiry = parseExpiry(expStr)
}
func processUpload(upReq UploadRequest) (upload Upload, err error) {
@ -183,6 +181,18 @@ func generateBarename() string {
return uuid.New()[:8]
}
func generateJSONresponse(upload Upload) []byte {
js, _ := json.Marshal(map[string]string{
"url": Config.siteURL + upload.Filename,
"filename": upload.Filename,
"delete_key": upload.DeleteKey,
"expiry": strconv.FormatInt(int64(upload.Expiry), 10),
"size": strconv.FormatInt(upload.Size, 10),
})
return js
}
var barePlusRe = regexp.MustCompile(`[^A-Za-z0-9\-]`)
func barePlusExt(filename string) (barename, extension string) {
@ -198,3 +208,16 @@ func barePlusExt(filename string) (barename, extension string) {
return
}
func parseExpiry(expStr string) int32 {
if expStr == "" {
return 0
} else {
expiry, err := strconv.ParseInt(expStr, 10, 32)
if err != nil {
return 0
} else {
return int32(expiry)
}
}
}
Loading…
Cancel
Save