netboot/tftp/handlers.go
David Anderson af8e62003b Implement a read-only TFTP server.
Testing is done against the atftp client.
2016-02-18 00:41:31 -08:00

45 lines
1.1 KiB
Go

package tftp
import (
"bytes"
"fmt"
"io"
"io/ioutil"
"net"
"os"
"path/filepath"
)
// FilesystemHandler returns a Handler that serves files in root.
func FilesystemHandler(root string) (Handler, error) {
root, err := filepath.Abs(root)
if err != nil {
return nil, err
}
root = filepath.ToSlash(root)
return func(path string, addr net.Addr) (io.ReadCloser, error) {
// Join with a root, which gets rid of directory traversal
// attempts. Then we join that canonicalized path with the
// actual root, which resolves to the actual on-disk file to
// serve.
path = filepath.Join("/", path)
path = filepath.FromSlash(filepath.Join(root, path))
st, err := os.Stat(path)
if err != nil {
return nil, err
}
if !st.Mode().IsRegular() {
return nil, fmt.Errorf("requested path %q is not a file", path)
}
return os.Open(path)
}, nil
}
// ConstantHandler returns a Handler that serves bs for all requested paths.
func ConstantHandler(bs []byte) Handler {
return func(path string, addr net.Addr) (io.ReadCloser, error) {
return ioutil.NopCloser(bytes.NewBuffer(bs)), nil
}
}