{"id":13413591,"url":"https://github.com/fclairamb/ftpserverlib","last_synced_at":"2025-05-15T01:09:15.778Z","repository":{"id":37306940,"uuid":"69161931","full_name":"fclairamb/ftpserverlib","owner":"fclairamb","description":"golang ftp server library","archived":false,"fork":false,"pushed_at":"2025-05-04T21:44:21.000Z","size":4752,"stargazers_count":446,"open_issues_count":9,"forks_count":101,"subscribers_count":13,"default_branch":"main","last_synced_at":"2025-05-04T22:33:51.147Z","etag":null,"topics":["ftp-server","golang","golang-library"],"latest_commit_sha":null,"homepage":"","language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/fclairamb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":"CONTRIBUTING.md","funding":null,"license":"license.txt","code_of_conduct":"CODE_OF_CONDUCT.md","threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2016-09-25T12:05:29.000Z","updated_at":"2025-05-04T21:43:56.000Z","dependencies_parsed_at":"2024-04-21T09:43:34.340Z","dependency_job_id":"4dee4ee7-51b8-4d6b-b10c-63614a5ea964","html_url":"https://github.com/fclairamb/ftpserverlib","commit_stats":{"total_commits":780,"total_committers":30,"mean_commits":26.0,"dds":0.7243589743589743,"last_synced_commit":"117fcb6c952e5062dfb1647d0158dfaa299d65cb"},"previous_names":[],"tags_count":29,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fclairamb%2Fftpserverlib","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fclairamb%2Fftpserverlib/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fclairamb%2Fftpserverlib/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/fclairamb%2Fftpserverlib/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/fclairamb","download_url":"https://codeload.github.com/fclairamb/ftpserverlib/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":254254043,"owners_count":22039792,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ftp-server","golang","golang-library"],"created_at":"2024-07-30T20:01:43.991Z","updated_at":"2025-05-15T01:09:10.757Z","avatar_url":"https://github.com/fclairamb.png","language":"Go","readme":"# Golang FTP Server library\n\n[![Go version](https://img.shields.io/github/go-mod/go-version/fclairamb/ftpserverlib)](https://golang.org/doc/devel/release.html)\n[![Release](https://img.shields.io/github/v/release/fclairamb/ftpserverlib)](https://github.com/fclairamb/ftpserverlib/releases/latest)\n[![Build](https://github.com/fclairamb/ftpserverlib/workflows/Build/badge.svg)](https://github.com/fclairamb/ftpserverlib/actions/workflows/build.yml)\n[![codecov](https://codecov.io/gh/fclairamb/ftpserverlib/branch/main/graph/badge.svg?token=IVeoGgl1rj)](https://codecov.io/gh/fclairamb/ftpserverlib)\n[![Go Report Card](https://goreportcard.com/badge/fclairamb/ftpserverlib)](https://goreportcard.com/report/fclairamb/ftpserverlib)\n[![GoDoc](https://godoc.org/github.com/fclairamb/ftpserverlib?status.svg)](https://godoc.org/github.com/fclairamb/ftpserverlib)\n[![Mentioned in Awesome Go](https://awesome.re/mentioned-badge.svg)](https://github.com/avelino/awesome-go)\n\nThis library allows to easily build a simple and fully-featured FTP server using [afero](https://github.com/spf13/afero) as the backend filesystem.\n\nIf you're interested in a fully featured FTP server, you should use [sftpgo](https://github.com/drakkan/sftpgo) (fully featured SFTP/FTP server) or [ftpserver](https://github.com/fclairamb/ftpserver) (basic FTP server).\n\n## Current status of the project\n\n### Features\n\n * Uploading and downloading files\n * Directory listing (LIST + MLST)\n * File and directory deletion and renaming\n * TLS support (AUTH + PROT)\n * File download/upload resume support (REST)\n * Passive socket connections (PASV and EPSV commands)\n * Active socket connections (PORT and EPRT commands)\n * IPv6 support (EPSV + EPRT)\n * Small memory footprint\n * Clean code: No sleep, no panic, no global sync (only around control/transfer connection per client)\n * Uses only the standard library except for:\n   * [afero](https://github.com/spf13/afero) for generic file systems handling\n   * [fclairamb/go-log](https://github.com/fclairamb/go-log) for logging through your existing libraries [go-kit/log](https://github.com/go-kit/log), [log15](https://github.com/inconshreveable/log15), [zap](https://github.com/uber-go/zap), [zerolog](https://github.com/rs/zerolog/), [logrus](https://github.com/sirupsen/logrus)\n * Supported extensions:\n   * [AUTH](https://tools.ietf.org/html/rfc2228#page-6) - Control session protection\n   * [AUTH TLS](https://tools.ietf.org/html/rfc4217#section-4.1) - TLS session\n   * [PROT](https://tools.ietf.org/html/rfc2228#page-8) - Transfer protection\n   * [EPRT/EPSV](https://tools.ietf.org/html/rfc2428) - IPv6 support\n   * [MDTM](https://tools.ietf.org/html/rfc3659#page-8) - File Modification Time\n   * [SIZE](https://tools.ietf.org/html/rfc3659#page-11) - Size of a file\n   * [REST](https://tools.ietf.org/html/rfc3659#page-13) - Restart of interrupted transfer\n   * [MLST](https://tools.ietf.org/html/rfc3659#page-23) - Simple file listing for machine processing\n   * [MLSD](https://tools.ietf.org/html/rfc3659#page-23) - Directory listing for machine processing\n   * [HASH](https://tools.ietf.org/html/draft-bryan-ftpext-hash-02) - Hashing of files\n   * [AVLB](https://tools.ietf.org/html/draft-peterson-streamlined-ftp-command-extensions-10#section-4) - Available space\n   * [COMB](https://help.globalscape.com/help/archive/eft6-4/mergedprojects/eft/allowingmultiparttransferscomb_command.htm) - Combine files\n\n## Quick test\nThe easiest way to test this library is to use [ftpserver](https://github.com/fclairamb/ftpserver).\n\n## The driver\nThe simplest way to get a good understanding of how the driver shall be implemented is to look at the [tests driver](https://github.com/fclairamb/ftpserverlib/blob/master/driver_test.go).\n\n### The base API\n\nThe API is directly based on [afero](https://github.com/spf13/afero).\n\n```go\n// MainDriver handles the authentication and ClientHandlingDriver selection\ntype MainDriver interface {\n\t// GetSettings returns some general settings around the server setup\n\tGetSettings() (*Settings, error)\n\n\t// ClientConnected is called to send the very first welcome message\n\tClientConnected(cc ClientContext) (string, error)\n\n\t// ClientDisconnected is called when the user disconnects, even if he never authenticated\n\tClientDisconnected(cc ClientContext)\n\n\t// AuthUser authenticates the user and selects an handling driver\n\tAuthUser(cc ClientContext, user, pass string) (ClientDriver, error)\n\n\t// GetTLSConfig returns a TLS Certificate to use\n\t// The certificate could frequently change if we use something like \"let's encrypt\"\n\tGetTLSConfig() (*tls.Config, error)\n}\n\n\n// ClientDriver is the base FS implementation that allows to manipulate files\ntype ClientDriver interface {\n\tafero.Fs\n}\n\n// ClientContext is implemented on the server side to provide some access to few data around the client\ntype ClientContext interface {\n\t// Path provides the path of the current connection\n\tPath() string\n\n\t// SetDebug activates the debugging of this connection commands\n\tSetDebug(debug bool)\n\n\t// Debug returns the current debugging status of this connection commands\n\tDebug() bool\n\n\t// Client's ID on the server\n\tID() uint32\n\n\t// Client's address\n\tRemoteAddr() net.Addr\n\n\t// Servers's address\n\tLocalAddr() net.Addr\n\n\t// Client's version can be empty\n\tGetClientVersion() string\n\n\t// Close closes the connection and disconnects the client.\n\tClose() error\n\n\t// HasTLSForControl returns true if the control connection is over TLS\n\tHasTLSForControl() bool\n\n\t// HasTLSForTransfers returns true if the transfer connection is over TLS\n\tHasTLSForTransfers() bool\n\n\t// GetLastCommand returns the last received command\n\tGetLastCommand() string\n\n\t// GetLastDataChannel returns the last data channel mode\n\tGetLastDataChannel() DataChannel\n}\n\n// Settings define all the server settings\ntype Settings struct {\n\tListener                 net.Listener     // (Optional) To provide an already initialized listener\n\tListenAddr               string           // Listening address\n\tPublicHost               string           // Public IP to expose (only an IP address is accepted at this stage)\n\tPublicIPResolver         PublicIPResolver // (Optional) To fetch a public IP lookup\n\tPassiveTransferPortRange *PortRange       // (Optional) Port Range for data connections. Random if not specified\n\tActiveTransferPortNon20  bool             // Do not impose the port 20 for active data transfer (#88, RFC 1579)\n\tIdleTimeout              int              // Maximum inactivity time before disconnecting (#58)\n\tConnectionTimeout        int              // Maximum time to establish passive or active transfer connections\n\tDisableMLSD              bool             // Disable MLSD support\n\tDisableMLST              bool             // Disable MLST support\n\tDisableMFMT              bool             // Disable MFMT support (modify file mtime)\n\tBanner                   string           // Banner to use in server status response\n\tTLSRequired              TLSRequirement   // defines the TLS mode\n\tDisableLISTArgs          bool             // Disable ls like options (-a,-la etc.) for directory listing\n\tDisableSite              bool             // Disable SITE command\n\tDisableActiveMode        bool             // Disable Active FTP\n\tEnableHASH               bool             // Enable support for calculating hash value of files\n\tDisableSTAT              bool             // Disable Server STATUS, STAT on files and directories will still work\n\tDisableSYST              bool             // Disable SYST\n\tEnableCOMB               bool             // Enable COMB support\n\tDefaultTransferType      TransferType     // Transfer type to use if the client don't send the TYPE command\n\t// ActiveConnectionsCheck defines the security requirements for active connections\n\tActiveConnectionsCheck DataConnectionRequirement\n\t// PasvConnectionsCheck defines the security requirements for passive connections\n\tPasvConnectionsCheck DataConnectionRequirement\n}\n```\n\n### Extensions\nThere are a few extensions to the base afero APIs so that you can perform some operations that aren't offered by afero.\n\n#### Pre-allocate some space\n```go\n// ClientDriverExtensionAllocate is an extension to support the \"ALLO\" - file allocation - command\ntype ClientDriverExtensionAllocate interface {\n\n\t// AllocateSpace reserves the space necessary to upload files\n\tAllocateSpace(size int) error\n}\n```\n\n#### Get available space\n```go\n// ClientDriverExtensionAvailableSpace is an extension to implement to support\n// the AVBL ftp command\ntype ClientDriverExtensionAvailableSpace interface {\n\tGetAvailableSpace(dirName string) (int64, error)\n}\n```\n\n#### Create symbolic link\n```go\n// ClientDriverExtensionSymlink is an extension to support the \"SITE SYMLINK\" - symbolic link creation - command\ntype ClientDriverExtensionSymlink interface {\n\n\t// Symlink creates a symlink\n\tSymlink(oldname, newname string) error\n\n\t// SymlinkIfPossible allows to get the source of a symlink (but we don't need for now)\n\t// ReadlinkIfPossible(name string) (string, error)\n}\n```\n\n#### Compute file hash\n```go\n// ClientDriverExtensionHasher is an extension to implement if you want to handle file digests\n// yourself. You have to set EnableHASH to true for this extension to be called\ntype ClientDriverExtensionHasher interface {\n\tComputeHash(name string, algo HASHAlgo, startOffset, endOffset int64) (string, error)\n}\n```\n\n## History of the project\n\nI wanted to make a system which would accept files through FTP and redirect them to something else. Go seemed like the obvious choice and it seemed there was a lot of libraries available but it turns out none of them were in a useable state.\n\n* [micahhausler/go-ftp](https://github.com/micahhausler/go-ftp) is a  minimalistic implementation\n* [shenfeng/ftpd.go](https://github.com/shenfeng/ftpd.go) is very basic and 4 years old.\n* [yob/graval](https://github.com/yob/graval) is 3 years old and “experimental”.\n* [goftp/server](https://github.com/goftp/server) seemed OK but I couldn't use it on both Filezilla and the MacOs ftp client.\n* [andrewarrow/paradise_ftp](https://github.com/andrewarrow/paradise_ftp) - Was the only one of the list I could test right away. This is the project I forked from.\n","funding_links":[],"categories":["Networking","Go","网络","Relational Databases"],"sub_categories":["Transliteration","Uncategorized","音译"],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffclairamb%2Fftpserverlib","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Ffclairamb%2Fftpserverlib","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Ffclairamb%2Fftpserverlib/lists"}