func (r *GoHeader) GetKeys() (value []string) {
	if !r.isResponse {
		for key := range r.Source.(*GoRequest).Original.Header {
			value = append(value, key)
		}
	} else {
		for key := range r.Source.(*GoResponse).Original.Header() {
			value = append(value, key)
		}
	}
	return
}
Returns list of header keys
package testsuite
import (
	"fmt"
	"net/http"
	"time"
	"github.com/revel/revel"
	"github.com/revel/revel/utils"
	"golang.org/x/net/websocket"
	"io"
	"mime/multipart"
	"net/http/httptest"
	"net/url"
	"strconv"
)
var serverLog = revel.AppLog
func init() {
	revel.RegisterServerEngine("go-test", func() revel.ServerEngine {
		return &GoHttpServer{}
	})
	revel.RegisterModuleInit(func(m *revel.Module) {
		serverLog = m.Log
	})
}
type GoHttpServer struct {
	Server           *http.Server       
	ServerInit       *revel.EngineInit  
	MaxMultipartSize int64
	TestChannel      chan *TestRequest
	StartedChan      chan bool
}
func (g *GoHttpServer) Init(init *revel.EngineInit) {
	g.TestChannel = make(chan *TestRequest)
	g.StartedChan = make(chan bool)
	g.MaxMultipartSize = int64(revel.Config.IntDefault("server.request.max.multipart.filesize", 32)) << 20  
	goContextStack = utils.NewStackLock(revel.Config.IntDefault("server.context.stack", 100),
		revel.Config.IntDefault("server.context.maxstack", 200),
		func() interface{} {
			return NewGOContext(g)
		})
	goMultipartFormStack = utils.NewStackLock(revel.Config.IntDefault("server.form.stack", 100),
		revel.Config.IntDefault("server.form.maxstack", 200),
		func() interface{} { return &GoMultipartForm{} })
	g.ServerInit = init
	g.Server = &http.Server{
		Addr: init.Address,
		Handler: http.HandlerFunc(func(writer http.ResponseWriter, request *http.Request) {
			g.Handle(writer, request)
		}),
		ReadTimeout:  time.Duration(revel.Config.IntDefault("http.timeout.read", 0)) * time.Second,
		WriteTimeout: time.Duration(revel.Config.IntDefault("http.timeout.write", 0)) * time.Second,
	}
}
func (g *GoHttpServer) Start() {
	go func() {
		time.Sleep(100 * time.Millisecond)
		fmt.Printf("Revel Listening on %d...\n", g.ServerInit.Port)
	}()
	g.StartedChan <- true
	for {
		task, more := <-g.TestChannel
		if more {
			task.testSuite.Response = httptest.NewRecorder()
			g.Handle(task.testSuite.Response, task.Request)
			task.testSuite.ResponseChannel <- true
		} else {
			break
		}
	}
}
func (g *GoHttpServer) Handle(w http.ResponseWriter, r *http.Request) {
	if maxRequestSize := int64(revel.Config.IntDefault("http.maxrequestsize", 0)); maxRequestSize > 0 {
		r.Body = http.MaxBytesReader(w, r.Body, maxRequestSize)
	}
	upgrade := r.Header.Get("Upgrade")
	context := goContextStack.Pop().(*GoContext)
	defer func() {
		goContextStack.Push(context)
	}()
	context.Request.SetRequest(r)
	context.Response.SetResponse(w)
	if upgrade == "websocket" || upgrade == "Websocket" {
		websocket.Handler(func(ws *websocket.Conn) {
			if err := ws.SetDeadline(time.Now().Add(time.Hour * 24)); err != nil {
				serverLog.Error("SetDeadLine failed:", "error", err)
			}
			r.Method = "WS"
			context.Request.WebSocket = ws
			context.WebSocket = &GoWebSocket{Conn: ws, GoResponse: *context.Response}
			g.ServerInit.Callback(context)
		}).ServeHTTP(w, r)
	} else {
		g.ServerInit.Callback(context)
	}
}
const GO_NATIVE_TEST_SERVER_ENGINE = "go-test"
func (g *GoHttpServer) Name() string {
	return GO_NATIVE_TEST_SERVER_ENGINE
}
func (g *GoHttpServer) Stats() map[string]interface{} {
	return map[string]interface{}{
		"Go Engine Context": goContextStack.String(),
		"Go Engine Forms":   goMultipartFormStack.String(),
	}
}
func (g *GoHttpServer) Engine() interface{} {
	return g.Server
}
func (g *GoHttpServer) Event(event revel.Event, args interface{}) revel.EventResponse {
	return 0
}
type (
	GoContext struct {
		Request   *GoRequest
		Response  *GoResponse
		WebSocket *GoWebSocket
	}
	GoRequest struct {
		Original        *http.Request
		FormParsed      bool
		MultiFormParsed bool
		WebSocket       *websocket.Conn
		ParsedForm      *GoMultipartForm
		Goheader        *GoHeader
		Engine          *GoHttpServer
	}
	GoResponse struct {
		Original http.ResponseWriter
		Goheader *GoHeader
		Writer   io.Writer
		Request  *GoRequest
		Engine   *GoHttpServer
	}
	GoMultipartForm struct {
		Form *multipart.Form
	}
	GoHeader struct {
		Source     interface{}
		isResponse bool
	}
	GoWebSocket struct {
		Conn *websocket.Conn
		GoResponse
	}
	GoCookie http.Cookie
)
var (
	goContextStack       *utils.SimpleLockStack
	goMultipartFormStack *utils.SimpleLockStack
)
func NewGOContext(instance *GoHttpServer) *GoContext {
	if instance == nil {
		instance = &GoHttpServer{MaxMultipartSize: 32 << 20}
	}
	c := &GoContext{Request: &GoRequest{Goheader: &GoHeader{}, Engine: instance}}
	c.Response = &GoResponse{Goheader: &GoHeader{}, Request: c.Request, Engine: instance}
	return c
}
func (c *GoContext) GetRequest() revel.ServerRequest {
	return c.Request
}
func (c *GoContext) GetResponse() revel.ServerResponse {
	if c.WebSocket != nil {
		return c.WebSocket
	}
	return c.Response
}
func (c *GoContext) Destroy() {
	c.Response.Destroy()
	c.Request.Destroy()
	if c.WebSocket != nil {
		c.WebSocket.Destroy()
	}
}
func (r *GoRequest) Get(key int) (value interface{}, err error) {
	switch key {
	case revel.HTTP_SERVER_HEADER:
		value = r.GetHeader()
	case revel.HTTP_MULTIPART_FORM:
		value, err = r.GetMultipartForm()
	case revel.HTTP_QUERY:
		value = r.Original.URL.Query()
	case revel.HTTP_FORM:
		value, err = r.GetForm()
	case revel.HTTP_REQUEST_URI:
		value = r.Original.URL.RequestURI()
	case revel.HTTP_REMOTE_ADDR:
		value = r.Original.RemoteAddr
	case revel.HTTP_METHOD:
		value = r.Original.Method
	case revel.HTTP_PATH:
		value = r.Original.URL.Path
	case revel.HTTP_HOST:
		value = r.Original.Host
	default:
		err = revel.ENGINE_UNKNOWN_GET
	}
	return
}
func (r *GoRequest) Set(key int, value interface{}) bool {
	return false
}
func (r *GoRequest) GetForm() (url.Values, error) {
	if !r.FormParsed {
		if e := r.Original.ParseForm(); e != nil {
			return nil, e
		}
		r.FormParsed = true
	}
	return r.Original.Form, nil
}
func (r *GoRequest) GetMultipartForm() (revel.ServerMultipartForm, error) {
	if !r.MultiFormParsed {
		if e := r.Original.ParseMultipartForm(r.Engine.MaxMultipartSize); e != nil {
			return nil, e
		}
		r.ParsedForm = goMultipartFormStack.Pop().(*GoMultipartForm)
		r.ParsedForm.Form = r.Original.MultipartForm
	}
	return r.ParsedForm, nil
}
func (r *GoRequest) GetHeader() revel.ServerHeader {
	return r.Goheader
}
func (r *GoRequest) GetRaw() interface{} {
	return r.Original
}
func (r *GoRequest) SetRequest(req *http.Request) {
	r.Original = req
	r.Goheader.Source = r
	r.Goheader.isResponse = false
}
func (r *GoRequest) Destroy() {
	r.Goheader.Source = nil
	r.Original = nil
	r.FormParsed = false
	r.MultiFormParsed = false
	r.ParsedForm = nil
}
func (r *GoResponse) Get(key int) (value interface{}, err error) {
	switch key {
	case revel.HTTP_SERVER_HEADER:
		value = r.Header()
	case revel.HTTP_STREAM_WRITER:
		value = r
	case revel.HTTP_WRITER:
		value = r.Writer
	default:
		err = revel.ENGINE_UNKNOWN_GET
	}
	return
}