예제 #1
0
파일: example_test.go 프로젝트: droyo/styx
func ExampleDecoder() {
	l, err := net.Listen("tcp", ":564")
	if err != nil {
		log.Fatal(err)
	}
	rwc, err := l.Accept()
	if err != nil {
		log.Fatal(err)
	}

	d := styxproto.NewDecoder(rwc)
	e := styxproto.NewEncoder(rwc)
	for d.Next() {
		switch msg := d.Msg().(type) {
		case styxproto.Tversion:
			log.Printf("Client wants version %s", msg.Version())
			e.Rversion(8192, "9P2000")
		case styxproto.Tread:
			e.Rread(msg.Tag(), []byte("data data"))
		case styxproto.Twrite:
			log.Printf("Receiving %d bytes from client", msg.Count())
			io.Copy(ioutil.Discard, msg)
		}
	}
}
예제 #2
0
파일: conn.go 프로젝트: droyo/styx
func newConn(srv *Server, rwc io.ReadWriteCloser) *conn {
	var msize int64 = styxproto.DefaultMaxSize
	if srv.MaxSize > 0 {
		if srv.MaxSize > styxproto.MinBufSize {
			msize = srv.MaxSize
		} else {
			msize = styxproto.MinBufSize
		}
	}
	var enc *styxproto.Encoder
	var dec *styxproto.Decoder
	if srv.TraceLog != nil {
		enc = tracing.Encoder(rwc, func(m styxproto.Msg) {
			srv.TraceLog.Printf("← %03d %s", m.Tag(), m)
		})
		dec = tracing.Decoder(rwc, func(m styxproto.Msg) {
			srv.TraceLog.Printf("→ %03d %s", m.Tag(), m)
		})
	} else {
		enc = styxproto.NewEncoder(rwc)
		dec = styxproto.NewDecoder(rwc)
	}
	return &conn{
		Decoder:    dec,
		Encoder:    enc,
		srv:        srv,
		rwc:        rwc,
		cx:         context.TODO(),
		msize:      msize,
		sessionFid: util.NewMap(),
		pendingReq: util.NewMap(),
		qidpool:    qidpool.New(),
	}
}
예제 #3
0
파일: server_test.go 프로젝트: droyo/styx
func copyMsg(msg styxproto.Msg) styxproto.Msg {
	var err error

	rd, wr := io.Pipe()
	d := styxproto.NewDecoder(rd)
	go func() {
		_, err = styxproto.Write(wr, msg)
		wr.CloseWithError(err)
	}()
	for d.Next() {
		return d.Msg()
	}
	panic(fmt.Errorf("failed to copy %T message: %s", msg, d.Err()))
}
예제 #4
0
파일: server_test.go 프로젝트: droyo/styx
func messagesFrom(t *testing.T, r io.Reader) chan styxproto.Msg {
	c := make(chan styxproto.Msg)
	input := styxproto.NewDecoder(r)
	go func() {
		for input.Next() {
			if b, ok := input.Msg().(styxproto.BadMessage); ok {
				t.Logf("skipping bad message: %s", b.Err)
			} else {
				c <- copyMsg(input.Msg())
			}
		}
		if input.Err() != nil {
			t.Error("error reading input: ", input.Err())
		}
		close(c)
	}()
	return c
}
예제 #5
0
파일: server_test.go 프로젝트: droyo/styx
func chanServer(t *testing.T, handler Handler) (in, out chan styxproto.Msg) {
	var ln netutil.PipeListener
	// last for one session
	srv := Server{
		Handler:  handler,
		ErrorLog: testLogger{t},
	}
	go srv.Serve(&ln)
	conn, err := ln.Dial()
	if err != nil {
		panic(err)
	}

	// NOTE(droyo) by buffering the channel we allow the server to take
	// in multiple requests without being blocked on sending their responses.
	// This is a compromise between keeping the messages in order and having
	// an infinite buffer depth (such as with goroutine per channel). Good enough
	// for testing.
	out = make(chan styxproto.Msg, 1000)
	in = make(chan styxproto.Msg)

	go func() {
		for req := range in {
			if _, err := styxproto.Write(conn, req); err != nil {
				t.Error(err)
				break
			}
		}
		conn.Close()
	}()
	go func() {
		d := styxproto.NewDecoder(conn)
		for d.Next() {
			out <- copyMsg(d.Msg())
		}
		close(out)
	}()
	return in, out
}