all repos — captcha @ 6e79acad4e8ca3f8b905c9957f2853dd9a8c5870

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

Move server parts to server.go.
Dmitry Chestnykh dmitry@codingrobots.com
Wed, 27 Apr 2011 12:30:13 +0200
commit

6e79acad4e8ca3f8b905c9957f2853dd9a8c5870

parent

316aacb9c04c6035277402f39fa8e40688258a7d

3 files changed, 79 insertions(+), 73 deletions(-)

jump to
M MakefileMakefile

@@ -7,7 +7,8 @@ store.go\

font.go\ image.go\ sounds.go\ - audio.go + audio.go\ + server.go include $(GOROOT)/src/Make.pkg
M captcha.gocaptcha.go

@@ -45,11 +45,8 @@ import (

"bytes" "crypto/rand" "github.com/dchest/uniuri" - "http" "io" "os" - "path" - "strconv" ) const (

@@ -178,72 +175,3 @@ // Collection is launched in a new goroutine.

func Collect() { go globalStore.Collect() } - -type captchaHandler struct { - imgWidth int - imgHeight int -} - -// 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 — -// its format (PNG or WAV). -// -// 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. -// -// 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 -// random number to make browsers refetch an image instead of loading it from -// 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 - } - 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) - case ".wav": - if r.URL.RawQuery == "get" { - w.Header().Set("Content-Type", "application/octet-stream") - } else { - w.Header().Set("Content-Type", "audio/x-wav") - } - //err = 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) - } - default: - err = ErrNotFound - } - if err != nil { - if err == ErrNotFound { - http.NotFound(w, r) - return - } - http.Error(w, "error serving captcha", http.StatusInternalServerError) - } -}
A server.go

@@ -0,0 +1,77 @@

+package captcha + +import ( + "http" + "os" + "path" + "strconv" +) + +type captchaHandler struct { + imgWidth int + imgHeight int +} + +// 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 — +// its format (PNG or WAV). +// +// 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. +// +// 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 +// random number to make browsers refetch an image instead of loading it from +// 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 + } + 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) + case ".wav": + if r.URL.RawQuery == "get" { + w.Header().Set("Content-Type", "application/octet-stream") + } else { + w.Header().Set("Content-Type", "audio/x-wav") + } + //err = 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) + } + default: + err = ErrNotFound + } + if err != nil { + if err == ErrNotFound { + http.NotFound(w, r) + return + } + http.Error(w, "error serving captcha", http.StatusInternalServerError) + } +}