Skip to content

Commit 403657b

Browse files
committed
server: use functional options for NewServer
1 parent 66d9ce1 commit 403657b

File tree

5 files changed

+74
-27
lines changed

5 files changed

+74
-27
lines changed

client_integration_test.go

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,17 @@ func testClientGoSvr(t testing.TB, readonly bool, delay time.Duration) (*Client,
9494
t.Fatal(err)
9595
}
9696

97-
server, err := NewServer(txPipeRd, rxPipeWr, os.Stderr, 0, readonly, ".")
97+
options := []ServerOption{WithDebug(os.Stderr)}
98+
if readonly {
99+
options = append(options, ReadOnly())
100+
}
101+
102+
server, err := NewServer(
103+
txPipeRd,
104+
rxPipeWr,
105+
".",
106+
options...,
107+
)
98108
if err != nil {
99109
t.Fatal(err)
100110
}

examples/sftp-server/main.go

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -19,23 +19,19 @@ import (
1919
func main() {
2020

2121
var (
22-
readOnly bool
23-
debugLevelStr string
24-
debugLevel int
25-
debugStderr bool
26-
rootDir string
22+
readOnly bool
23+
debugStderr bool
24+
rootDir string
2725
)
2826

2927
flag.BoolVar(&readOnly, "R", false, "read-only server")
3028
flag.BoolVar(&debugStderr, "e", false, "debug to stderr")
31-
flag.StringVar(&debugLevelStr, "l", "none", "debug level")
3229
flag.StringVar(&rootDir, "root", "", "root directory")
3330
flag.Parse()
3431

3532
debugStream := ioutil.Discard
3633
if debugStderr {
3734
debugStream = os.Stderr
38-
debugLevel = 1
3935
}
4036

4137
// An SSH server is represented by a ServerConfig, which holds
@@ -124,7 +120,13 @@ func main() {
124120
}
125121
}(requests)
126122

127-
server, err := sftp.NewServer(channel, channel, debugStream, debugLevel, readOnly, rootDir)
123+
server, err := sftp.NewServer(
124+
channel,
125+
channel,
126+
rootDir,
127+
sftp.WithDebug(debugStream),
128+
sftp.ReadOnly(),
129+
)
128130
if err != nil {
129131
log.Fatal(err)
130132
}

server.go

Lines changed: 38 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"encoding"
77
"fmt"
88
"io"
9+
"io/ioutil"
910
"os"
1011
"path/filepath"
1112
"sync"
@@ -26,7 +27,6 @@ type Server struct {
2627
out io.WriteCloser
2728
outMutex *sync.Mutex
2829
debugStream io.Writer
29-
debugLevel int
3030
readOnly bool
3131
rootDir string
3232
lastID uint32
@@ -70,10 +70,12 @@ type serverRespondablePacket interface {
7070
respond(svr *Server) error
7171
}
7272

73-
// NewServer creates a new server instance around the provided streams.
74-
// Various debug output will be written to debugStream, with verbosity set by debugLevel
75-
// A subsequent call to Serve() is required.
76-
func NewServer(in io.Reader, out io.WriteCloser, debugStream io.Writer, debugLevel int, readOnly bool, rootDir string) (*Server, error) {
73+
// NewServer creates a new Server instance around the provided streams, serving
74+
// content from the directory specified by rootDir. Optionally, ServerOption
75+
// functions may be specified to further configure the Server.
76+
//
77+
// A subsequent call to Serve() is required to begin serving files over SFTP.
78+
func NewServer(in io.Reader, out io.WriteCloser, rootDir string, options ...ServerOption) (*Server, error) {
7779
if rootDir == "" {
7880
wd, err := os.Getwd()
7981
if err != nil {
@@ -82,20 +84,46 @@ func NewServer(in io.Reader, out io.WriteCloser, debugStream io.Writer, debugLev
8284

8385
rootDir = wd
8486
}
85-
return &Server{
87+
88+
s := &Server{
8689
in: in,
8790
out: out,
8891
outMutex: &sync.Mutex{},
89-
debugStream: debugStream,
90-
debugLevel: debugLevel,
91-
readOnly: readOnly,
92+
debugStream: ioutil.Discard,
9293
rootDir: rootDir,
9394
pktChan: make(chan rxPacket, sftpServerWorkerCount),
9495
openFiles: map[string]*os.File{},
9596
openFilesLock: &sync.RWMutex{},
9697
maxTxPacket: 1 << 15,
9798
workerCount: sftpServerWorkerCount,
98-
}, nil
99+
}
100+
101+
for _, o := range options {
102+
if err := o(s); err != nil {
103+
return nil, err
104+
}
105+
}
106+
107+
return s, nil
108+
}
109+
110+
// A ServerOption is a function which applies configuration to a Server.
111+
type ServerOption func(*Server) error
112+
113+
// WithDebug enables Server debugging output to the supplied io.Writer.
114+
func WithDebug(w io.Writer) func(*Server) error {
115+
return func(s *Server) error {
116+
s.debugStream = w
117+
return nil
118+
}
119+
}
120+
121+
// ReadOnly configures a Server to serve files in read-only mode.
122+
func ReadOnly() func(*Server) error {
123+
return func(s *Server) error {
124+
s.readOnly = true
125+
return nil
126+
}
99127
}
100128

101129
type rxPacket struct {

server_integration_test.go

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -294,7 +294,12 @@ func (chsvr *sshSessionChannelServer) handleSubsystem(req *ssh.Request) error {
294294
return cmd.Wait()
295295
}
296296

297-
sftpServer, err := NewServer(chsvr.ch, chsvr.ch, sftpServerDebugStream, 0, false, ".")
297+
sftpServer, err := NewServer(
298+
chsvr.ch,
299+
chsvr.ch,
300+
".",
301+
WithDebug(sftpServerDebugStream),
302+
)
298303
if err != nil {
299304
return err
300305
}

server_standalone/main.go

Lines changed: 9 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,24 +14,26 @@ import (
1414

1515
func main() {
1616
var (
17-
readOnly bool
18-
debugLevelStr string
19-
debugLevel int
20-
debugStderr bool
17+
readOnly bool
18+
debugStderr bool
2119
)
2220

2321
flag.BoolVar(&readOnly, "R", false, "read-only server")
2422
flag.BoolVar(&debugStderr, "e", false, "debug to stderr")
25-
flag.StringVar(&debugLevelStr, "l", "none", "debug level")
2623
flag.Parse()
2724

2825
debugStream := ioutil.Discard
2926
if debugStderr {
3027
debugStream = os.Stderr
31-
debugLevel = 1
3228
}
3329

34-
svr, _ := sftp.NewServer(os.Stdin, os.Stdout, debugStream, debugLevel, readOnly, "")
30+
svr, _ := sftp.NewServer(
31+
os.Stdin,
32+
os.Stdout,
33+
"",
34+
sftp.WithDebug(debugStream),
35+
sftp.ReadOnly(),
36+
)
3537
if err := svr.Serve(); err != nil {
3638
fmt.Fprintf(debugStream, "sftp server completed with error: %v", err)
3739
os.Exit(1)

0 commit comments

Comments
 (0)