Skip to content

Commit 52a50ed

Browse files
authored
Merge pull request #114 from smallstep/test-fileserver
Add test command step fileserver
2 parents 841c3ec + 7bd0553 commit 52a50ed

File tree

2 files changed

+114
-0
lines changed

2 files changed

+114
-0
lines changed

cmd/step/main.go

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@ import (
2222
_ "github.com/smallstep/cli/command/ca"
2323
_ "github.com/smallstep/cli/command/certificate"
2424
_ "github.com/smallstep/cli/command/crypto"
25+
_ "github.com/smallstep/cli/command/fileserver"
2526
_ "github.com/smallstep/cli/command/oauth"
2627
_ "github.com/smallstep/cli/command/path"
2728

command/fileserver/fileserver.go

Lines changed: 113 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,113 @@
1+
package fileserver
2+
3+
import (
4+
"fmt"
5+
"net"
6+
"net/http"
7+
"os"
8+
9+
"github.com/pkg/errors"
10+
11+
"github.com/smallstep/cli/errs"
12+
13+
"github.com/smallstep/cli/command"
14+
"github.com/urfave/cli"
15+
)
16+
17+
func init() {
18+
cmd := cli.Command{
19+
Name: "fileserver",
20+
Hidden: true,
21+
Action: command.ActionFunc(fileServerAction),
22+
Usage: "start an HTTP(S) server serving the contents of a path",
23+
UsageText: `step fileserver <dir>
24+
[--address=<address>] [--cert=<path>] [--key=<path>]`,
25+
Description: `**step fileserver** command starts an HTTP(S) server serving the contents of a file
26+
system.
27+
28+
This command is experimental and only intended for test purposes.
29+
30+
## POSITIONAL ARGUMENTS
31+
32+
<dir>
33+
: The directory used as root for the HTTP file server.
34+
35+
## EXAMPLES
36+
37+
Start an HTTP file server on port 8080.
38+
'''
39+
$ step fileserver --address :8080 /path/to/root
40+
'''
41+
42+
Start an HTTPS file server on 127.0.0.1:8443.
43+
'''
44+
$ step ca certificate 127.0.0.1 localhost.crt localhost.key
45+
...
46+
$ step fileserver --address 127.0.0.1:8443 \
47+
--cert localhost.crt --key localhost.key /path/to/root
48+
'''`,
49+
Flags: []cli.Flag{
50+
cli.StringFlag{
51+
Name: "address",
52+
Usage: "The TCP <address> to listen on (e.g. \":8443\").",
53+
Value: ":0",
54+
},
55+
cli.StringFlag{
56+
Name: "cert",
57+
Usage: `The <path> to the TLS certificate to use.`,
58+
},
59+
cli.StringFlag{
60+
Name: "key",
61+
Usage: `The <path> to the key corresponding to the certificate.`,
62+
},
63+
},
64+
}
65+
command.Register(cmd)
66+
}
67+
68+
func fileServerAction(ctx *cli.Context) error {
69+
if err := errs.NumberOfArguments(ctx, 1); err != nil {
70+
return err
71+
}
72+
73+
root := ctx.Args().First()
74+
f, err := os.Stat(root)
75+
if err != nil {
76+
return errs.FileError(err, root)
77+
}
78+
if !f.Mode().IsDir() {
79+
return errors.New("positional argument <dir> must be a directory")
80+
}
81+
82+
address := ctx.String("address")
83+
cert := ctx.String("cert")
84+
key := ctx.String("key")
85+
86+
switch {
87+
case address == "":
88+
return errs.RequiredFlag(ctx, "address")
89+
case cert != "" && key == "":
90+
return errs.RequiredWithFlag(ctx, "cert", "key")
91+
case key != "" && cert == "":
92+
return errs.RequiredWithFlag(ctx, "key", "cert")
93+
}
94+
95+
l, err := net.Listen("tcp", address)
96+
if err != nil {
97+
return errors.Wrapf(err, "failed to listen on at %s", address)
98+
}
99+
100+
handler := http.FileServer(http.Dir(root))
101+
if cert != "" && key != "" {
102+
fmt.Printf("Serving HTTPS at %s ...\n", l.Addr().String())
103+
err = http.ServeTLS(l, handler, cert, key)
104+
} else {
105+
fmt.Printf("Serving HTTP at %s...\n", l.Addr().String())
106+
err = http.Serve(l, handler)
107+
}
108+
if err != nil && err != http.ErrServerClosed {
109+
return errors.Wrap(err, "file server failed")
110+
}
111+
112+
return nil
113+
}

0 commit comments

Comments
 (0)