96 lines
2.1 KiB
Go
96 lines
2.1 KiB
Go
package api
|
|
|
|
import (
|
|
"io"
|
|
"net"
|
|
)
|
|
|
|
// Transport is an interface for accepting connections from API clients.
|
|
type Transport interface {
|
|
// Accept waits for and returns the next connection.
|
|
Accept() (io.ReadWriteCloser, error)
|
|
// Close stops the transport from accepting new connections.
|
|
Close() error
|
|
}
|
|
|
|
// PipeTransport accepts connections on a Unix domain socket or Windows named pipe.
|
|
type PipeTransport struct {
|
|
listener net.Listener
|
|
}
|
|
|
|
// NewPipeTransport creates a new transport listening on the given path.
|
|
// On Unix, this creates a Unix domain socket. On Windows, this creates a named pipe.
|
|
func NewPipeTransport(path string) (*PipeTransport, error) {
|
|
listener, err := newPipeListener(path)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return &PipeTransport{listener: listener}, nil
|
|
}
|
|
|
|
// Accept implements Transport.
|
|
func (t *PipeTransport) Accept() (io.ReadWriteCloser, error) {
|
|
return t.listener.Accept()
|
|
}
|
|
|
|
// Close implements Transport.
|
|
func (t *PipeTransport) Close() error {
|
|
return t.listener.Close()
|
|
}
|
|
|
|
// Path returns the path of the pipe/socket.
|
|
func (t *PipeTransport) Path() string {
|
|
return t.listener.Addr().String()
|
|
}
|
|
|
|
// StdioTransport wraps stdin/stdout as a single connection transport.
|
|
// It only accepts one connection.
|
|
type StdioTransport struct {
|
|
stdin io.ReadCloser
|
|
stdout io.WriteCloser
|
|
used bool
|
|
}
|
|
|
|
// NewStdioTransport creates a transport using the given stdin/stdout.
|
|
func NewStdioTransport(stdin io.ReadCloser, stdout io.WriteCloser) *StdioTransport {
|
|
return &StdioTransport{
|
|
stdin: stdin,
|
|
stdout: stdout,
|
|
}
|
|
}
|
|
|
|
// Accept implements Transport.
|
|
func (t *StdioTransport) Accept() (io.ReadWriteCloser, error) {
|
|
if t.used {
|
|
return nil, io.EOF
|
|
}
|
|
t.used = true
|
|
return &stdioConn{
|
|
Reader: t.stdin,
|
|
Writer: t.stdout,
|
|
stdin: t.stdin,
|
|
stdout: t.stdout,
|
|
}, nil
|
|
}
|
|
|
|
// Close implements Transport.
|
|
func (t *StdioTransport) Close() error {
|
|
return nil
|
|
}
|
|
|
|
type stdioConn struct {
|
|
io.Reader
|
|
io.Writer
|
|
stdin io.ReadCloser
|
|
stdout io.WriteCloser
|
|
}
|
|
|
|
func (c *stdioConn) Close() error {
|
|
err1 := c.stdin.Close()
|
|
err2 := c.stdout.Close()
|
|
if err1 != nil {
|
|
return err1
|
|
}
|
|
return err2
|
|
}
|