func (ctx *Context) Set(key string, val interface{}) {
	ctx.mu.Lock()
	defer ctx.mu.Unlock()
	ctx.vals[key] = val
}
Set takes a key and associates it with val in the context. The value is
persisted for the duration of the request and is removed on the following
request.
package martian
import (
	"bufio"
	"crypto/rand"
	"encoding/hex"
	"fmt"
	"net"
	"net/http"
	"sync"
)
type Context struct {
	session *Session
	id      string
	mu            sync.RWMutex
	vals          map[string]interface{}
	skipRoundTrip bool
	skipLogging   bool
	apiRequest    bool
}
type Session struct {
	mu       sync.RWMutex
	id       string
	secure   bool
	hijacked bool
	conn     net.Conn
	brw      *bufio.ReadWriter
	vals     map[string]interface{}
}
var (
	ctxmu sync.RWMutex
	ctxs  = make(map[*http.Request]*Context)
)
func NewContext(req *http.Request) *Context {
	ctxmu.RLock()
	defer ctxmu.RUnlock()
	return ctxs[req]
}
func TestContext(req *http.Request, conn net.Conn, bw *bufio.ReadWriter) (ctx *Context, remove func(), err error) {
	ctxmu.Lock()
	defer ctxmu.Unlock()
	ctx, ok := ctxs[req]
	if ok {
		return ctx, func() { unlink(req) }, nil
	}
	s, err := newSession(conn, bw)
	if err != nil {
		return nil, nil, err
	}
	ctx, err = withSession(s)
	if err != nil {
		return nil, nil, err
	}
	ctxs[req] = ctx
	return ctx, func() { unlink(req) }, nil
}
func (s *Session) ID() string {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.id
}
func (s *Session) IsSecure() bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.secure
}
func (s *Session) MarkSecure() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.secure = true
}
func (s *Session) MarkInsecure() {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.secure = false
}
func (s *Session) Hijack() (net.Conn, *bufio.ReadWriter, error) {
	s.mu.Lock()
	defer s.mu.Unlock()
	if s.hijacked {
		return nil, nil, fmt.Errorf("martian: session has already been hijacked")
	}
	s.hijacked = true
	return s.conn, s.brw, nil
}
func (s *Session) Hijacked() bool {
	s.mu.RLock()
	defer s.mu.RUnlock()
	return s.hijacked
}
func (s *Session) setConn(conn net.Conn, brw *bufio.ReadWriter) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.conn = conn
	s.brw = brw
}
func (s *Session) Get(key string) (interface{}, bool) {
	s.mu.RLock()
	defer s.mu.RUnlock()
	val, ok := s.vals[key]
	return val, ok
}
func (s *Session) Set(key string, val interface{}) {
	s.mu.Lock()
	defer s.mu.Unlock()
	s.vals[key] = val
}
func (ctx *Context) Session() *Session {
	return ctx.session
}
func (ctx *Context) ID() string {
	return ctx.id
}
func (ctx *Context) Get(key string) (interface{}, bool) {
	ctx.mu.RLock()
	defer ctx.mu.RUnlock()
	val, ok := ctx.vals[key]
	return val, ok
}