all repos — captcha @ 8a2b5ae5df96f92bcc8bbf57acc7381b5116edde

Go package captcha implements generation and verification of image and audio CAPTCHAs.

Add Audio.EncodedLen. Workaround for Chrome WAV bug.
Dmitry Chestnykh dmitry@codingrobots.com
Mon, 25 Apr 2011 02:16:01 +0200
commit

8a2b5ae5df96f92bcc8bbf57acc7381b5116edde

parent

d010e3f940eb4120c858e62195435aa592c1ece5

2 files changed, 26 insertions(+), 4 deletions(-)

jump to
M audio.goaudio.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.gocaptcha.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 }