bftp

package
v0.0.0-...-c113072 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 8, 2023 License: MIT, MIT Imports: 27 Imported by: 0

README

server

Build Status

A FTP server framework forked from github.com/yob/graval and changed a lot.

Full documentation for the package is available on godoc

Installation

go get goftp.io/server/v1

Usage

To boot a FTP server you will need to provide a driver that speaks to your persistence layer - the required driver contract is in the documentation.

Look at the file driver to see an example of how to build a backend.

There is a sample ftp server as a demo. You can build it with this command:

go install goftp.io/ftpd

And finally, connect to the server with any FTP client and the following details:

host: 127.0.0.1
port: 2121
username: admin
password: 123456

This uses the file driver mentioned above to serve files.

Contact us

You can contact us via discord https://discord.gg/ytmYqfNfqh or QQ群 972357369

Contributors

see https://gitea.com/goftp/server/graphs/contributors

Warning

FTP is an incredibly insecure protocol. Be careful about forcing users to authenticate with an username or password that are important.

License

This library is distributed under the terms of the MIT License. See the included file for more detail.

Contributing

All suggestions and patches welcome, preferably via a git repository I can pull from. If this library proves useful to you, please let me know.

Further Reading

There are a range of RFCs that together specify the FTP protocol. In chronological order, the more useful ones are:

For an english summary that's somewhat more legible than the RFCs, and provides some commentary on what features are actually useful or relevant 24 years after RFC959 was published:

For a history lesson, check out Appendix III of RCF959. It lists the preceding (obsolete) RFC documents that relate to file transfers, including the ye old RFC114 from 1971, "A File Transfer Protocol"

This library is heavily based on em-ftpd, an FTPd framework with similar design goals within the ruby and EventMachine ecosystems. It worked well enough, but you know, callbacks and event loops make me something something.

Documentation

Index

Constants

View Source
const (
	CODE_FILE_STATUS_OK              = 150 // 文件状态正常,准备打开数据连接
	CODE_COMMAND_OK                  = 200 // 命令执行成功
	CODE_COMMAND_IMPLEMENTED         = 202 // 命令未实现
	CODE_SYSTEM_STATUS               = 211 // 系统状态
	CODE_DIR_STATUS                  = 212 // 目录状态
	CODE_FILE_STATUS                 = 213 // 文件状态
	CODE_HELP_MESSAGE                = 214 // 帮助消息
	CODE_NAME_SYSTEM_TYPE            = 215 // NAME系统类型
	CODE_SERVICE_READY               = 220 // 服务已经准备就绪
	CODE_CLOSE_CONN                  = 221 // 服务关闭控制连接
	CODE_DATA_CONN_OPEN              = 225 // 数据连接打开,没有进行中的传输
	CODE_DATA_CONN_CLOSE             = 226 // 关闭数据连接。请求的文件操作已经成功执行
	CODE_ENTER_PASV                  = 227 // 进入被动模式
	CODE_USER_LOGINED                = 230 // 用户已经登录,继续执行
	CODE_TLS_AUTH_OK                 = 234 // TLS授权成功
	CODE_FILE_COMMANG_OK             = 250 // 请求的文件操作正确,已完成
	CODE_PATHNAME_CREATED            = 257 // PATHNAME已创建
	CODE_NEED_PASS                   = 331 // 用户名正确,需要密码
	CODE_NEED_ACCOUNT                = 332 // 需要用户名
	CODE_NEED_NEXT                   = 350 // 请求的文件操作需要进一步命令
	CODE_SRV_NO_AVAI                 = 421 // 服务不可用,关闭控制连接
	CODE_FAILED_OPEN_DATA_CONN       = 425 // 不能打开数据连接
	CODE_CONN_CLOSED                 = 426 // 连接被关闭,中止传输
	CODE_FILE_ACTION_NOTAKEN         = 450 // 文件操作未执行
	CODE_LOCAL_ERROR                 = 451 // 终止请求的操作:有本地错误
	CODE_STORAGE_SPACE_INSUFFICIENT  = 452 // 未执行请求的操作:存储空间不足
	CODE_COMMAND_ERROR               = 500 // 命令错误,未找到次命令的实现
	CODE_PARAM_ERROR                 = 500 // 参数错误
	CODE_CMD_IMPLEMENTED             = 502 // 命令未实现
	CODE_BAD_SEQ                     = 503 // 命令执行顺序错误
	CODE_CMD_IMPLEMENTED_WITH_PARAM  = 504 // 此参数下的命令功能未实现
	CODE_UNLOGIN                     = 530 // 未登录
	CODE_NEED_ACCOUNT_FOR_STOR_FILE  = 532 // 存储文件需要账户
	CODE_ACTION_NOTAKEN              = 550 // 未执行请求的操作
	CODE_ACTION_ABORTED              = 551 // 请求操作终止:页类型未知
	CODE_FILE_ACTION_ABORTED         = 552 // 请求文件操作终止,存储分配溢出
	CODE_ACTION_NOTAKEN_WITH_UNALLOW = 553 // 未执行请求的操作。不允许的文件名。
)
View Source
const (
	StatusInitiating    = 100
	StatusRestartMarker = 110
	StatusReadyMinute   = 120
	StatusAlreadyOpen   = 125
	StatusAboutToSend   = 150

	StatusCommandOK             = 200
	StatusCommandNotImplemented = 202
	StatusSystem                = 211
	StatusDirectory             = 212
	StatusFile                  = 213
	StatusHelp                  = 214
	StatusName                  = 215
	StatusReady                 = 220
	StatusClosing               = 221
	StatusDataConnectionOpen    = 225
	StatusClosingDataConnection = 226
	StatusPassiveMode           = 227
	StatusLongPassiveMode       = 228
	StatusExtendedPassiveMode   = 229
	StatusLoggedIn              = 230
	StatusLoggedOut             = 231
	StatusLogoutAck             = 232
	StatusAuthOK                = 234
	StatusRequestedFileActionOK = 250
	StatusPathCreated           = 257

	StatusUserOK             = 331
	StatusLoginNeedAccount   = 332
	StatusRequestFilePending = 350

	StatusNotAvailable             = 421
	StatusCanNotOpenDataConnection = 425
	StatusTransfertAborted         = 426
	StatusInvalidCredentials       = 430
	StatusHostUnavailable          = 434
	StatusFileActionIgnored        = 450
	StatusActionAborted            = 451
	Status452                      = 452

	StatusBadCommand              = 500
	StatusBadArguments            = 501
	StatusNotImplemented          = 502
	StatusBadSequence             = 503
	StatusNotImplementedParameter = 504
	StatusNotLoggedIn             = 530
	StatusStorNeedAccount         = 532
	StatusFileUnavailable         = 550
	StatusPageTypeUnknown         = 551
	StatusExceededStorage         = 552
	StatusBadFileName             = 553
)

