diff --git a/internal/room/cmddialer.go b/internal/room/cmddialer.go deleted file mode 100644 index 145b1d8..0000000 --- a/internal/room/cmddialer.go +++ /dev/null @@ -1,93 +0,0 @@ -package room - -import ( - "fmt" - "io" - "net" - "time" -) - -type cmdDialer struct { - stdin io.WriteCloser - stdout io.ReadCloser -} - -// Read reads data from the connection. -// Read can be made to time out and return an error after a fixed -// time limit; see SetDeadline and SetReadDeadline. -func (c *cmdDialer) Read(b []byte) (n int, err error) { - n, err = c.stdout.Read(b) - fmt.Printf("Read: %s\n", b) - return -} - -// Write writes data to the connection. -// Write can be made to time out and return an error after a fixed -// time limit; see SetDeadline and SetWriteDeadline. -func (c *cmdDialer) Write(b []byte) (n int, err error) { - fmt.Printf("Write: %s\n", b) - return c.stdin.Write(b) -} - -// Close closes the connection. -// Any blocked Read or Write operations will be unblocked and return errors. -func (c *cmdDialer) Close() error { - if err := c.stdin.Close(); err != nil { - return err - } - return c.stdout.Close() -} - -// LocalAddr returns the local network address, if known. -func (c *cmdDialer) LocalAddr() net.Addr { - return nil -} - -// RemoteAddr returns the remote network address, if known. -func (c *cmdDialer) RemoteAddr() net.Addr { - return nil -} - -// SetDeadline sets the read and write deadlines associated -// with the connection. It is equivalent to calling both -// SetReadDeadline and SetWriteDeadline. -// -// A deadline is an absolute time after which I/O operations -// fail instead of blocking. The deadline applies to all future -// and pending I/O, not just the immediately following call to -// Read or Write. After a deadline has been exceeded, the -// connection can be refreshed by setting a deadline in the future. -// -// If the deadline is exceeded a call to Read or Write or to other -// I/O methods will return an error that wraps os.ErrDeadlineExceeded. -// This can be tested using errors.Is(err, os.ErrDeadlineExceeded). -// The error's Timeout method will return true, but note that there -// are other possible errors for which the Timeout method will -// return true even if the deadline has not been exceeded. -// -// An idle timeout can be implemented by repeatedly extending -// the deadline after successful Read or Write calls. -// -// A zero value for t means I/O operations will not time out. -func (c *cmdDialer) SetDeadline(t time.Time) error { - if err := c.SetReadDeadline(t); err != nil { - return err - } - return c.SetWriteDeadline(t) -} - -// SetReadDeadline sets the deadline for future Read calls -// and any currently-blocked Read call. -// A zero value for t means Read will not time out. -func (c *cmdDialer) SetReadDeadline(t time.Time) error { - return nil -} - -// SetWriteDeadline sets the deadline for future Write calls -// and any currently-blocked Write call. -// Even if write times out, it may return n > 0, indicating that -// some of the data was successfully written. -// A zero value for t means Write will not time out. -func (c *cmdDialer) SetWriteDeadline(t time.Time) error { - return nil -} diff --git a/internal/room/containers.go b/internal/room/containers.go index 683699a..2997c77 100644 --- a/internal/room/containers.go +++ b/internal/room/containers.go @@ -9,9 +9,9 @@ import ( dockerTypes "github.com/docker/docker/api/types" "github.com/docker/docker/api/types/filters" - "github.com/docker/docker/pkg/stdcopy" "github.com/m1k1o/neko-rooms/internal/types" + "github.com/m1k1o/neko-rooms/internal/utils" ) func (manager *RoomManagerCtx) containerToEntry(container dockerTypes.Container) (*types.RoomEntry, error) { @@ -145,8 +145,6 @@ func (manager *RoomManagerCtx) containerExec(id string, cmd []string) ([]byte, e func (manager *RoomManagerCtx) containerExecDialer(id string) func(ctx context.Context, network, addr string) (net.Conn, error) { return func(ctx context.Context, network, addr string) (net.Conn, error) { - fmt.Println("dialer", network, addr) - // split addr host, port, err := net.SplitHostPort(addr) if err != nil { @@ -156,16 +154,17 @@ func (manager *RoomManagerCtx) containerExecDialer(id string) func(ctx context.C exec, err := manager.client.ContainerExecCreate(ctx, id, dockerTypes.ExecConfig{ AttachStdin: true, AttachStdout: true, - AttachStderr: true, - Cmd: []string{"wget", "-O-", "http://" + host + ":" + port + ""}, + AttachStderr: false, + Cmd: []string{"nc", host, port}, Tty: false, Detach: false, }) + if err != nil { return nil, err } - c, err := manager.client.ContainerExecAttach(ctx, exec.ID, dockerTypes.ExecStartCheck{ + res, err := manager.client.ContainerExecAttach(ctx, exec.ID, dockerTypes.ExecStartCheck{ Detach: false, Tty: false, }) @@ -173,22 +172,6 @@ func (manager *RoomManagerCtx) containerExecDialer(id string) func(ctx context.C return nil, err } - // Read all - // io.ReadAll(c.Reader) - dat, err := io.ReadAll(c.Reader) - if err != nil { - return nil, err - } - - fmt.Println("dialer", string(dat)) - - // new pipe - stderr := stdcopy.NewStdWriter(c.Conn, stdcopy.Stderr) - stdout := stdcopy.NewStdWriter(c.Conn, stdcopy.Stdout) - - return &cmdDialer{ - stdin: c.Conn, - stdout: c.Conn, - }, nil + return utils.StdCopyDialer(res), nil } } diff --git a/internal/utils/stdcopydialer.go b/internal/utils/stdcopydialer.go new file mode 100644 index 0000000..050d2fc --- /dev/null +++ b/internal/utils/stdcopydialer.go @@ -0,0 +1,28 @@ +package utils + +import ( + "io" + "net" + + "github.com/docker/docker/api/types" + "github.com/docker/docker/pkg/stdcopy" +) + +type stdCopyDialer struct { + net.Conn + stdout io.ReadCloser +} + +func StdCopyDialer(res types.HijackedResponse) net.Conn { + stdout, dstout := io.Pipe() + go stdcopy.StdCopy(dstout, io.Discard, res.Conn) + + return &stdCopyDialer{ + Conn: res.Conn, + stdout: stdout, + } +} + +func (d *stdCopyDialer) Read(b []byte) (int, error) { + return d.stdout.Read(b) +}