[tor-commits] [check/master] Prevent multiple response.WriteHeader calls.

arlo at torproject.org arlo at torproject.org
Thu Oct 3 04:13:59 UTC 2013


commit 5e5bd0cce147bfe1e077579abb33802978792cc5
Author: Arlo Breault <arlolra at gmail.com>
Date:   Wed Oct 2 21:02:55 2013 -0700

    Prevent multiple response.WriteHeader calls.
    
    HEAD requests were causing the template executer to warn about
    ErrBodyNotAllowed. The error handler was then trying to return a 500,
    but headers had already be written.
    
    For now we'll just log errors. A better fix may be to buffer a response,
    then check for errors before writing it.
    
    Closes #18
---
 handlers.go |   13 +++++++------
 utils.go    |   22 ++++++++++------------
 2 files changed, 17 insertions(+), 18 deletions(-)

diff --git a/handlers.go b/handlers.go
index 39bb584..cef330d 100644
--- a/handlers.go
+++ b/handlers.go
@@ -3,6 +3,7 @@ package main
 import (
 	"fmt"
 	"html/template"
+	"log"
 	"net"
 	"net/http"
 	"time"
@@ -53,8 +54,8 @@ 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 {
-				http.Error(w, err.Error(), http.StatusInternalServerError)
+			if err := Layout.ExecuteTemplate(w, "torbutton.html", isTor); err != nil && NotHeadErr(err) {
+				log.Printf("Layout.ExecuteTemplate: %v", err)
 			}
 			return
 		}
@@ -94,8 +95,8 @@ func RootHandler(Layout *template.Template, Exits *Exits, Phttp *http.ServeMux)
 		}
 
 		// render the template
-		if err := Layout.ExecuteTemplate(w, "index.html", p); err != nil {
-			http.Error(w, err.Error(), http.StatusInternalServerError)
+		if err := Layout.ExecuteTemplate(w, "index.html", p); err != nil && NotHeadErr(err) {
+			log.Printf("Layout.ExecuteTemplate: %v", err)
 		}
 
 	}
@@ -109,8 +110,8 @@ func BulkHandler(Layout *template.Template, Exits *Exits) func(http.ResponseWrit
 
 		ip := q.Get("ip")
 		if net.ParseIP(ip) == nil {
-			if err := Layout.ExecuteTemplate(w, "bulk.html", nil); err != nil {
-				http.Error(w, err.Error(), http.StatusInternalServerError)
+			if err := Layout.ExecuteTemplate(w, "bulk.html", nil); err != nil && NotHeadErr(err) {
+				log.Printf("Layout.ExecuteTemplate: %v", err)
 			}
 			return
 		}
diff --git a/utils.go b/utils.go
index eb8a66d..d2ab661 100644
--- a/utils.go
+++ b/utils.go
@@ -9,9 +9,10 @@ import (
 	"io/ioutil"
 	"log"
 	"net/http"
+	"net/url"
 	"os"
 	"strconv"
-	"net/url"
+	"strings"
 )
 
 func UpToDate(r *http.Request) bool {
@@ -48,6 +49,11 @@ 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{} {
@@ -65,27 +71,19 @@ func FuncMap(domain *gettext.Domain) template.FuncMap {
 var Layout *template.Template
 
 func CompileTemplate(domain *gettext.Domain, templateName string) *template.Template {
-	var err error
 	if Layout == nil {
 		Layout = template.New("")
 		Layout = Layout.Funcs(FuncMap(domain))
-		Layout, err = Layout.ParseFiles(
+		Layout = template.Must(Layout.ParseFiles(
 			"public/base.html",
 			"public/torbutton.html",
-		)
-		if err != nil {
-			log.Fatal(err)
-		}
+		))
 	}
 	l, err := Layout.Clone()
 	if err != nil {
 		log.Fatal(err)
 	}
-	l, err = l.ParseFiles("public/" + templateName)
-	if err != nil {
-		log.Fatal(err)
-	}
-	return l
+	return template.Must(l.ParseFiles("public/" + templateName))
 }
 
 type locale struct {



More information about the tor-commits mailing list