Documentation ¶
Overview ¶
An experimental FTP server framework. By providing a simple driver class that responds to a handful of methods you can have a complete FTP server.
Some sample use cases include persisting data to an Amazon S3 bucket, a relational database, redis or memory.
There is a sample in-memory driver available - see the documentation for the graval-mem package or the graval READEME for more details.
Index ¶
Constants ¶
This section is empty.
Variables ¶
var FtpLogTimeFormat = "2006-01-02 15:04:05"
Functions ¶
func NewDirItem ¶
NewDirItem creates a new os.FileInfo that represents a single diretory. Use this function to build the response to DirContents() in your FTPDriver implementation.
Types ¶
type FTPDriver ¶
type FTPDriver interface { // params - username, password // returns - true if the provided details are valid Authenticate(string, string, string) (bool, error) // params - a file path // returns - an int with the number of bytes in the file or -1 if the file // doesn't exist Bytes(string) (int64, error) // params - a file path // returns - a time indicating when the requested path was last modified // - an error if the file doesn't exist or the user lacks // permissions ModifiedTime(string) (time.Time, error) // params - path // returns - true if the current user is permitted to change to the // requested path ChangeDir(string) (bool, error) // params - path // returns - a collection of items describing the contents of the requested // path DirContents(string) ([]os.FileInfo, error) // params - path // returns - true if the directory was deleted DeleteDir(string) (bool, error) // params - path // returns - true if the file was deleted DeleteFile(string) (bool, error) // params - from_path, to_path // returns - true if the file was renamed Rename(string, string) (bool, error) // params - path // returns - true if the new directory was created MakeDir(string) (bool, error) // params - path // returns - a Reader that will return file data to send to the client GetFile(string) (io.ReadCloser, error) // params - desination path, an io.Reader containing the file data // returns - true if the data was successfully persisted PutFile(string, io.Reader) (bool, error) }
You will create an implementation of this interface that speaks to your chosen persistence layer. graval will create a new instance of your driver for each client that connects and delegate to it as required.
type FTPDriverFactory ¶
For each client that connects to the server, a new FTPDriver is required. Create an implementation if this interface and provide it to FTPServer.
type FTPLogger ¶
type FTPLogger interface { Info(args ...interface{}) Infof(format string, args ...interface{}) Warn(args ...interface{}) Warnf(format string, args ...interface{}) Error(args ...interface{}) Errorf(format string, args ...interface{}) Debug(args ...interface{}) Debugf(format string, args ...interface{}) }
func NewDefaultFtpLogger ¶
func NewDefaultFtpLogger() FTPLogger
func NewDefaultFtpLoggerWithLevel ¶
func NewDefaultFtpLoggerWithLevel(ftpLogLevel FtpLogLevel) FTPLogger
type FTPServer ¶
type FTPServer struct {
// contains filtered or unexported fields
}
FTPServer is the root of your FTP application. You should instantiate one of these and call ListenAndServe() to start accepting client connections.
Always use the NewFTPServer() method to create a new FTPServer.
func NewFTPServer ¶
func NewFTPServer(opts *FTPServerOpts) *FTPServer
NewFTPServer initialises a new FTP server. Configuration options are provided via an instance of FTPServerOpts. Calling this function in your code will probably look something like this:
factory := &MyDriverFactory{} server := graval.NewFTPServer(&graval.FTPServerOpts{ Factory: factory })
or:
factory := &MyDriverFactory{} opts := &graval.FTPServerOpts{ Factory: factory, Port: 2000, Hostname: "127.0.0.1", } server := graval.NewFTPServer(opts)
func (*FTPServer) Close ¶
func (ftpServer *FTPServer) Close()
Close signals the server to stop. It may take a couple of seconds. Do not call ListenAndServe again after this, build a new FTPServer.
func (*FTPServer) ListenAndServe ¶
ListenAndServe asks a new FTPServer to begin accepting client connections. It accepts no arguments - all configuration is provided via the NewFTPServer function.
If the server fails to start for any reason, an error will be returned. Common errors are trying to bind to a privileged port or something else is already listening on the same port.
type FTPServerOpts ¶
type FTPServerOpts struct { // Server name will be used for welcome message ServerName string // The factory that will be used to create a new FTPDriver instance for // each client connection. This is a mandatory option. Factory FTPDriverFactory // The hostname that the FTP server should listen on. Optional, defaults to // "::", which means all hostnames on ipv4 and ipv6. Hostname string // The port that the FTP should listen on. Optional, defaults to 3000. In // a production environment you will probably want to change this to 21. Port uint16 // The lower bound of port numbers that can be used for passive-mode data sockets // Defaults to 0, which allows the server to pick any free port PasvMinPort uint16 // The upper bound of port numbers that can be used for passive-mode data sockets // Defaults to 0, which allows the server to pick any free port PasvMaxPort uint16 // Use this option to override the IP address that will be advertised in response to the // PASV command. Most setups can ignore this, but it can be helpful in situations where // the FTP server is behind a NAT gateway or load balancer and the public IP used by // clients is different to the IP the server is directly listening on PasvAdvertisedIp string // The logger implementation Logger FTPLogger }
serverOpts contains parameters for graval.NewFTPServer()
type FtpLogLevel ¶
type FtpLogLevel int
const ( ErrorLevel FtpLogLevel = iota WarnLevel InfoLevel DebugLevel )
Source Files ¶
Directories ¶
Path | Synopsis |
---|---|
An example FTP server build on top of go-raval.
|
An example FTP server build on top of go-raval. |