Variables

View Source
var ErrServerClosed = errors.New("ftp: Server closed")

ErrServerClosed is returned by ListenAndServe() or Serve() when a shutdown was requested.

Functions

func DefaultCommands

func DefaultCommands() map[string]Command

DefaultCommands returns the default Commands

Types

type Account

type Account struct {
	Name     string
	Password string
	Putable  bool // 是否具有上传权限
	Readable bool // 是否具有下载权限
	Deleable bool // 是否具有下载权限
}

type Auth

type Auth interface {
	CheckPasswd(*Context, string, string) (bool, error)
	Register(account Account)
	Update(account Account)
	Delete(name string)
	IsPutable(ctx *Context, name string) bool
	IsReadable(ctx *Context, name string) bool
	IsDeleable(ctx *Context, name string) bool
}

Auth is an interface to auth your ftp user login.

type BlogLogger

type BlogLogger struct{}

func (*BlogLogger) Print

func (logger *BlogLogger) Print(sessionID string, message interface{})

Print implements Logger

func (*BlogLogger) PrintCommand

func (logger *BlogLogger) PrintCommand(sessionID string, command string, params string)

PrintCommand implements Logger

func (*BlogLogger) PrintResponse

func (logger *BlogLogger) PrintResponse(sessionID string, code int, message string)

PrintResponse implements Logger

func (*BlogLogger) Printf

func (logger *BlogLogger) Printf(sessionID string, format string, v ...interface{})

Printf implements Logger

type Command

type Command interface {
	IsExtend() bool
	RequireParam() bool
	RequireAuth() bool
	Execute(*Session, string)
}

Command represents a Command interface to a ftp Command

type CommandAdat

type CommandAdat struct{}

func (CommandAdat) Execute

func (cmd CommandAdat) Execute(sess *Session, param string)

func (CommandAdat) IsExtend

func (cmd CommandAdat) IsExtend() bool

func (CommandAdat) RequireAuth

func (cmd CommandAdat) RequireAuth() bool

func (CommandAdat) RequireParam

func (cmd CommandAdat) RequireParam() bool

type CommandAllo

type CommandAllo struct{}

commandAllo responds to the ALLO FTP command.

This is essentially a ping from the client so we just respond with an basic OK message.

func (CommandAllo) Execute

func (cmd CommandAllo) Execute(sess *Session, param string)

func (CommandAllo) IsExtend

func (cmd CommandAllo) IsExtend() bool

func (CommandAllo) RequireAuth

func (cmd CommandAllo) RequireAuth() bool

func (CommandAllo) RequireParam

func (cmd CommandAllo) RequireParam() bool

type CommandAppe

type CommandAppe struct{}

CommandAppe responds to the APPE FTP Command. It allows the user to upload a new file but always append if file exists otherwise create one.

func (CommandAppe) Execute

func (cmd CommandAppe) Execute(sess *Session, param string)

func (CommandAppe) IsExtend

func (cmd CommandAppe) IsExtend() bool

func (CommandAppe) RequireAuth

func (cmd CommandAppe) RequireAuth() bool

func (CommandAppe) RequireParam

func (cmd CommandAppe) RequireParam() bool

type CommandAuth

type CommandAuth struct{}

func (CommandAuth) Execute

func (cmd CommandAuth) Execute(sess *Session, param string)

func (CommandAuth) IsExtend

func (cmd CommandAuth) IsExtend() bool

func (CommandAuth) RequireAuth

func (cmd CommandAuth) RequireAuth() bool

func (CommandAuth) RequireParam

func (cmd CommandAuth) RequireParam() bool

type CommandCLNT

type CommandCLNT struct{}

func (CommandCLNT) Execute

func (cmd CommandCLNT) Execute(sess *Session, param string)

func (CommandCLNT) IsExtend

func (cmd CommandCLNT) IsExtend() bool

func (CommandCLNT) RequireAuth

func (cmd CommandCLNT) RequireAuth() bool

func (CommandCLNT) RequireParam

func (cmd CommandCLNT) RequireParam() bool

type CommandCcc

type CommandCcc struct{}

func (CommandCcc) Execute

func (cmd CommandCcc) Execute(sess *Session, param string)

func (CommandCcc) IsExtend

func (cmd CommandCcc) IsExtend() bool

func (CommandCcc) RequireAuth

func (cmd CommandCcc) RequireAuth() bool

func (CommandCcc) RequireParam

func (cmd CommandCcc) RequireParam() bool

type CommandCdup

type CommandCdup struct{}

cmdCdup responds to the CDUP FTP Command.

Allows the client change their current directory to the parent.

func (CommandCdup) Execute

func (cmd CommandCdup) Execute(sess *Session, param string)

func (CommandCdup) IsExtend

func (cmd CommandCdup) IsExtend() bool

func (CommandCdup) RequireAuth

