func NewConnection(conn net.Conn, server bool) (*Connection, error) {
	framer, framerErr := spdy.NewFramer(conn, conn)
	if framerErr != nil {
		return nil, framerErr
	}
	idleAwareFramer := newIdleAwareFramer(framer)
	var sid spdy.StreamId
	var rid spdy.StreamId
	var pid uint32
	if server {
		sid = 2
		rid = 1
		pid = 2
	} else {
		sid = 1
		rid = 2
		pid = 1
	}
	streamLock := new(sync.RWMutex)
	streamCond := sync.NewCond(streamLock)
	session := &Connection{
		conn:   conn,
		framer: idleAwareFramer,
		closeChan:     make(chan bool),
		goAwayTimeout: time.Duration(0),
		closeTimeout:  time.Duration(0),
		streamLock:       streamLock,
		streamCond:       streamCond,
		streams:          make(map[spdy.StreamId]*Stream),
		nextStreamId:     sid,
		receivedStreamId: rid,
		pingId:    pid,
		pingChans: make(map[uint32]chan error),
		shutdownChan: make(chan error),
	}
	session.dataFrameHandler = session.handleDataFrame
	idleAwareFramer.conn = session
	go idleAwareFramer.monitor()
	return session, nil
}
NewConnection creates a new spdy connection from an existing
network connection.
package spdystream
import (
	"errors"
	"fmt"
	"io"
	"net"
	"net/http"
	"sync"
	"time"
	"github.com/docker/spdystream/spdy"
)
var (
	ErrInvalidStreamId   = errors.New("Invalid stream id")
	ErrTimeout           = errors.New("Timeout occured")
	ErrReset             = errors.New("Stream reset")
	ErrWriteClosedStream = errors.New("Write on closed stream")
)
const (
	FRAME_WORKERS = 5
	QUEUE_SIZE    = 50
)
type StreamHandler func(stream *Stream)
type AuthHandler func(header http.Header, slot uint8, parent uint32) bool
type idleAwareFramer struct {
	f              *spdy.Framer
	conn           *Connection
	writeLock      sync.Mutex
	resetChan      chan struct{}
	setTimeoutLock sync.Mutex
	setTimeoutChan chan time.Duration
	timeout        time.Duration
}
func newIdleAwareFramer(framer *spdy.Framer) *idleAwareFramer {
	iaf := &idleAwareFramer{
		f:         framer,
		resetChan: make(chan struct{}, 2),
		setTimeoutChan: make(chan time.Duration, 1),
	}
	return iaf
}
func (i *idleAwareFramer) monitor() {
	var (
		timer          *time.Timer
		expired        <-chan time.Time
		resetChan      = i.resetChan
		setTimeoutChan = i.setTimeoutChan
	)
Loop:
	for {
		select {
		case timeout := <-i.setTimeoutChan:
			i.timeout = timeout
			if timeout == 0 {
				if timer != nil {
					timer.Stop()
				}
			} else {
				if timer == nil {
					timer = time.NewTimer(timeout)
					expired = timer.C
				} else {
					timer.Reset(timeout)
				}
			}
		case <-resetChan:
			if timer != nil && i.timeout > 0 {
				timer.Reset(i.timeout)
			}
		case <-expired:
			i.conn.streamCond.L.Lock()
			streams := i.conn.streams
			i.conn.streams = make(map[spdy.StreamId]*Stream)
			i.conn.streamCond.Broadcast()
			i.conn.streamCond.L.Unlock()
			go func() {
				for _, stream := range streams {
					stream.resetStream()
				}
				i.conn.Close()
			}()
		case <-i.conn.closeChan:
			if timer != nil {
				timer.Stop()
			}
			go func() {
				for _ = range resetChan {
				}
			}()
			go func() {
				for _ = range setTimeoutChan {
				}
			}()
			i.writeLock.Lock()
			close(resetChan)
			i.resetChan = nil
			i.writeLock.Unlock()
			i.setTimeoutLock.Lock()
			close(i.setTimeoutChan)
			i.setTimeoutChan = nil
			i.setTimeoutLock.Unlock()
			break Loop
		}
	}
	for _ = range resetChan {
	}
}
func (i *idleAwareFramer) WriteFrame(frame spdy.Frame) error {
	i.writeLock.Lock()
	defer i.writeLock.Unlock()
	if i.resetChan == nil {
		return io.EOF
	}
	err := i.f.WriteFrame(frame)
	if err != nil {
		return err
	}
	i.resetChan <- struct{}{}
	return nil
}
func (i *idleAwareFramer) ReadFrame() (spdy.Frame, error) {
	frame, err := i.f.ReadFrame()
	if err != nil {
		return nil, err
	}
	i.resetChan <- struct{}{}
	return frame, nil
}
func (i *idleAwareFramer) setIdleTimeout(timeout time.Duration) {
	i.setTimeoutLock.Lock()
	defer i.setTimeoutLock.Unlock()
	if i.setTimeoutChan == nil {
		return
	}
	i.setTimeoutChan <- timeout
}
type Connection struct {
	conn   net.Conn
	framer *idleAwareFramer
	closeChan      chan bool
	goneAway       bool
	lastStreamChan chan<- *Stream
	goAwayTimeout  time.Duration
	closeTimeout   time.Duration
	streamLock *sync.RWMutex
	streamCond *sync.Cond
	streams    map[spdy.StreamId]*Stream
	nextIdLock       sync.Mutex
	receiveIdLock    sync.Mutex
	nextStreamId     spdy.StreamId
	receivedStreamId spdy.StreamId
	pingIdLock sync.Mutex
	pingId     uint32
	pingChans  map[uint32]chan error
	shutdownLock sync.Mutex
	shutdownChan chan error
	hasShutdown  bool
	dataFrameHandler func(*spdy.DataFrame) error
}