Documentation ¶
Overview ¶
http://tools.ietf.org/html/rfc959
http://www.faqs.org/rfcs/rfc2389.html http://www.faqs.org/rfcs/rfc959.html
Index ¶
- func Version() string
- type Auth
- type Command
- type Conn
- type DataSocket
- type Driver
- type DriverFactory
- type FileInfo
- type Logger
- type Perm
- type Server
- type ServerOpts
- type SimplePerm
- func (s *SimplePerm) ChGroup(string, string) error
- func (s *SimplePerm) ChMode(string, os.FileMode) error
- func (s *SimplePerm) ChOwner(string, string) error
- func (s *SimplePerm) GetGroup(string) (string, error)
- func (s *SimplePerm) GetMode(string) (os.FileMode, error)
- func (s *SimplePerm) GetOwner(string) (string, error)
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
Types ¶
type Conn ¶
type Conn struct { LastFilePos int64 // contains filtered or unexported fields }
func (*Conn) Close ¶
func (Conn *Conn) Close()
Close will manually close this connection, even if the client isn't ready.
func (*Conn) CloseDataConn ¶
func (Conn *Conn) CloseDataConn()
func (*Conn) GetDataConn ¶
func (Conn *Conn) GetDataConn() DataSocket
func (*Conn) Serve ¶
func (Conn *Conn) Serve()
Serve starts an endless loop that reads FTP commands from the client and responds appropriately. terminated is a channel that will receive a true message when the connection closes. This loop will be running inside a goroutine, so use this channel to be notified when the connection can be cleaned up.
type DataSocket ¶
type DataSocket interface { Host() string Port() int // the standard io.Reader interface Read(p []byte) (n int, err error) // the standard io.Writer interface Write(p []byte) (n int, err error) // the standard io.Closer interface Close() error }
A data socket is used to send non-control data between the client and server.
type Driver ¶
type Driver interface { // 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 Stat(string) (FileInfo, error) // params - path // returns - true if the current user is permitted to change to the // requested path ChangeDir(string) error // params - path, function on file or subdir found // returns - error // path ListDir(string, string, func(FileInfo) error) error // params - path // returns - true if the directory was deleted DeleteDir(string) error // params - path // returns - true if the file was deleted DeleteFile(string) error // params - from_path, to_path // returns - true if the file was renamed Rename(string, string) error // params - path // returns - true if the new directory was created MakeDir(string) error // params - path // returns - a string containing the file data to send to the client GetFile(string, string, int64) (int64, io.ReadCloser, error) ServeFileToSocket(string, string, *Conn) error // params - desination path, an io.Reader containing the file data // returns - true if the data was successfully persisted PutFile(string, string, io.Reader, bool) (int64, 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 DriverFactory ¶
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 Logger ¶
type Logger struct {
// contains filtered or unexported fields
}
Use an instance of this to log in a standard format
func (*Logger) PrintCommand ¶
func (*Logger) PrintResponse ¶
type Server ¶
type Server struct { *ServerOpts // contains filtered or unexported fields }
Server is the root of your FTP application. You should instantiate one of these and call ListenAndServe() to start accepting client connections.
Always use the NewServer() method to create a new Server.
func NewServer ¶
func NewServer(opts *ServerOpts) *Server
NewServer initialises a new FTP server. Configuration options are provided via an instance of ServerOpts. Calling this function in your code will probably look something like this:
factory := &MyDriverFactory{} server := server.NewServer(&server.ServerOpts{ Factory: factory })
or:
factory := &MyDriverFactory{} opts := &server.ServerOpts{ Factory: factory, Port: 2000, Hostname: "127.0.0.1", } server := server.NewServer(opts)
func (*Server) ListenAndServe ¶
ListenAndServe asks a new Server to begin accepting client connections. It accepts no arguments - all configuration is provided via the NewServer 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 ServerOpts ¶
type ServerOpts struct { // The factory that will be used to create a new FTPDriver instance for // each client connection. This is a mandatory option. Factory DriverFactory Auth Auth // Server Name, Default is Go Ftp Server Name string // 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 int // use tls, default is false TLS bool // if tls used, cert file is required CertFile string // if tls used, key file is required KeyFile string WelcomeMessage string }
serverOpts contains parameters for server.NewServer()
type SimplePerm ¶
type SimplePerm struct {
// contains filtered or unexported fields
}
func NewSimplePerm ¶
func NewSimplePerm(owner, group string) *SimplePerm