func (cmd CommandCdup) RequireAuth() bool

func (CommandCdup) RequireParam

func (cmd CommandCdup) RequireParam() bool

type CommandConf

type CommandConf struct{}

func (CommandConf) Execute

func (cmd CommandConf) Execute(sess *Session, param string)

func (CommandConf) IsExtend

func (cmd CommandConf) IsExtend() bool

func (CommandConf) RequireAuth

func (cmd CommandConf) RequireAuth() bool

func (CommandConf) RequireParam

func (cmd CommandConf) RequireParam() bool

type CommandCwd

type CommandCwd struct{}

CommandCwd responds to the CWD FTP Command. It allows the client to change the current working directory.

func (CommandCwd) Execute

func (cmd CommandCwd) Execute(sess *Session, param string)

func (CommandCwd) IsExtend

func (cmd CommandCwd) IsExtend() bool

func (CommandCwd) RequireAuth

func (cmd CommandCwd) RequireAuth() bool

func (CommandCwd) RequireParam

func (cmd CommandCwd) RequireParam() bool

type CommandDele

type CommandDele struct{}

CommandDele responds to the DELE FTP Command. It allows the client to delete a file

func (CommandDele) Execute

func (cmd CommandDele) Execute(sess *Session, param string)

func (CommandDele) IsExtend

func (cmd CommandDele) IsExtend() bool

func (CommandDele) RequireAuth

func (cmd CommandDele) RequireAuth() bool

func (CommandDele) RequireParam

func (cmd CommandDele) RequireParam() bool

type CommandEnc

type CommandEnc struct{}

func (CommandEnc) Execute

func (cmd CommandEnc) Execute(sess *Session, param string)

func (CommandEnc) IsExtend

func (cmd CommandEnc) IsExtend() bool

func (CommandEnc) RequireAuth

func (cmd CommandEnc) RequireAuth() bool

func (CommandEnc) RequireParam

func (cmd CommandEnc) RequireParam() bool

type CommandEprt

type CommandEprt struct{}

CommandEprt responds to the EPRT FTP Command. It allows the client to request an active data socket with more options than the original PORT Command. It mainly adds ipv6 support.

func (CommandEprt) Execute

func (cmd CommandEprt) Execute(sess *Session, param string)

func (CommandEprt) IsExtend

func (cmd CommandEprt) IsExtend() bool

func (CommandEprt) RequireAuth

func (cmd CommandEprt) RequireAuth() bool

func (CommandEprt) RequireParam

func (cmd CommandEprt) RequireParam() bool

type CommandEpsv

type CommandEpsv struct{}

CommandEpsv responds to the EPSV FTP Command. It allows the client to request a passive data socket with more options than the original PASV Command. It mainly adds ipv6 support, although we don't support that yet.

func (CommandEpsv) Execute

func (cmd CommandEpsv) Execute(sess *Session, param string)

func (CommandEpsv) IsExtend

func (cmd CommandEpsv) IsExtend() bool

func (CommandEpsv) RequireAuth

func (cmd CommandEpsv) RequireAuth() bool

func (CommandEpsv) RequireParam

func (cmd CommandEpsv) RequireParam() bool

type CommandFeat

type CommandFeat struct{}

func (CommandFeat) Execute

func (cmd CommandFeat) Execute(sess *Session, param string)

func (CommandFeat) IsExtend

func (cmd CommandFeat) IsExtend() bool

func (CommandFeat) RequireAuth

func (cmd CommandFeat) RequireAuth() bool

func (CommandFeat) RequireParam

func (cmd CommandFeat) RequireParam() bool

type CommandList

type CommandList struct{}

CommandList responds to the LIST FTP Command. It allows the client to retrieve a detailed listing of the contents of a directory.

func (CommandList) Execute

func (cmd CommandList) Execute(sess *Session, param string)

func (CommandList) IsExtend

func (cmd CommandList) IsExtend() bool

func (CommandList) RequireAuth

func (cmd CommandList) RequireAuth() bool

func (CommandList) RequireParam

func (cmd CommandList) RequireParam() bool

type CommandLprt

type CommandLprt struct{}

CommandLprt responds to the LPRT FTP Command. It allows the client to request an active data socket with more options than the original PORT Command. FTP Operation Over Big Address Records.

func (CommandLprt) Execute

func (cmd CommandLprt) Execute(sess *Session, param string)

func (CommandLprt) IsExtend

func (cmd CommandLprt) IsExtend() bool

func (CommandLprt) RequireAuth

func (cmd CommandLprt) RequireAuth() bool

func (CommandLprt) RequireParam

func (cmd CommandLprt) RequireParam() bool

type CommandMLSD

type CommandMLSD struct{}

func (CommandMLSD) Execute

func (cmd CommandMLSD) Execute(sess *Session, param string)

func (CommandMLSD) IsExtend

func (cmd CommandMLSD) IsExtend() bool

func (CommandMLSD) RequireAuth

func (cmd CommandMLSD) RequireAuth() bool

func (CommandMLSD) RequireParam

func (cmd CommandMLSD) RequireParam() bool

type CommandMdtm

type CommandMdtm struct{}

CommandMdtm responds to the MDTM FTP Command. It allows the client to retreive the last modified time of a file.

func (CommandMdtm) Execute

func (cmd CommandMdtm) Execute(sess *Session, param string)

func (CommandMdtm) IsExtend

func (cmd CommandMdtm) IsExtend() bool

func (CommandMdtm) RequireAuth

func (cmd CommandMdtm) RequireAuth() bool

func (CommandMdtm) RequireParam

func (cmd CommandMdtm) RequireParam() bool

type CommandMic

type CommandMic struct{}

func (CommandMic) Execute

func (cmd CommandMic) Execute(sess *Session, param string)

func (CommandMic) IsExtend

func (cmd CommandMic) IsExtend() bool

