Add Audio.EncodedLen. Workaround for Chrome WAV bug.
Dmitry Chestnykh dmitry@codingrobots.com
Mon, 25 Apr 2011 02:16:01 +0200
2 files changed,
26 insertions(+),
4 deletions(-)
M
audio.go
→
audio.go
@@ -91,6 +91,11 @@ n += int64(nn)
return } +// EncodedLen returns the length of WAV-encoded audio captcha. +func (a *Audio) EncodedLen() int { + return len(waveHeader) + 4 + a.body.Len() +} + // mixSound mixes src into dst. Dst must have length equal to or greater than // src length. func mixSound(dst, src []byte) {
M
captcha.go
→
captcha.go
@@ -8,6 +8,7 @@ "http"
"io" "os" "path" + "strconv" ) const (@@ -16,7 +17,7 @@ StdLength = 6
// 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 @@ imgWidth int
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 @@ //
// 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 @@ case ".png", ".PNG":
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 }