func sockjsHandlerWithRequest(
	prefix string,
	opts sockjs.Options,
	handleFunc func(sockjs.Session, *http.Request),
) http.Handler {
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		sockjs.NewHandler(prefix, opts, func(session sockjs.Session) {
			handleFunc(session, r)
		}).ServeHTTP(w, r)
	})
}
sockjsHandlerWithRequest is a wrapper around the sockjs.Handler that
includes a *http.Request context.
package tunnelproxy
import (
	"crypto/tls"
	"errors"
	"net"
	"net/http"
	"net/url"
	"strconv"
	"strings"
	"sync/atomic"
	"time"
	"github.com/koding/kite"
	"github.com/koding/kite/config"
	"github.com/dgrijalva/jwt-go"
	"github.com/igm/sockjs-go/sockjs"
)
const (
	ProxyVersion = "0.0.2"
)
var (
	DefaultPort       = 3999
	DefaultPublicHost = "localhost:3999"
)
type Proxy struct {
	Kite *kite.Kite
	listener  net.Listener
	TLSConfig *tls.Config
	readyC chan bool  
	closeC chan bool  
	PublicHost string
	pubKey  string
	privKey string
	kites map[string]*PrivateKite
	mux *http.ServeMux
	RegisterToKontrol bool
	url *url.URL
}
func New(conf *config.Config, version, pubKey, privKey string) *Proxy {
	k := kite.New("tunnelproxy", version)
	k.Config = conf
	if k.Config.Port == 0 {
		k.Config.Port = DefaultPort
	}
	p := &Proxy{
		Kite:              k,
		readyC:            make(chan bool),
		closeC:            make(chan bool),
		pubKey:            pubKey,
		privKey:           privKey,
		kites:             make(map[string]*PrivateKite),
		mux:               http.NewServeMux(),
		RegisterToKontrol: true,
		PublicHost:        DefaultPublicHost,
	}
	p.Kite.HandleFunc("register", p.handleRegister)
	p.mux.Handle("/", p.Kite)
	p.mux.Handle("/proxy/", sockjsHandlerWithRequest("/proxy", sockjs.DefaultOptions, p.handleProxy))     
	p.mux.Handle("/tunnel/", sockjsHandlerWithRequest("/tunnel", sockjs.DefaultOptions, p.handleTunnel))  
	k.OnDisconnect(func(r *kite.Client) {
		delete(p.kites, r.Kite.ID)
	})
	return p
}