func (CommandMic) RequireAuth

func (cmd CommandMic) RequireAuth() bool

func (CommandMic) RequireParam

func (cmd CommandMic) RequireParam() bool

type CommandMkd

type CommandMkd struct{}

CommandMkd responds to the MKD FTP Command. It allows the client to create a new directory

func (CommandMkd) Execute

func (cmd CommandMkd) Execute(sess *Session, param string)

func (CommandMkd) IsExtend

func (cmd CommandMkd) IsExtend() bool

func (CommandMkd) RequireAuth

func (cmd CommandMkd) RequireAuth() bool

func (CommandMkd) RequireParam

func (cmd CommandMkd) RequireParam() bool

type CommandMode

type CommandMode struct{}

cmdMode responds to the MODE FTP Command.

the original FTP spec had various options for hosts to negotiate how data would be sent over the data socket, In reality these days (S)tream mode is all that is used for the mode - data is just streamed down the data socket unchanged.

func (CommandMode) Execute

func (cmd CommandMode) Execute(sess *Session, param string)

func (CommandMode) IsExtend

func (cmd CommandMode) IsExtend() bool

func (CommandMode) RequireAuth

func (cmd CommandMode) RequireAuth() bool

func (CommandMode) RequireParam

func (cmd CommandMode) RequireParam() bool

type CommandNlst

type CommandNlst struct{}

CommandNlst responds to the NLST FTP Command. It allows the client to retrieve a list of filenames in the current directory.

func (CommandNlst) Execute

func (cmd CommandNlst) Execute(sess *Session, param string)

func (CommandNlst) IsExtend

func (cmd CommandNlst) IsExtend() bool

func (CommandNlst) RequireAuth

func (cmd CommandNlst) RequireAuth() bool

func (CommandNlst) RequireParam

func (cmd CommandNlst) RequireParam() bool

type CommandNoop

type CommandNoop struct{}

cmdNoop responds to the NOOP FTP Command.

This is essentially a ping from the client so we just respond with an basic 200 message.

func (CommandNoop) Execute

func (cmd CommandNoop) Execute(sess *Session, param string)

func (CommandNoop) IsExtend

func (cmd CommandNoop) IsExtend() bool

func (CommandNoop) RequireAuth

func (cmd CommandNoop) RequireAuth() bool

func (CommandNoop) RequireParam

func (cmd CommandNoop) RequireParam() bool

type CommandOpts

type CommandOpts struct{}

func (CommandOpts) Execute

func (cmd CommandOpts) Execute(sess *Session, param string)

func (CommandOpts) IsExtend

func (cmd CommandOpts) IsExtend() bool

func (CommandOpts) RequireAuth

func (cmd CommandOpts) RequireAuth() bool

func (CommandOpts) RequireParam

func (cmd CommandOpts) RequireParam() bool

type CommandPass

type CommandPass struct{}

CommandPass respond to the PASS FTP Command by asking the driver if the supplied username and password are valid

func (CommandPass) Execute

func (cmd CommandPass) Execute(sess *Session, param string)

func (CommandPass) IsExtend

func (cmd CommandPass) IsExtend() bool

func (CommandPass) RequireAuth

func (cmd CommandPass) RequireAuth() bool

func (CommandPass) RequireParam

func (cmd CommandPass) RequireParam() bool

type CommandPasv

type CommandPasv struct{}

CommandPasv responds to the PASV FTP Command.

The client is requesting us to open a new TCP listing socket and wait for them to connect to it.

func (CommandPasv) Execute

func (cmd CommandPasv) Execute(sess *Session, param string)

func (CommandPasv) IsExtend

func (cmd CommandPasv) IsExtend() bool

func (CommandPasv) RequireAuth

func (cmd CommandPasv) RequireAuth() bool

func (CommandPasv) RequireParam

func (cmd CommandPasv) RequireParam() bool

type CommandPbsz

type CommandPbsz struct{}

func (CommandPbsz) Execute

func (cmd CommandPbsz) Execute(sess *Session, param string)

func (CommandPbsz) IsExtend

func (cmd CommandPbsz) IsExtend() bool

func (CommandPbsz) RequireAuth

func (cmd CommandPbsz) RequireAuth() bool

func (CommandPbsz) RequireParam

func (cmd CommandPbsz) RequireParam() bool

type CommandPort

type CommandPort struct{}

CommandPort responds to the PORT FTP Command.

The client has opened a listening socket for sending out of band data and is requesting that we connect to it

func (CommandPort) Execute

func (cmd CommandPort) Execute(sess *Session, param string)

func (CommandPort) IsExtend

func (cmd CommandPort) IsExtend() bool

func (CommandPort) RequireAuth

func (cmd CommandPort) RequireAuth() bool

func (CommandPort) RequireParam

func (cmd CommandPort) RequireParam() bool

type CommandProt

type CommandProt struct{}

func (CommandProt) Execute

func (cmd CommandProt) Execute(sess *Session, param string)

func (CommandProt) IsExtend

func (cmd CommandProt) IsExtend() bool

func (CommandProt) RequireAuth

func (cmd CommandProt) RequireAuth() bool

func (CommandProt) RequireParam

func (cmd CommandProt) RequireParam() bool

type CommandPwd

type CommandPwd struct{}

CommandPwd responds to the PWD FTP Command.

Tells the client what the current working directory is.

func (CommandPwd) Execute

func (cmd CommandPwd) Execute(sess *Session, param string)

func (CommandPwd) IsExtend

func (cmd CommandPwd) IsExtend() bool

func (CommandPwd) RequireAuth

func (cmd CommandPwd) RequireAuth() bool

func (CommandPwd) RequireParam

func (cmd CommandPwd) RequireParam() bool

type CommandQuit

type CommandQuit struct{}

CommandQuit responds to the QUIT FTP Command. The client has requested the connection be closed.

func (CommandQuit) Execute

