|
|
@@ -8,6 +8,7 @@ import (
|
|
|
"io"
|
|
|
"os"
|
|
|
"path"
|
|
|
+ "strconv"
|
|
|
)
|
|
|
|
|
|
const (
|
|
|
@@ -16,7 +17,7 @@ const (
|
|
|
// The number of captchas created that triggers garbage collection.
|
|
|
StdCollectNum = 100
|
|
|
// Expiration time of captchas.
|
|
|
- StdExpiration = 2 * 60 // 2 minutes
|
|
|
+ StdExpiration = 10 * 60 // 10 minutes
|
|
|
|
|
|
)
|
|
|
|
|
|
@@ -135,7 +136,7 @@ type captchaHandler struct {
|
|
|
imgHeight int
|
|
|
}
|
|
|
|
|
|
-// CaptchaServer returns a handler that serves HTTP requests with image or
|
|
|
+// Server returns a handler that serves HTTP requests with image or
|
|
|
// audio representations of captchas. Image dimensions are accepted as
|
|
|
// arguments. The server decides which captcha to serve based on the last URL
|
|
|
// path component: file name part must contain a captcha id, file extension —
|
|
|
@@ -144,6 +145,8 @@ type captchaHandler struct {
|
|
|
// 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.
|
|
|
func Server(w, h int) http.Handler { return &captchaHandler{w, h} }
|
|
|
|
|
|
func (h *captchaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
@@ -160,8 +163,22 @@ func (h *captchaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
|
|
|
w.Header().Set("Content-Type", "image/png")
|
|
|
err = WriteImage(w, id, h.imgWidth, h.imgHeight)
|
|
|
case ".wav", ".WAV":
|
|
|
- w.Header().Set("Content-Type", "audio/x-wav")
|
|
|
- err = WriteAudio(w, id)
|
|
|
+ if r.URL.RawQuery == "get" {
|
|
|
+ w.Header().Set("Content-Type", "application/octet-stream")
|
|
|
+ } else {
|
|
|
+ w.Header().Set("Content-Type", "audio/x-wav")
|
|
|
+ }
|
|
|
+ //err = WriteAudio(buf, id)
|
|
|
+ //XXX(dchest) Workaround for Chrome: it wants content-length,
|
|
|
+ //or else will start playing NOT from the beginning.
|
|
|
+ d := globalStore.getDigits(id)
|
|
|
+ if d == nil {
|
|
|
+ err = ErrNotFound
|
|
|
+ } else {
|
|
|
+ a := NewAudio(d)
|
|
|
+ w.Header().Set("Content-Length", strconv.Itoa(a.EncodedLen()))
|
|
|
+ _, err = a.WriteTo(w)
|
|
|
+ }
|
|
|
default:
|
|
|
err = ErrNotFound
|
|
|
}
|