func (s *Server) serveConnection(conn net.Conn) { defer conn.Close() if s.ReadTimeout != 0 { conn.SetReadTimeout(s.ReadTimeout) } if s.WriteTimeout != 0 { conn.SetWriteTimeout(s.WriteTimeout) } br := bufio.NewReader(conn) for { t := &transaction{ server: s, conn: conn, br: br} if err := t.prepare(); err != nil { if err != os.EOF { log.Println("twister: prepare failed", err) } break } t.invokeHandler() if t.hijacked { return } if err := t.finish(); err != nil { log.Println("twister: finish failed", err) break } if t.closeAfterResponse { break } } }
// prepConn() takes a net.Conn and attaches a file descriptor release in its Close method func (p *Proxy) prepConn(c net.Conn) (net.Conn, os.Error) { c.(*net.TCPConn).SetKeepAlive(true) err := c.SetReadTimeout(p.config.Timeout) if err != nil { log.Printf("Error TCP set read timeout: %s\n", err) c.Close() p.fdl.Unlock() return c, err } err = c.SetWriteTimeout(p.config.Timeout) if err != nil { log.Printf("Error TCP set write timeout: %s\n", err) c.Close() p.fdl.Unlock() return c, err } return util.NewRunOnCloseConn(c, func() { p.fdl.Unlock() }), nil }