func (cmd CommandQuit) Execute(sess *Session, param string)

func (CommandQuit) IsExtend

func (cmd CommandQuit) IsExtend() bool

func (CommandQuit) RequireAuth

func (cmd CommandQuit) RequireAuth() bool

func (CommandQuit) RequireParam

func (cmd CommandQuit) RequireParam() bool

type CommandRest

type CommandRest struct{}

func (CommandRest) Execute

func (cmd CommandRest) Execute(sess *Session, param string)

func (CommandRest) IsExtend

func (cmd CommandRest) IsExtend() bool

func (CommandRest) RequireAuth

func (cmd CommandRest) RequireAuth() bool

func (CommandRest) RequireParam

func (cmd CommandRest) RequireParam() bool

type CommandRetr

type CommandRetr struct{}

CommandRetr responds to the RETR FTP Command. It allows the client to download a file. REST can be followed by APPE, STOR, or RETR

func (CommandRetr) Execute

func (cmd CommandRetr) Execute(sess *Session, param string)

func (CommandRetr) IsExtend

func (cmd CommandRetr) IsExtend() bool

func (CommandRetr) RequireAuth

func (cmd CommandRetr) RequireAuth() bool

func (CommandRetr) RequireParam

func (cmd CommandRetr) RequireParam() bool

type CommandRmd

type CommandRmd struct{}

cmdRmd responds to the RMD FTP Command. It allows the client to delete a directory.

func (CommandRmd) Execute

func (cmd CommandRmd) Execute(sess *Session, param string)

func (CommandRmd) IsExtend

func (cmd CommandRmd) IsExtend() bool

func (CommandRmd) RequireAuth

func (cmd CommandRmd) RequireAuth() bool

func (CommandRmd) RequireParam

func (cmd CommandRmd) RequireParam() bool

type CommandRnfr

type CommandRnfr struct{}

CommandRnfr responds to the RNFR FTP Command. It's the first of two Commands required for a client to rename a file.

func (CommandRnfr) Execute

func (cmd CommandRnfr) Execute(sess *Session, param string)

func (CommandRnfr) IsExtend

func (cmd CommandRnfr) IsExtend() bool

func (CommandRnfr) RequireAuth

func (cmd CommandRnfr) RequireAuth() bool

func (CommandRnfr) RequireParam

func (cmd CommandRnfr) RequireParam() bool

type CommandRnto

type CommandRnto struct{}

cmdRnto responds to the RNTO FTP Command. It's the second of two Commands required for a client to rename a file.

func (CommandRnto) Execute

func (cmd CommandRnto) Execute(sess *Session, param string)

func (CommandRnto) IsExtend

func (cmd CommandRnto) IsExtend() bool

func (CommandRnto) RequireAuth

func (cmd CommandRnto) RequireAuth() bool

func (CommandRnto) RequireParam

func (cmd CommandRnto) RequireParam() bool

type CommandSize

type CommandSize struct{}

CommandSize responds to the SIZE FTP Command. It returns the size of the requested path in bytes.

func (CommandSize) Execute

func (cmd CommandSize) Execute(sess *Session, param string)

func (CommandSize) IsExtend

func (cmd CommandSize) IsExtend() bool

func (CommandSize) RequireAuth

func (cmd CommandSize) RequireAuth() bool

func (CommandSize) RequireParam

func (cmd CommandSize) RequireParam() bool

type CommandStat

type CommandStat struct{}

CommandStat responds to the STAT FTP Command. It returns the stat of the requested path.

func (CommandStat) Execute

func (cmd CommandStat) Execute(sess *Session, param string)

func (CommandStat) IsExtend

func (cmd CommandStat) IsExtend() bool

func (CommandStat) RequireAuth

func (cmd CommandStat) RequireAuth() bool

func (CommandStat) RequireParam

func (cmd CommandStat) RequireParam() bool

type CommandStor

type CommandStor struct{}

CommandStor responds to the STOR FTP Command. It allows the user to upload a new file.

func (CommandStor) Execute

func (cmd CommandStor) Execute(sess *Session, param string)

func (CommandStor) IsExtend

func (cmd CommandStor) IsExtend() bool

func (CommandStor) RequireAuth

func (cmd CommandStor) RequireAuth() bool

func (CommandStor) RequireParam

func (cmd CommandStor) RequireParam() bool

type CommandStru

type CommandStru struct{}

CommandStru responds to the STRU FTP Command.

like the MODE and TYPE Commands, stru[cture] dates back to a time when the FTP protocol was more aware of the content of the files it was transferring, and would sometimes be expected to translate things like EOL markers on the fly.

These days files are sent unmodified, and F(ile) mode is the only one we really need to support.

func (CommandStru) Execute

func (cmd CommandStru) Execute(sess *Session, param string)

func (CommandStru) IsExtend

func (cmd CommandStru) IsExtend() bool

func (CommandStru) RequireAuth

func (cmd CommandStru) RequireAuth() bool

func (CommandStru) RequireParam

func (cmd CommandStru) RequireParam() bool

type CommandSyst

type CommandSyst struct{}

CommandSyst responds to the SYST FTP Command by providing a canned response.

func (CommandSyst) Execute

func (cmd CommandSyst) Execute(sess *Session, param string)

func (CommandSyst) IsExtend

func (cmd CommandSyst) IsExtend() bool

func (CommandSyst) RequireAuth

func (cmd CommandSyst) RequireAuth() bool

func (CommandSyst) RequireParam

func (cmd CommandSyst) RequireParam() bool

type CommandType

type CommandType struct{}

CommandType responds to the TYPE FTP Command.

like the MODE and STRU Commands, TYPE dates back to a time when the FTP
protocol was more aware of the content of the files it was transferring, and
would sometimes be expected to translate things like EOL markers on the fly.

