Browse Source

server: serve downloads from "/download/".

Also, refactor methods.
Dmitry Chestnykh 14 years ago
parent
commit
c72fa4f230
1 changed files with 33 additions and 26 deletions
  1. 33 26
      server.go

+ 33 - 26
server.go

@@ -22,7 +22,9 @@ type captchaHandler struct {
 // 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 @@ type captchaHandler struct {
 // 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
+func (h *captchaHandler) serve(w http.ResponseWriter, id, ext string, download bool) os.Error {
+	if download {
+		w.Header().Set("Content-Type", "application/octet-stream")
 	}
-	if r.FormValue("reload") != "" {
-		Reload(id)
-	}
-	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