// NewSpdyStreamProvider creates a stream provider by starting a spdy // session on the given connection. The server argument is used to // determine whether the spdy connection is the client or server side. func NewSpdyStreamProvider(conn net.Conn, server bool, handler StreamHandler) (streams.StreamProvider, error) { spdyConn, spdyErr := spdystream.NewConnection(conn, server) if spdyErr != nil { return nil, spdyErr } if handler == nil { handler = nilHandler } provider := &spdyStreamProvider{ conn: spdyConn, closeChan: make(chan struct{}), listenChan: make(chan acceptStream), handler: handler, } go spdyConn.Serve(provider.newStreamHandler) go func() { select { case <-spdyConn.CloseChan(): case <-provider.closeChan: } close(provider.listenChan) }() return provider, nil }
// Connect to the Websocket endpoint at ws://localhost // using SPDY over Websockets framing. func ExampleConn() { wsconn, _, _ := websocket.DefaultDialer.Dial("ws://localhost/", http.Header{"Origin": {"http://localhost/"}}) conn, _ := spdystream.NewConnection(NewConnection(wsconn), false) go conn.Serve(spdystream.NoOpStreamHandler, spdystream.NoAuthHandler) stream, _ := conn.CreateStream(http.Header{}, nil, false) stream.Wait() }
func newSession(conn net.Conn, server bool) (*Transport, error) { var referenceCounter uint64 if server { referenceCounter = 2 } else { referenceCounter = 1 } session := &Transport{ receiverChan: make(chan *channel), channelC: sync.NewCond(new(sync.Mutex)), channels: make(map[uint64]*channel), referenceCounter: referenceCounter, byteStreamC: sync.NewCond(new(sync.Mutex)), byteStreams: make(map[uint64]*byteStream), netConnC: sync.NewCond(new(sync.Mutex)), netConns: make(map[byte]map[string]net.Conn), networks: make(map[string]byte), } spdyConn, spdyErr := spdystream.NewConnection(conn, server) if spdyErr != nil { return nil, spdyErr } go spdyConn.Serve(session.newStreamHandler) session.conn = spdyConn session.handler = session.initializeHandler() return session, nil }
func (l *ListenSession) Serve() { for { conn, err := l.listener.Accept() if err != nil { // TODO log break } go func() { authHandler, authErr := l.auth(conn) if authErr != nil { // TODO log conn.Close() return } spdyConn, spdyErr := spdystream.NewConnection(conn, true) if spdyErr != nil { // TODO log conn.Close() return } go spdyConn.Serve(l.streamHandler, authHandler) }() } }
func main() { conn, err := net.Dial("tcp", "localhost:8080") if err != nil { panic(err) } spdyConn, err := spdystream.NewConnection(conn, false) if err != nil { panic(err) } header := http.Header{} header.Add(":method", "GET") header.Add(":path", "/") go spdyConn.Serve(spdystream.NoOpStreamHandler) stream, err := spdyConn.CreateStream(header, nil, false) if err != nil { panic(err) } stream.Wait() fmt.Fprint(stream, "Writing to stream") buf := make([]byte, 25) stream.Read(buf) fmt.Println(string(buf)) stream.Close() }
func spdyClient(c <-chan int) { v := <-c fmt.Printf("this is v %d\n", v) conn, err := net.Dial("tcp", "localhost:8080") if err != nil { panic(err) } spdyConn, err := spdystream.NewConnection(conn, false) if err != nil { panic(err) } go spdyConn.Serve(spdystream.NoOpStreamHandler) stream, err := spdyConn.CreateStream(http.Header{}, nil, false) if err != nil { panic(err) } stream.Wait() fmt.Fprint(stream, "Writing to stream") buf := make([]byte, 25) stream.Read(buf) fmt.Println("reading the response...") fmt.Println(string(buf)) stream.Close() }
// NewServerConnection creates a new SPDY server connection. newStreamHandler // will be invoked when the server receives a newly created stream from the // client. func NewServerConnection(conn net.Conn, newStreamHandler httpstream.NewStreamHandler) (httpstream.Connection, error) { spdyConn, err := spdystream.NewConnection(conn, true) if err != nil { defer conn.Close() return nil, err } return newConnection(spdyConn, newStreamHandler), nil }
// NewClientConnection creates a new SPDY client connection. func NewClientConnection(conn net.Conn) (httpstream.Connection, error) { spdyConn, err := spdystream.NewConnection(conn, false) if err != nil { defer conn.Close() return nil, err } return newConnection(spdyConn, httpstream.NoOpNewStreamHandler), nil }
// NewSpdyStreamProvider creates a stream provider by starting a spdy // session on the given connection. The server argument is used to // determine whether the spdy connection is the client or server side. func NewSpdyStreamProvider(conn net.Conn, server bool) (StreamProvider, error) { spdyConn, spdyErr := spdystream.NewConnection(conn, server) if spdyErr != nil { return nil, spdyErr } provider := &spdyStreamProvider{ conn: spdyConn, closeChan: make(chan struct{}), listenChan: make(chan *spdyStream), } go spdyConn.Serve(provider.newStreamHandler) return provider, nil }
// Create a Beam receiver from a net.Conn func NewServer(conn net.Conn) (*Server, error) { spdyConn, err := spdystream.NewConnection(conn, true) if err != nil { return nil, err } s := &Server{ conn: spdyConn, streamChan: make(chan *spdystream.Stream), subStreamChans: make(map[string]chan *spdystream.Stream), } go s.conn.Serve(s.streamHandler, spdystream.NoAuthHandler) return s, nil }
// NewStreamSession creates a new stream session from the // provided network connection. The network connection is // expected to already provide a tls session. func NewStreamSession(conn net.Conn) (*StreamSession, error) { session := &StreamSession{ streamChan: make(chan *spdystream.Stream), subStreamChans: make(map[string]chan *spdystream.Stream), } spdyConn, spdyErr := spdystream.NewConnection(conn, false) if spdyErr != nil { return nil, spdyErr } go spdyConn.Serve(session.newStreamHandler) session.conn = spdyConn return session, nil }
func main() { listener, err := net.Listen("tcp", "localhost:9090") if err != nil { panic(err) } for { conn, err := listener.Accept() if err != nil { panic(err) } spdyConn, err := spdystream.NewConnection(conn, true) if err != nil { panic(err) } go spdyConn.Serve(spdystream.MirrorStreamHandler) } }
func spdyServer(c chan<- int) { listener, err := net.Listen("tcp", "localhost:8080") if err != nil { panic(err) } c <- 1 fmt.Println("signalled listening") for { conn, err := listener.Accept() if err != nil { panic(err) } spdyConn, err := spdystream.NewConnection(conn, true) if err != nil { panic(err) } go spdyConn.Serve(spdystream.MirrorStreamHandler) } }
func serveWs(w http.ResponseWriter, r *http.Request) { if r.Method != "GET" { http.Error(w, "Method not allowed", 405) return } ws, err := upgrader.Upgrade(w, r, nil) if err != nil { if _, ok := err.(websocket.HandshakeError); !ok { log.Println(err) } return } wrap := NewConnection(ws) spdyConn, err := spdystream.NewConnection(wrap, true) if err != nil { log.Fatal(err) return } serverSpdyConn = spdyConn go spdyConn.Serve(spdystream.MirrorStreamHandler, authStreamHandler) }
func TestSpdyStreamOverWs(t *testing.T) { server := httptest.NewServer(http.HandlerFunc(serveWs)) defer server.Close() defer func() { if serverSpdyConn != nil { serverSpdyConn.Close() } }() wsconn, _, err := websocket.DefaultDialer.Dial(strings.Replace(server.URL, "http://", "ws://", 1), http.Header{"Origin": {server.URL}}) if err != nil { t.Fatal(err) } wrap := NewConnection(wsconn) spdyConn, err := spdystream.NewConnection(wrap, false) if err != nil { defer wsconn.Close() t.Fatal(err) } defer spdyConn.Close() authenticated = true go spdyConn.Serve(spdystream.NoOpStreamHandler, spdystream.RejectAuthHandler) stream, streamErr := spdyConn.CreateStream(http.Header{}, nil, false) if streamErr != nil { t.Fatalf("Error creating stream: %s", streamErr) } waitErr := stream.Wait() if waitErr != nil { t.Fatalf("Error waiting for stream: %s", waitErr) } message := []byte("hello") writeErr := stream.WriteData(message, false) if writeErr != nil { t.Fatalf("Error writing data") } buf := make([]byte, 10) n, readErr := stream.Read(buf) if readErr != nil { t.Fatalf("Error reading data from stream: %s", readErr) } if n != 5 { t.Fatalf("Unexpected number of bytes read:\nActual: %d\nExpected: 5", n) } if bytes.Compare(buf[:n], message) != 0 { t.Fatalf("Did not receive expected message:\nActual: %s\nExpectd: %s", buf, message) } writeErr = stream.WriteData(message, true) if writeErr != nil { t.Fatalf("Error writing data") } smallBuf := make([]byte, 3) n, readErr = stream.Read(smallBuf) if readErr != nil { t.Fatalf("Error reading data from stream: %s", readErr) } if n != 3 { t.Fatalf("Unexpected number of bytes read:\nActual: %d\nExpected: 3", n) } if bytes.Compare(smallBuf[:n], []byte("hel")) != 0 { t.Fatalf("Did not receive expected message:\nActual: %s\nExpectd: %s", smallBuf[:n], message) } n, readErr = stream.Read(smallBuf) if readErr != nil { t.Fatalf("Error reading data from stream: %s", readErr) } if n != 2 { t.Fatalf("Unexpected number of bytes read:\nActual: %d\nExpected: 2", n) } if bytes.Compare(smallBuf[:n], []byte("lo")) != 0 { t.Fatalf("Did not receive expected message:\nActual: %s\nExpected: lo", smallBuf[:n]) } n, readErr = stream.Read(buf) if readErr != io.EOF { t.Fatalf("Expected EOF reading from finished stream, read %d bytes", n) } streamCloseErr := stream.Close() if streamCloseErr != nil { t.Fatalf("Error closing stream: %s", streamCloseErr) } // Closing again should return nil streamCloseErr = stream.Close() if streamCloseErr != nil { t.Fatalf("Error closing stream: %s", streamCloseErr) } authenticated = false badStream, badStreamErr := spdyConn.CreateStream(http.Header{}, nil, false) if badStreamErr != nil { t.Fatalf("Error creating stream: %s", badStreamErr) } waitErr = badStream.Wait() if waitErr == nil { t.Fatalf("Did not receive error creating stream") } if waitErr != spdystream.ErrReset { t.Fatalf("Unexpected error creating stream: %s", waitErr) } spdyCloseErr := spdyConn.Close() if spdyCloseErr != nil { t.Fatalf("Error closing spdy connection: %s", spdyCloseErr) } }
func (t transport) NewConn(nc net.Conn, isServer bool) (pst.Conn, error) { sc, err := ss.NewConnection(nc, isServer) return &conn{sc: sc, closed: make(chan struct{})}, err }