commit 8652915e57f200c60cdbf8082f04e5d96448e616 Author: Arlo Breault arlolra@gmail.com Date: Thu Oct 3 11:46:53 2013 -0700
Buffer template rendering.
This allows for better error handling and a place to deal with HEAD requests. --- check.go | 4 ++-- handlers.go | 55 ++++++++++++++++++++++++++++++++++--------------- public/torbutton.html | 2 +- utils.go | 6 ------ 4 files changed, 41 insertions(+), 26 deletions(-)
diff --git a/check.go b/check.go index 3354e69..3cdc989 100644 --- a/check.go +++ b/check.go @@ -45,8 +45,8 @@ func main() { Phttp.Handle("/", files)
// routes - http.HandleFunc("/", RootHandler(CompileTemplate(domain, "index.html"), exits, Phttp)) - bulk := BulkHandler(CompileTemplate(domain, "bulk.html"), exits) + http.HandleFunc("/", RootHandler(CompileTemplate(domain, "index.html"), exits, domain, Phttp)) + bulk := BulkHandler(CompileTemplate(domain, "bulk.html"), exits, domain) http.HandleFunc("/torbulkexitlist", bulk) http.HandleFunc("/cgi-bin/TorBulkExitList.py", bulk)
diff --git a/handlers.go b/handlers.go index cef330d..cd8e815 100644 --- a/handlers.go +++ b/handlers.go @@ -1,11 +1,15 @@ package main
import ( + "bytes" "fmt" + "github.com/samuel/go-gettext/gettext" "html/template" + "io" "log" "net" "net/http" + "strconv" "time" )
@@ -24,7 +28,7 @@ type Page struct { Locales map[string]string }
-func RootHandler(Layout *template.Template, Exits *Exits, Phttp *http.ServeMux) func(http.ResponseWriter, *http.Request) { +func RootHandler(Layout *template.Template, Exits *Exits, domain *gettext.Domain, Phttp *http.ServeMux) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
@@ -34,17 +38,18 @@ func RootHandler(Layout *template.Template, Exits *Exits, Phttp *http.ServeMux) return }
+ var ( + err error + isTor bool + fingerprint string + ) + // get remote ip host := r.Header.Get("X-Forwarded-For") - var err error if len(host) == 0 { host, _, err = net.SplitHostPort(r.RemoteAddr) }
- var ( - isTor bool - fingerprint string - ) // determine if we're in Tor if err != nil { isTor = false @@ -54,9 +59,7 @@ func RootHandler(Layout *template.Template, Exits *Exits, Phttp *http.ServeMux)
// short circuit for torbutton if len(r.URL.Query().Get("TorButton")) > 0 { - if err := Layout.ExecuteTemplate(w, "torbutton.html", isTor); err != nil && NotHeadErr(err) { - log.Printf("Layout.ExecuteTemplate: %v", err) - } + WriteHTMLBuf(w, r, Layout, domain, "torbutton.html", Page{IsTor: isTor}) return }
@@ -95,24 +98,19 @@ func RootHandler(Layout *template.Template, Exits *Exits, Phttp *http.ServeMux) }
// render the template - if err := Layout.ExecuteTemplate(w, "index.html", p); err != nil && NotHeadErr(err) { - log.Printf("Layout.ExecuteTemplate: %v", err) - } - + WriteHTMLBuf(w, r, Layout, domain, "index.html", p) }
}
-func BulkHandler(Layout *template.Template, Exits *Exits) func(http.ResponseWriter, *http.Request) { +func BulkHandler(Layout *template.Template, Exits *Exits, domain *gettext.Domain) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) { q := r.URL.Query()
ip := q.Get("ip") if net.ParseIP(ip) == nil { - if err := Layout.ExecuteTemplate(w, "bulk.html", nil); err != nil && NotHeadErr(err) { - log.Printf("Layout.ExecuteTemplate: %v", err) - } + WriteHTMLBuf(w, r, Layout, domain, "bulk.html", Page{}) return }
@@ -128,3 +126,26 @@ func BulkHandler(Layout *template.Template, Exits *Exits) func(http.ResponseWrit }
} + +func WriteHTMLBuf(w http.ResponseWriter, r *http.Request, Layout *template.Template, domain *gettext.Domain, tmp string, p Page) { + buf := new(bytes.Buffer) + + // render template + if err := Layout.ExecuteTemplate(buf, tmp, p); err != nil { + log.Printf("Layout.ExecuteTemplate: %v", err) + http.Error(w, domain.GetText(p.Lang, "Sorry, your query failed or an unexpected response was received."), http.StatusInternalServerError) + return + } + + // set some headers + w.Header().Set("Content-Type", "text/html; charset=utf-8") + if r.Method == "HEAD" { + w.Header().Set("Content-Length", strconv.Itoa(buf.Len())) + return + } + + // write buf + if _, err := io.Copy(w, buf); err != nil { + log.Printf("io.Copy: %v", err) + } +} diff --git a/public/torbutton.html b/public/torbutton.html index ef97d09..3369f50 100644 --- a/public/torbutton.html +++ b/public/torbutton.html @@ -1,6 +1,6 @@ <!doctype html> <html> <body> - <a id="TorCheckResult" target="{{ if . }}success{{ else }}fail{{ end }}" href="/"></a> + <a id="TorCheckResult" target="{{ if .IsTor }}success{{ else }}fail{{ end }}" href="/"></a> </body> </html> \ No newline at end of file diff --git a/utils.go b/utils.go index d2ab661..9d2667b 100644 --- a/utils.go +++ b/utils.go @@ -12,7 +12,6 @@ import ( "net/url" "os" "strconv" - "strings" )
func UpToDate(r *http.Request) bool { @@ -49,11 +48,6 @@ func GetQS(q url.Values, param string, deflt int) (num int, str string) { return }
-func NotHeadErr(err error) bool { - // should just be able to compare errors but executetemplate formats it - return !strings.Contains(err.Error(), http.ErrBodyNotAllowed.Error()) -} - func FuncMap(domain *gettext.Domain) template.FuncMap { return template.FuncMap{ "UnEscaped": func(x string) interface{} {
tor-commits@lists.torproject.org