server: serve downloads from "/download/". Also, refactor methods.
Dmitry Chestnykh dmitry@codingrobots.com
Wed, 27 Apr 2011 13:09:22 +0200
1 files changed,
33 insertions(+),
26 deletions(-)
jump to
M
server.go
→
server.go
@@ -22,7 +22,9 @@ // For example, for file name "B9QTvDV1RXbVJ3Ac.png" it serves an image captcha
// with id "B9QTvDV1RXbVJ3Ac", and for "B9QTvDV1RXbVJ3Ac.wav" it serves the // same captcha in audio format. // -// To serve an audio captcha as downloadable file, append "?get" to URL. +// To serve a captcha as a downloadable file, the URL must be constructed in +// such a way as if the file to serve is in "download" subdirectory: +// "/download/B9QTvDV1RXbVJ3Ac.wav". // // To reload captcha (get a different solution for the same captcha id), append // "?reload=x" to URL, where x may be anything (for example, current time or a@@ -30,44 +32,49 @@ // random number to make browsers refetch an image instead of loading it from
// cache). func Server(w, h int) http.Handler { return &captchaHandler{w, h} } -func (h *captchaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { - _, file := path.Split(r.URL.Path) - ext := path.Ext(file) - id := file[:len(file)-len(ext)] - if ext == "" || id == "" { - http.NotFound(w, r) - return - } - if r.FormValue("reload") != "" { - Reload(id) +func (h *captchaHandler) serve(w http.ResponseWriter, id, ext string, download bool) os.Error { + if download { + w.Header().Set("Content-Type", "application/octet-stream") } - var err os.Error switch ext { case ".png": - w.Header().Set("Content-Type", "image/png") - err = WriteImage(w, id, h.imgWidth, h.imgHeight) + if !download { + w.Header().Set("Content-Type", "image/png") + } + return WriteImage(w, id, h.imgWidth, h.imgHeight) case ".wav": - if r.URL.RawQuery == "get" { - w.Header().Set("Content-Type", "application/octet-stream") - } else { + if !download { w.Header().Set("Content-Type", "audio/x-wav") } - //err = WriteAudio(w, id) + //return WriteAudio(w, id) //XXX(dchest) Workaround for Chrome: it wants content-length, //or else will start playing NOT from the beginning. //Filed issue: http://code.google.com/p/chromium/issues/detail?id=80565 d := globalStore.Get(id, false) if d == nil { - err = ErrNotFound - } else { - a := NewAudio(d) - w.Header().Set("Content-Length", strconv.Itoa(a.EncodedLen())) - _, err = a.WriteTo(w) + return ErrNotFound } - default: - err = ErrNotFound + a := NewAudio(d) + w.Header().Set("Content-Length", strconv.Itoa(a.EncodedLen())) + _, err := a.WriteTo(w) + return err + } + return ErrNotFound +} + +func (h *captchaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { + dir, file := path.Split(r.URL.Path) + ext := path.Ext(file) + id := file[:len(file)-len(ext)] + if ext == "" || id == "" { + http.NotFound(w, r) + return + } + if r.FormValue("reload") != "" { + Reload(id) } - if err != nil { + download := path.Base(dir) == "download" + if err := h.serve(w, id, ext, download); err != nil { if err == ErrNotFound { http.NotFound(w, r) return