Valid options were A(SCII), I(mage), E(BCDIC) or LN (for local type). Since
we plan to just accept bytes from the client unchanged, I think Image mode is
adequate. The RFC requires we accept ASCII mode however, so accept it, but
ignore it.

func (CommandType) Execute

func (cmd CommandType) Execute(sess *Session, param string)

func (CommandType) IsExtend

func (cmd CommandType) IsExtend() bool

func (CommandType) RequireAuth

func (cmd CommandType) RequireAuth() bool

func (CommandType) RequireParam

func (cmd CommandType) RequireParam() bool

type CommandUser

type CommandUser struct{}

CommandUser responds to the USER FTP Command by asking for the password

func (CommandUser) Execute

func (cmd CommandUser) Execute(sess *Session, param string)

func (CommandUser) IsExtend

func (cmd CommandUser) IsExtend() bool

func (CommandUser) RequireAuth

func (cmd CommandUser) RequireAuth() bool

func (CommandUser) RequireParam

func (cmd CommandUser) RequireParam() bool

type CommandXRmd

type CommandXRmd struct{}

cmdXRmd responds to the RMD FTP Command. It allows the client to delete a directory.

func (CommandXRmd) Execute

func (cmd CommandXRmd) Execute(sess *Session, param string)

func (CommandXRmd) IsExtend

func (cmd CommandXRmd) IsExtend() bool

func (CommandXRmd) RequireAuth

func (cmd CommandXRmd) RequireAuth() bool

func (CommandXRmd) RequireParam

func (cmd CommandXRmd) RequireParam() bool

type Context

type Context struct {
	Sess  *Session
	Cmd   string                 // request command on this request
	Param string                 // request param on this request
	Data  map[string]interface{} // share data between middlewares
}

Context represents a context the driver may want to know

type DataSocket

type DataSocket interface {
	Host() string

	Port() int

	// the standard io.Reader interface
	Read(p []byte) (n int, err error)

	// the standard io.ReaderFrom interface
	ReadFrom(r io.Reader) (int64, error)

	// the standard io.Writer interface
	Write(p []byte) (n int, err error)

	// the standard io.Closer interface
	Close() error
}

DataSocket describes a data socket is used to send non-control data between the client and server.

type DiscardLogger

type DiscardLogger struct{}

DiscardLogger represents a silent logger, produces no output

func (*DiscardLogger) Print

func (logger *DiscardLogger) Print(sessionID string, message interface{})

Print implements Logger

func (*DiscardLogger) PrintCommand

func (logger *DiscardLogger) PrintCommand(sessionID string, command string, params string)

PrintCommand implements Logger

func (*DiscardLogger) PrintResponse

func (logger *DiscardLogger) PrintResponse(sessionID string, code int, message string)

PrintResponse implements Logger

func (*DiscardLogger) Printf

func (logger *DiscardLogger) Printf(sessionID string, format string, v ...interface{})

Printf implements Logger

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(*Context, string) (os.FileInfo, error)

	// params  - path, function on file or subdir found
	// returns - error
	//           path
	ListDir(*Context, string, func(os.FileInfo) error) error

	// params  - path
	// returns - nil if the directory was deleted or any error encountered
	DeleteDir(*Context, string) error

	// params  - path
	// returns - nil if the file was deleted or any error encountered
	DeleteFile(*Context, string) error

	// params  - from_path, to_path
	// returns - nil if the file was renamed or any error encountered
	Rename(*Context, string, string) error

	// params  - path
	// returns - nil if the new directory was created or any error encountered
	MakeDir(*Context, string) error

	// params  - path, filepos
	// returns - a string containing the file data to send to the client
	GetFile(*Context, string, int64) (int64, io.ReadCloser, error)

	// params  - destination path, an io.Reader containing the file data
	// returns - the number of bytes written and the first error encountered while writing, if any.
	PutFile(*Context, string, io.Reader, int64) (int64, error)
}

Driver is an interface that you will implement to create a driver for your chosen persistence layer. The server will create a new instance of your driver for each client that connects and delegate to it as required.

Note that if the driver also implements the Auth interface then this will be called instead of calling Options.Auth. This allows the Auth mechanism to change the driver configuration.

func NewMultiDriver

func NewMultiDriver(drivers map[string]Driver) Driver

NewMultiDriver creates a multi driver to combind multiple driver

type FileInfo

type FileInfo interface {
	os.FileInfo

	Owner() string
	Group() string
}

FileInfo represents an file interface

type Filter

type Filter interface {
	BeforeLoginUser(ctx *Context, userName string) bool
	BeforePutFile(ctx *Context, dstPath string) bool
	BeforeDeleteFile(ctx *Context, dstPath string) bool
	BeforeChangeCurDir(ctx *Context, oldCurDir, newCurDir string) bool
	BeforeCreateDir(ctx *Context, dstPath string) bool
	BeforeDeleteDir(ctx *Context, dstPath string) bool
	BeforeDownloadFile(ctx *Context, dstPath string) bool
	AfterUserLogin(ctx *Context, userName, password string, passMatched bool, err error)
	AfterFilePut(ctx *Context, dstPath string, size int64, err error)
	AfterFileDeleted(ctx *Context, dstPath string, err error)
	AfterFileDownloaded(ctx *Context, dstPath string, size int64, err error)
	AfterCurDirChanged(ctx *Context, oldCurDir, newCurDir string, err error)
	AfterDirCreated(ctx *Context, dstPath string, err error)
	AfterDirDeleted(ctx *Context, dstPath string, err error)
}

Filter represents a notification operator interface

type Logger

type Logger interface {
	Print(sessionID string, message interface{})
	Printf(sessionID string, format string, v ...interface{})
	PrintCommand(sessionID string, command string, params string)
	PrintResponse(sessionID string, code int, message string)
}

Logger represents an interface to record all ftp information and command

type MultiAuth

