Skip to content

Instantly share code, notes, and snippets.

@s-shin
Created June 7, 2017 11:33
Show Gist options
  • Save s-shin/ee5fda02ca720d948b83a401937341e1 to your computer and use it in GitHub Desktop.
Save s-shin/ee5fda02ca720d948b83a401937341e1 to your computer and use it in GitHub Desktop.
package main
import (
"compress/gzip"
"io"
"log"
"net"
)
type hello struct {
msg []byte
r io.Reader
written int
}
func newHello(r io.Reader, name string) *hello {
return &hello{
msg: []byte("Hello, " + name + "!\n"),
r: r,
written: 0,
}
}
func (h *hello) Read(p []byte) (int, error) {
if h.written < len(h.msg) {
n := copy(p, h.msg[h.written:])
h.written += n
return n, nil
}
return h.r.Read(p)
}
type transformer func(r io.Reader) (io.Reader, error)
func transform(r io.Reader, t transformer) io.Reader {
pr, pw := io.Pipe()
go func() {
tr, err := t(r)
if err != nil {
pw.CloseWithError(err)
return
}
_, err = io.Copy(pw, tr)
if err != nil {
pw.CloseWithError(err)
return
}
pw.Close()
}()
return pr
}
func onConnected(c net.Conn) {
defer c.Close()
io.Copy(c, transform(
transform(
c,
func(r io.Reader) (io.Reader, error) {
return gzip.NewReader(r)
},
),
func(r io.Reader) (io.Reader, error) {
return newHello(r, "world"), nil
},
))
}
func main() {
l, err := net.Listen("tcp", ":5000")
if err != nil {
log.Fatal(err)
}
for {
conn, err := l.Accept()
if err != nil {
log.Fatal(err)
}
go onConnected(conn)
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment