all repos — captcha @ 6e79acad4e8ca3f8b905c9957f2853dd9a8c5870

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

server.go (view raw)

 1package captcha
 2
 3import (
 4	"http"
 5	"os"
 6	"path"
 7	"strconv"
 8)
 9
10type captchaHandler struct {
11	imgWidth  int
12	imgHeight int
13}
14
15// Server returns a handler that serves HTTP requests with image or
16// audio representations of captchas. Image dimensions are accepted as
17// arguments. The server decides which captcha to serve based on the last URL
18// path component: file name part must contain a captcha id, file extension —
19// its format (PNG or WAV).
20//
21// For example, for file name "B9QTvDV1RXbVJ3Ac.png" it serves an image captcha
22// with id "B9QTvDV1RXbVJ3Ac", and for "B9QTvDV1RXbVJ3Ac.wav" it serves the
23// same captcha in audio format.
24//
25// To serve an audio captcha as downloadable file, append "?get" to URL.
26//
27// To reload captcha (get a different solution for the same captcha id), append
28// "?reload=x" to URL, where x may be anything (for example, current time or a
29// random number to make browsers refetch an image instead of loading it from
30// cache).
31func Server(w, h int) http.Handler { return &captchaHandler{w, h} }
32
33func (h *captchaHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) {
34	_, file := path.Split(r.URL.Path)
35	ext := path.Ext(file)
36	id := file[:len(file)-len(ext)]
37	if ext == "" || id == "" {
38		http.NotFound(w, r)
39		return
40	}
41	if r.FormValue("reload") != "" {
42		Reload(id)
43	}
44	var err os.Error
45	switch ext {
46	case ".png":
47		w.Header().Set("Content-Type", "image/png")
48		err = WriteImage(w, id, h.imgWidth, h.imgHeight)
49	case ".wav":
50		if r.URL.RawQuery == "get" {
51			w.Header().Set("Content-Type", "application/octet-stream")
52		} else {
53			w.Header().Set("Content-Type", "audio/x-wav")
54		}
55		//err = WriteAudio(w, id)
56		//XXX(dchest) Workaround for Chrome: it wants content-length,
57		//or else will start playing NOT from the beginning.
58		//Filed issue: http://code.google.com/p/chromium/issues/detail?id=80565
59		d := globalStore.Get(id, false)
60		if d == nil {
61			err = ErrNotFound
62		} else {
63			a := NewAudio(d)
64			w.Header().Set("Content-Length", strconv.Itoa(a.EncodedLen()))
65			_, err = a.WriteTo(w)
66		}
67	default:
68		err = ErrNotFound
69	}
70	if err != nil {
71		if err == ErrNotFound {
72			http.NotFound(w, r)
73			return
74		}
75		http.Error(w, "error serving captcha", http.StatusInternalServerError)
76	}
77}