type MultiAuth struct {
	Accounts map[string]Account
	// contains filtered or unexported fields
}

func NewMultiAuth

func NewMultiAuth() *MultiAuth

func (*MultiAuth) CheckPasswd

func (self *MultiAuth) CheckPasswd(ctx *Context, name, pass string) (bool, error)

CheckPasswd

@Description: 校验密码
@param ctx
@param name 用户名
@param pass 密码
@return bool 是否匹配
@return error 错误说明

func (*MultiAuth) Delete

func (self *MultiAuth) Delete(name string)

Delete

@Description: 删除name
@param name

func (*MultiAuth) IsDeleable

func (self *MultiAuth) IsDeleable(ctx *Context, name string) bool

IsDeleable

@Description: name是否具有删除权限
@param ctx
@param name
@return bool true - 具有删除权限

func (*MultiAuth) IsPutable

func (self *MultiAuth) IsPutable(ctx *Context, name string) bool

IsPutable

@Description: name是否具有上传权限
@param ctx
@param name
@return bool true - 具有上传权限

func (*MultiAuth) IsReadable

func (self *MultiAuth) IsReadable(ctx *Context, name string) bool

IsReadable

@Description:name是否具有读取权限
@param ctx
@param name
@return bool true - 具有读取权限

func (*MultiAuth) Register

func (self *MultiAuth) Register(account Account)

Register

@Description: 注册账户,如果已经存在将会替换
@param account

func (*MultiAuth) Update

func (self *MultiAuth) Update(account Account)

Update

@Description: 更新用户信息
@param account

type MultiDriver

type MultiDriver struct {
	// contains filtered or unexported fields
}

MultiDriver represents a composite driver

func (*MultiDriver) DeleteDir

func (driver *MultiDriver) DeleteDir(ctx *Context, path string) error

DeleteDir implements Driver

func (*MultiDriver) DeleteFile

func (driver *MultiDriver) DeleteFile(ctx *Context, path string) error

DeleteFile implements Driver

func (*MultiDriver) GetFile

func (driver *MultiDriver) GetFile(ctx *Context, path string, offset int64) (int64, io.ReadCloser, error)

GetFile implements Driver

func (*MultiDriver) ListDir

func (driver *MultiDriver) ListDir(ctx *Context, path string, callback func(os.FileInfo) error) error

ListDir implements Driver

func (*MultiDriver) MakeDir

func (driver *MultiDriver) MakeDir(ctx *Context, path string) error

MakeDir implements Driver

func (*MultiDriver) PutFile

func (driver *MultiDriver) PutFile(ctx *Context, destPath string, data io.Reader, offset int64) (int64, error)

PutFile implements Driver

func (*MultiDriver) Rename

func (driver *MultiDriver) Rename(ctx *Context, fromPath string, toPath string) error

Rename implements Driver

func (*MultiDriver) Stat

func (driver *MultiDriver) Stat(ctx *Context, path string) (os.FileInfo, error)

Stat implements Driver

type NullFilter

type NullFilter struct{}

NullFilter implements Filter

func (NullFilter) AfterCurDirChanged

func (NullFilter) AfterCurDirChanged(ctx *Context, oldCurDir, newCurDir string, err error)

AfterCurDirChanged implements Filter

func (NullFilter) AfterDirCreated

func (NullFilter) AfterDirCreated(ctx *Context, dstPath string, err error)

AfterDirCreated implements Filter

func (NullFilter) AfterDirDeleted

func (NullFilter) AfterDirDeleted(ctx *Context, dstPath string, err error)

AfterDirDeleted implements Filter

func (NullFilter) AfterFileDeleted

func (NullFilter) AfterFileDeleted(ctx *Context, dstPath string, err error)

AfterFileDeleted implements Filter

func (NullFilter) AfterFileDownloaded

func (NullFilter) AfterFileDownloaded(ctx *Context, dstPath string, size int64, err error)

AfterFileDownloaded implements Filter

func (NullFilter) AfterFilePut

func (NullFilter) AfterFilePut(ctx *Context, dstPath string, size int64, err error)

AfterFilePut implements Filter

func (NullFilter) AfterUserLogin

func (NullFilter) AfterUserLogin(ctx *Context, userName, password string, passMatched bool, err error)

AfterUserLogin implements Filter

func (NullFilter) BeforeChangeCurDir

func (NullFilter) BeforeChangeCurDir(ctx *Context, oldCurDir, newCurDir string) bool

BeforeChangeCurDir implements Filter

func (NullFilter) BeforeCreateDir

func (NullFilter) BeforeCreateDir(ctx *Context, dstPath string) bool

BeforeCreateDir implements Filter

func (NullFilter) BeforeDeleteDir

func (NullFilter) BeforeDeleteDir(ctx *Context, dstPath string) bool

BeforeDeleteDir implements Filter

func (NullFilter) BeforeDeleteFile

func (NullFilter) BeforeDeleteFile(ctx *Context, dstPath string) bool

BeforeDeleteFile implements Filter

func (NullFilter) BeforeDownloadFile

func (NullFilter) BeforeDownloadFile(ctx *Context, dstPath string) bool

BeforeDownloadFile implements Filter

func (NullFilter) BeforeLoginUser

func (NullFilter) BeforeLoginUser(ctx *Context, userName string) bool

BeforeLoginUser implements Filter

func (NullFilter) BeforePutFile

func (NullFilter) BeforePutFile(ctx *Context, dstPath string) bool

BeforePutFile implements Filter

type Options

type Options struct {
	// This server supported commands, if blank, it will be defaultCommands
	// So that users could override the Commands
	Commands map[string]Command

	// The driver that will be used to handle files persistent
	Driver Driver

	// How to hanle the authenticate requests
	Auth Auth

	// How to handle the perm controls
	Perm Perm

	// 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

	// Public IP of the server
	PublicIP string

	// Passive ports
	PassivePorts 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

	// If ture TLS is used in RFC4217 mode
	ExplicitFTPS bool

	// If true, client must upgrade to TLS before sending any other command
	ForceTLS bool

	WelcomeMessage string

	// A logger implementation, if nil the StdLogger is used
	Logger Logger

	// Rate Limit per connection bytes per second, 0 means no limit
	RateLimit int64
}

