all repos — captcha @ 84aa93995e70fb9bea09dde3d0036cdc8b298266

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

Use ServeContent in Server.

This makes Server support Range request, fixing issue with Safari not
playing audio.
Dmitry Chestnykh dmitry@codingrobots.com
Sat, 25 Apr 2015 11:28:47 +0200
commit

84aa93995e70fb9bea09dde3d0036cdc8b298266

parent

6a5989d72f51dc85d9d6e2c6f0ee79cf675a3cfd

1 files changed, 18 insertions(+), 25 deletions(-)

jump to
M server.goserver.go

@@ -5,10 +5,11 @@

package captcha import ( + "bytes" "net/http" "path" - "strconv" "strings" + "time" ) type captchaHandler struct {

@@ -42,36 +43,28 @@ func Server(imgWidth, imgHeight int) http.Handler {

return &captchaHandler{imgWidth, imgHeight} } -func (h *captchaHandler) serve(w http.ResponseWriter, id, ext string, lang string, download bool) error { +func (h *captchaHandler) serve(w http.ResponseWriter, r *http.Request, id, ext, lang string, download bool) error { w.Header().Set("Cache-Control", "no-cache, no-store, must-revalidate") w.Header().Set("Pragma", "no-cache") w.Header().Set("Expires", "0") - if download { - w.Header().Set("Content-Type", "application/octet-stream") - } + + var content bytes.Buffer switch ext { case ".png": - if !download { - w.Header().Set("Content-Type", "image/png") - } - return WriteImage(w, id, h.imgWidth, h.imgHeight) + w.Header().Set("Content-Type", "image/png") + WriteImage(&content, id, h.imgWidth, h.imgHeight) case ".wav": - //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 { - return ErrNotFound - } - a := NewAudio(id, d, lang) - if !download { - w.Header().Set("Content-Type", "audio/x-wav") - } - w.Header().Set("Content-Length", strconv.Itoa(a.EncodedLen())) - _, err := a.WriteTo(w) - return err + w.Header().Set("Content-Type", "audio/x-wav") + WriteAudio(&content, id, lang) + default: + return ErrNotFound + } + + if download { + w.Header().Set("Content-Type", "application/octet-stream") } - return ErrNotFound + http.ServeContent(w, r, id+ext, time.Time{}, bytes.NewReader(content.Bytes())) + return nil } func (h *captchaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {

@@ -87,7 +80,7 @@ Reload(id)

} lang := strings.ToLower(r.FormValue("lang")) download := path.Base(dir) == "download" - if h.serve(w, id, ext, lang, download) == ErrNotFound { + if h.serve(w, r, id, ext, lang, download) == ErrNotFound { http.NotFound(w, r) } // Ignore other errors.