Repository: istio/fortio (go)

Issue:
fortio /debug : sort the headers
would make it easier to find

Pull request description:
Fix #143 : sort the headers alphabetically for `fortio server` /debug endpoint
fixes #143 

Patch:
diff --git a/fhttp/http.go b/fhttp/http.go
index bee5d42..0f57110 100644
--- a/fhttp/http.go
+++ b/fhttp/http.go
@@ -27,6 +27,7 @@ import (
 	"net/http/httputil"
 	"net/url"
 	"os"
+	"sort"
 	"strconv"
 	"strings"
 	"sync/atomic"
@@ -1232,11 +1233,18 @@ func DebugHandler(w http.ResponseWriter, r *http.Request) {
 	// Host is removed from headers map and put here (!)
 	buf.WriteString("Host: ")
 	buf.WriteString(r.Host)
-	for name, headers := range r.Header {
+
+	var keys []string
+	for k := range r.Header {
+		keys = append(keys, k)
+	}
+	sort.Strings(keys)
+	for _, name := range keys {
 		buf.WriteByte('\n')
 		buf.WriteString(name)
 		buf.WriteString(": ")
 		first := true
+		headers := r.Header[name]
 		for _, h := range headers {
 			if !first {
 				buf.WriteByte(',')


Test patch:
diff --git a/fhttp/http_test.go b/fhttp/http_test.go
index ab0ee41..883bbff 100644
--- a/fhttp/http_test.go
+++ b/fhttp/http_test.go
@@ -597,6 +597,39 @@ func TestPayloadSizeLarge(t *testing.T) {
 	}
 }
 
+func TestDebugHandlerSortedHeaders(t *testing.T) {
+	p, m := DynamicHTTPServer(false)
+	m.HandleFunc("/debug", DebugHandler)
+	url := fmt.Sprintf("http://localhost:%d/debug", p)
+	o := HTTPOptions{URL: url, DisableFastClient: true}
+	o.AddAndValidateExtraHeader("BBB: bbb")
+	o.AddAndValidateExtraHeader("CCC: ccc")
+	o.AddAndValidateExtraHeader("ZZZ: zzz")
+	o.AddAndValidateExtraHeader("AAA: aaa")
+	client := NewClient(&o)
+	code, data, header := client.Fetch() // used to panic/bug #127
+	t.Logf("TestDebugHandlerSortedHeaders result code %d, data len %d, headerlen %d", code, len(data), header)
+	if code != http.StatusOK {
+		t.Errorf("Got %d instead of 200", code)
+	}
+	//remove the first line ('Φορτίο version...') from the body
+	body := string(data)
+	i := strings.Index(body, "\n")
+	body = body[i+1:]
+	expected := fmt.Sprintf("\nGET /debug HTTP/1.1\n\n"+
+		"headers:\n\n"+
+		"Host: localhost:%d\n"+
+		"Aaa: aaa\n"+
+		"Bbb: bbb\n"+
+		"Ccc: ccc\n"+
+		"User-Agent: %s\n"+
+		"Zzz: zzz\n\n"+
+		"body:\n\n\n", p, userAgent)
+	if body != expected {
+		t.Errorf("Get body: %s not as expected: %s", body, expected)
+	}
+}
+
 // --- for bench mark/comparaison
 
 func asciiFold0(str string) []byte {