Options contains parameters for server.NewServer()

type Perm

type Perm interface {
	GetOwner(string) (string, error)
	GetGroup(string) (string, error)
	GetMode(string) (os.FileMode, error)

	ChOwner(string, string) error
	ChGroup(string, string) error
	ChMode(string, os.FileMode) error
}

Perm represents a perm interface

type Server

type Server struct {
	*Options
	// 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 *Options) (*Server, error)

NewServer initialises a new FTP server. Configuration options are provided via an instance of Options. Calling this function in your code will probably look something like this:

driver := &MyDriver{}
opts    := &server.Options{
  Driver: driver,
  Auth: auth,
  Port: 2000,
  Perm: perm,
  Hostname: "127.0.0.1",
}
server, err  := server.NewServer(opts)

func (*Server) ListenAndServe

func (server *Server) ListenAndServe() error

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.

func (*Server) RegisterNotifer

func (server *Server) RegisterNotifer(filter Filter)

RegisterNotifer registers a notifier

func (*Server) Serve

func (server *Server) Serve(l net.Listener) error

Serve accepts connections on a given net.Listener and handles each request in a new goroutine.

func (*Server) Shutdown

func (server *Server) Shutdown() error

Shutdown will gracefully stop a server. Already connected clients will retain their connections

type Session

type Session struct {
	Data map[string]interface{} // shared data between different commands
	// contains filtered or unexported fields
}

Session represents a session between ftp client and the server

func (*Session) BuildPath

func (sess *Session) BuildPath(filename string) string

func (*Session) Close

func (sess *Session) Close()

Close will manually close this connection, even if the client isn't ready.

func (*Session) DataConn

func (sess *Session) DataConn() DataSocket

DataConn returns the data connection

func (*Session) IsLogin

func (sess *Session) IsLogin() bool

IsLogin returns if user has login

func (*Session) LastFilePos

func (sess *Session) LastFilePos() int64

func (*Session) LoginUser

func (sess *Session) LoginUser() string

LoginUser returns the login user name if login

func (*Session) Options

func (sess *Session) Options() *Options

Options returns the server options

func (*Session) PassivePort

func (sess *Session) PassivePort() int

PassivePort returns the port which could be used by passive mode.

func (*Session) PreCommand

func (sess *Session) PreCommand() string

func (*Session) PublicIP

func (sess *Session) PublicIP() string

PublicIP returns the public ip of the server

func (*Session) RemoteAddr

func (sess *Session) RemoteAddr() net.Addr

RemoteAddr returns the remote ftp client's address

func (*Session) Serve

func (sess *Session) 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.

func (*Session) Server

func (sess *Session) Server() *Server

Server returns the server of session

func (*Session) WriteMessage

func (sess *Session) WriteMessage(code int, message string)

type SimpleAuth

type SimpleAuth struct {
	Name     string
	Password string
}

SimpleAuth implements Auth interface to provide a memory user login auth

func (*SimpleAuth) CheckPasswd

func (a *SimpleAuth) CheckPasswd(ctx *Context, name, pass string) (bool, error)

CheckPasswd will check user's password

func (*SimpleAuth) Delete

func (self *SimpleAuth) Delete(name string)

func (*SimpleAuth) IsDeleable

func (self *SimpleAuth) IsDeleable(ctx *Context, name string) bool

func (*SimpleAuth) IsPutable

func (self *SimpleAuth) IsPutable(ctx *Context, name string) bool

func (*SimpleAuth) IsReadable

func (self *SimpleAuth) IsReadable(ctx *Context, name string) bool

func (*SimpleAuth) Register

func (self *SimpleAuth) Register(account Account)

func (*SimpleAuth) Update

func (self *SimpleAuth) Update(account Account)

type SimplePerm

type SimplePerm struct {
	// contains filtered or unexported fields
}

SimplePerm implements Perm interface that all files are owned by special owner and group

func NewSimplePerm

func NewSimplePerm(owner, group string) *SimplePerm

NewSimplePerm creates a SimplePerm

func (*SimplePerm) ChGroup

func (s *SimplePerm) ChGroup(string, string) error

ChGroup changed the file's group

func (*SimplePerm) ChMode

func (s *SimplePerm) ChMode(string, os.FileMode) error

ChMode changed the file's mode

func (*SimplePerm) ChOwner

func (s *SimplePerm) ChOwner(string, string) error

ChOwner changed the file's owner

func (*SimplePerm) GetGroup

func (s *SimplePerm) GetGroup(string) (string, error)

GetGroup returns the group of the file

func (*SimplePerm) GetMode

func (s *SimplePerm) GetMode(string) (os.FileMode, error)

GetMode returns the file's mode

func (*SimplePerm) GetOwner

func (s *SimplePerm) GetOwner(string) (string, error)

GetOwner returns the file's owner

type StdLogger

type StdLogger struct{}

StdLogger use an instance of this to log in a standard format

func (*StdLogger) Print

func (logger *StdLogger) Print(sessionID string, message interface{})

Print implements Logger

func (*StdLogger) PrintCommand

func (logger *StdLogger) PrintCommand(sessionID string, command string, params string)

PrintCommand implements Logger

func (*StdLogger) PrintResponse

func (logger *StdLogger) PrintResponse(sessionID string, code int, message string)

PrintResponse implements Logger

func (*StdLogger) Printf

func (logger *StdLogger) Printf(sessionID string, format string, v ...interface{})

Printf implements Logger

Directories

Path Synopsis
driver

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL