Documentation ¶
Overview ¶
Package sftp implements the SSH File Transfer Protocol as described in https://filezilla-project.org/specs/draft-ietf-secsh-filexfer-02.txt
Example ¶
package main import ( "log" "github.com/pkg/sftp" "golang.org/x/crypto/ssh" ) func main() { var conn *ssh.Client // open an SFTP session over an existing ssh connection. sftp, err := sftp.NewClient(conn) if err != nil { log.Fatal(err) } defer sftp.Close() // walk a directory w := sftp.Walk("/home/user") for w.Step() { if w.Err() != nil { continue } log.Println(w.Path()) } // leave your mark f, err := sftp.Create("hello.txt") if err != nil { log.Fatal(err) } if _, err := f.Write([]byte("Hello world!")); err != nil { log.Fatal(err) } // check it's there fi, err := sftp.Lstat("hello.txt") if err != nil { log.Fatal(err) } log.Println(fi) }
Output:
Index ¶
- Constants
- Variables
- func FakeFileInfoSys() interface{}
- func Join(elem ...string) string
- func Match(pattern, name string) (matched bool, err error)
- func MaxPacket(size int) func(*Client) error
- func NextId() uint64
- func SFTPCode2BaseCode(errcode uint32) int
- func Split(path string) (dir, file string)
- type Client
- func (c *Client) Chmod(path string, mode os.FileMode) error
- func (c *Client) Chown(path string, uid, gid int) error
- func (c *Client) Chtimes(path string, atime time.Time, mtime time.Time) error
- func (c *Client) Close() error
- func (c *Client) Create(path string) (*File, error)
- func (c *Client) Getwd() (string, error)
- func (c *Client) Glob(pattern string) (matches []string, err error)
- func (c *Client) Join(elem ...string) string
- func (c *Client) Lstat(p string) (os.FileInfo, error)
- func (c *Client) Mkdir(path string) error
- func (c *Client) Open(path string) (*File, error)
- func (c *Client) OpenFile(path string, f int) (*File, error)
- func (c *Client) ReadDir(p string) ([]os.FileInfo, error)
- func (c *Client) ReadLink(p string) (string, error)
- func (c *Client) Remove(path string) error
- func (c *Client) RemoveDirectory(path string) error
- func (c *Client) Rename(oldname, newname string) error
- func (c *Client) Stat(p string) (os.FileInfo, error)
- func (c *Client) StatVFS(path string) (*StatVFS, error)
- func (c *Client) Symlink(oldname, newname string) error
- func (c *Client) Truncate(path string, size int64) error
- func (c *Client) Walk(root string) *fs.Walker
- type File
- func (f *File) Chmod(mode os.FileMode) error
- func (f *File) Chown(uid, gid int) error
- func (f *File) Close() error
- func (f *File) Name() string
- func (f *File) Read(b []byte) (int, error)
- func (f *File) ReadFrom(r io.Reader) (int64, error)
- func (f *File) Seek(offset int64, whence int) (int64, error)
- func (f *File) Stat() (os.FileInfo, error)
- func (f *File) Truncate(size int64) error
- func (f *File) Write(b []byte) (int, error)
- func (f *File) WriteTo(w io.Writer) (int64, error)
- type FileCmder
- type FileInfoer
- type FileReader
- type FileStat
- type FileWriter
- type Handlers
- type Request
- func (r *Request) Getfinfo() ([]os.FileInfo, bool)
- func (r *Request) Getfinfoflag() bool
- func (r *Request) LsNext() string
- func (r *Request) LsSave(token string)
- func (r *Request) SetStatus(status uint32)
- func (r *Request) Setfinfo(finfo []os.FileInfo, getfinfoflag bool)
- func (r *Request) Setfinfoflag(getfinfoflag bool)
- type RequestServer
- type Server
- type ServerOption
- type SftpConf
- type StatExtended
- type StatVFS
- type StatusError
- type UnSeqId
Examples ¶
Constants ¶
const ( SftpStatusOK = 200 SftpStatusCreated = 201 // RFC 7231, 6.3.2 SftpStatusAccepted = 202 // RFC 7231, 6.3.3 SftpStatusNonAuthoritativeInfo = 203 // RFC 7231, 6.3.4 SftpStatusNoContent = 204 // RFC 7231, 6.3.5 SftpStatusResetContent = 205 // RFC 7231, 6.3.6 SftpStatusPartialContent = 206 // RFC 7233, 4.1 SftpStatusMultiStatus = 207 // RFC 4918, 11.1 SftpStatusAlreadyReported = 208 // RFC 5842, 7.1 SftpStatusIMUsed = 226 // RFC 3229, 10.4.1 SftpStatusMultipleChoices = 300 // RFC 7231, 6.4.1 SftpStatusMovedPermanently = 301 // RFC 7231, 6.4.2 SftpStatusFound = 302 // RFC 7231, 6.4.3 SftpStatusSeeOther = 303 // RFC 7231, 6.4.4 SftpStatusNotModified = 304 // RFC 7232, 4.1 SftpStatusUseProxy = 305 // RFC 7231, 6.4.5 SftpStatusTemporaryRedirect = 307 // RFC 7231, 6.4.7 SftpStatusPermanentRedirect = 308 // RFC 7538, 3 SftpStatusBadRequest = 400 // RFC 7231, 6.5.1 SftpStatusPaymentRequired = 402 // RFC 7231, 6.5.2 SftpStatusForbidden = 403 // RFC 7231, 6.5.3 SftpStatusNotFound = 404 // RFC 7231, 6.5.4 SftpStatusMethodNotAllowed = 405 // RFC 7231, 6.5.5 SftpStatusNotAcceptable = 406 // RFC 7231, 6.5.6 SftpStatusProxyAuthRequired = 407 // RFC 7235, 3.2 SftpStatusRequestTimeout = 408 // RFC 7231, 6.5.7 SftpStatusConflict = 409 // RFC 7231, 6.5.8 SftpStatusGone = 410 // RFC 7231, 6.5.9 SftpStatusLengthRequired = 411 // RFC 7231, 6.5.10 SftpStatusPreconditionFailed = 412 // RFC 7232, 4.2 SftpStatusRequestEntityTooLarge = 413 // RFC 7231, 6.5.11 SftpStatusRequestURITooLong = 414 // RFC 7231, 6.5.12 SftpStatusUnsupportedMediaType = 415 // RFC 7231, 6.5.13 SftpStatusRequestedRangeNotSatisfiable = 416 // RFC 7233, 4.4 SftpStatusExpectationFailed = 417 // RFC 7231, 6.5.14 SftpStatusTeapot = 418 // RFC 7168, 2.3.3 SftpStatusUnprocessableEntity = 422 // RFC 4918, 11.2 SftpStatusLocked = 423 // RFC 4918, 11.3 SftpStatusFailedDependency = 424 // RFC 4918, 11.4 SftpStatusUpgradeRequired = 426 // RFC 7231, 6.5.15 SftpStatusPreconditionRequired = 428 // RFC 6585, 3 SftpStatusTooManyRequests = 429 // RFC 6585, 4 SftpStatusRequestHeaderFieldsTooLarge = 431 // RFC 6585, 5 SftpStatusInternalServerError = 500 // RFC 7231, 6.6.1 SftpStatusNotImplemented = 501 // RFC 7231, 6.6.2 SftpStatusBadGateway = 502 // RFC 7231, 6.6.3 SftpStatusGatewayTimeout = 504 // RFC 7231, 6.6.5 SftpStatusHTTPVersionNotSupported = 505 // RFC 7231, 6.6.6 SftpStatusVariantAlsoNegotiates = 506 // RFC 2295, 8.1 SftpStatusInsufficientStorage = 507 // RFC 4918, 11.5 SftpStatusLoopDetected = 508 // RFC 5842, 7.2 SftpStatusNotExtended = 510 // RFC 2774, 7 SftpStatusNetworkAuthenticationRequired = 511 // RFC 6585, 6 )
const (
FTPVERSION = 2
)
Variables ¶
var ErrBadPattern = errors.New("syntax error in pattern")
ErrBadPattern indicates a globbing pattern was malformed.
Functions ¶
func FakeFileInfoSys ¶
func FakeFileInfoSys() interface{}
func Join ¶
Join joins any number of path elements into a single path, adding a Separator if necessary. all empty strings are ignored.
func Match ¶
Match reports whether name matches the shell file name pattern. The pattern syntax is:
pattern: { term } term: '*' matches any sequence of non-Separator characters '?' matches any single non-Separator character '[' [ '^' ] { character-range } ']' character class (must be non-empty) c matches character c (c != '*', '?', '\\', '[') '\\' c matches character c character-range: c matches character c (c != '\\', '-', ']') '\\' c matches character c lo '-' hi matches character c for lo <= c <= hi
Match requires pattern to match all of name, not just a substring. The only possible returned error is ErrBadPattern, when pattern is malformed.
func SFTPCode2BaseCode ¶
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client represents an SFTP session on a *ssh.ClientConn SSH connection. Multiple Clients can be active on a single SSH connection, and a Client may be called concurrently from multiple Goroutines.
Client implements the github.com/kr/fs.FileSystem interface.
func NewClientPipe ¶
NewClientPipe creates a new SFTP client given a Reader and a WriteCloser. This can be used for connecting to an SFTP server over TCP/TLS or by using the system's ssh client program (e.g. via exec.Command).
Example ¶
package main import ( "fmt" "log" "os" "os/exec" "github.com/pkg/sftp" ) func main() { // Connect to a remote host and request the sftp subsystem via the 'ssh' // command. This assumes that passwordless login is correctly configured. cmd := exec.Command("ssh", "example.com", "-s", "sftp") // send errors from ssh to stderr cmd.Stderr = os.Stderr // get stdin and stdout wr, err := cmd.StdinPipe() if err != nil { log.Fatal(err) } rd, err := cmd.StdoutPipe() if err != nil { log.Fatal(err) } // start the process if err := cmd.Start(); err != nil { log.Fatal(err) } defer cmd.Wait() // open the SFTP session client, err := sftp.NewClientPipe(rd, wr) if err != nil { log.Fatal(err) } // read a directory list, err := client.ReadDir("/") if err != nil { log.Fatal(err) } // print contents for _, item := range list { fmt.Println(item.Name()) } // close the connection client.Close() }
Output:
func (*Client) Create ¶
Create creates the named file mode 0666 (before umask), truncating it if it already exists. If successful, methods on the returned File can be used for I/O; the associated file descriptor has mode O_RDWR.
func (*Client) Getwd ¶
Getwd returns the current working directory of the server. Operations involving relative paths will be based at this location.
func (*Client) Glob ¶
Glob returns the names of all files matching pattern or nil if there is no matching file. The syntax of patterns is the same as in Match. The pattern may describe hierarchical names such as /usr/*/bin/ed (assuming the Separator is '/').
Glob ignores file system errors such as I/O errors reading directories. The only possible returned error is ErrBadPattern, when pattern is malformed.
func (*Client) Join ¶
Join joins any number of path elements into a single path, adding a separating slash if necessary. The result is Cleaned; in particular, all empty strings are ignored.
func (*Client) Lstat ¶
Lstat returns a FileInfo structure describing the file specified by path 'p'. If 'p' is a symbolic link, the returned FileInfo structure describes the symbolic link.
func (*Client) Mkdir ¶
Mkdir creates the specified directory. An error will be returned if a file or directory with the specified path already exists, or if the directory's parent folder does not exist (the method cannot create complete paths).
Example (Parents) ¶
package main import ( "fmt" "log" "os" "path" "strings" "github.com/pkg/sftp" "golang.org/x/crypto/ssh" ) func main() { // Example of mimicing 'mkdir --parents'; I.E. recursively create // directoryies and don't error if any directories already exists. var conn *ssh.Client client, err := sftp.NewClient(conn) if err != nil { log.Fatal(err) } defer client.Close() ssh_fx_failure := uint32(4) mkdirParents := func(client *sftp.Client, dir string) (err error) { var parents string for _, name := range strings.Split(dir, "/") { parents = path.Join(parents, name) err = client.Mkdir(parents) if status, ok := err.(*sftp.StatusError); ok { if status.Code == ssh_fx_failure { var fi os.FileInfo fi, err = client.Stat(parents) if err == nil { if !fi.IsDir() { return fmt.Errorf("File exists: %s", parents) } } } } if err != nil { break } } return err } err = mkdirParents(client, "/tmp/foo/bar") if err != nil { log.Fatal(err) } }
Output:
func (*Client) Open ¶
Open opens the named file for reading. If successful, methods on the returned file can be used for reading; the associated file descriptor has mode O_RDONLY.
func (*Client) OpenFile ¶
OpenFile is the generalized open call; most users will use Open or Create instead. It opens the named file with specified flag (O_RDONLY etc.). If successful, methods on the returned File can be used for I/O.
func (*Client) ReadDir ¶
ReadDir reads the directory named by dirname and returns a list of directory entries.
func (*Client) Remove ¶
Remove removes the specified file or directory. An error will be returned if no file or directory with the specified path exists, or if the specified directory is not empty.
func (*Client) RemoveDirectory ¶
RemoveDirectory removes a directory path.
func (*Client) Stat ¶
Stat returns a FileInfo structure describing the file specified by path 'p'. If 'p' is a symbolic link, the returned FileInfo structure describes the referent file.
func (*Client) StatVFS ¶
StatVFS retrieves VFS statistics from a remote host.
It implements the statvfs@openssh.com SSH_FXP_EXTENDED feature from http://www.opensource.apple.com/source/OpenSSH/OpenSSH-175/openssh/PROTOCOL?txt.
type File ¶
type File struct {
// contains filtered or unexported fields
}
File represents a remote file.
func (*File) Close ¶
Close closes the File, rendering it unusable for I/O. It returns an error, if any.
func (*File) Read ¶
Read reads up to len(b) bytes from the File. It returns the number of bytes read and an error, if any. Read follows io.Reader semantics, so when Read encounters an error or EOF condition after successfully reading n > 0 bytes, it returns the number of bytes read.
func (*File) ReadFrom ¶
ReadFrom reads data from r until EOF and writes it to the file. The return value is the number of bytes read. Any error except io.EOF encountered during the read is also returned.
func (*File) Seek ¶
Seek implements io.Seeker by setting the client offset for the next Read or Write. It returns the next offset read. Seeking before or after the end of the file is undefined. Seeking relative to the end calls Stat.
func (*File) Truncate ¶
Truncate sets the size of the current file. Although it may be safely assumed that if the size is less than its current size it will be truncated to fit, the SFTP protocol does not specify what behavior the server should do when setting size greater than the current size.
type FileInfoer ¶
FileInfoer should return file listing info and errors (readdir, stat) note stat requests would return a list of 1
type FileReader ¶
FileReader should return an io.Reader for the filepath
type FileStat ¶
type FileStat struct { Size uint64 Mode uint32 Mtime uint32 Atime uint32 UID uint32 GID uint32 Extended []StatExtended }
FileStat holds the original unmarshalled values from a call to READDIR or *STAT. It is exported for the purposes of accessing the raw values via os.FileInfo.Sys()
type FileWriter ¶
FileWriter should return an io.Writer for the filepath
type Handlers ¶
type Handlers struct { FileGet FileReader FilePut FileWriter FileCmd FileCmder FileInfo FileInfoer }
Handlers contains the 4 SFTP server request handlers.
type Request ¶
type Request struct { // Get, Put, Setstat, Stat, Rename, Remove // Rmdir, Mkdir, List, Readlink, Symlink Method string Filepath string Filesize int64 Flags uint32 Attrs []byte // convert to sub-struct Target string // for renames and sym-links // contains filtered or unexported fields }
Request contains the data and state for the incoming service request.
func NewRequest ¶
NewRequest creates a new Request object.
func (*Request) LsNext ¶
LsNext should return the token from the previous call to know which batch to return next.
func (*Request) LsSave ¶
LsSave takes a token to keep track of file list batches. Openssh uses a batch size of 100, so I suggest sticking close to that.
func (*Request) Setfinfoflag ¶
type RequestServer ¶
type RequestServer struct { Handlers Handlers // contains filtered or unexported fields }
RequestServer abstracts the sftp protocol with an http request-like protocol
func NewRequestServer ¶
func NewRequestServer(rwc io.ReadWriteCloser, h Handlers, rootpath string, time, worknum int, user, localip, remoteip string) *RequestServer
NewRequestServer creates/allocates/returns new RequestServer. Normally there there will be one server per user-session.
func (*RequestServer) Close ¶
func (rs *RequestServer) Close() error
Close the read/write/closer to trigger exiting the main server loop
func (*RequestServer) Serve ¶
func (rs *RequestServer) Serve() error
Serve requests for user session
type Server ¶
type Server struct {
// contains filtered or unexported fields
}
Server is an SSH File Transfer Protocol (sftp) server. This is intended to provide the sftp subsystem to an ssh server daemon. This implementation currently supports most of sftp server protocol version 3, as specified at http://tools.ietf.org/html/draft-ietf-secsh-filexfer-02
func NewServer ¶
func NewServer(rwc io.ReadWriteCloser, options ...ServerOption) (*Server, error)
NewServer creates a new Server instance around the provided streams, serving content from the root of the filesystem. Optionally, ServerOption functions may be specified to further configure the Server.
A subsequent call to Serve() is required to begin serving files over SFTP.
type ServerOption ¶
A ServerOption is a function which applies configuration to a Server.
func ReadOnly ¶
func ReadOnly() ServerOption
ReadOnly configures a Server to serve files in read-only mode.
func WithDebug ¶
func WithDebug(w io.Writer) ServerOption
WithDebug enables Server debugging output to the supplied io.Writer.
type SftpConf ¶
type SftpConf struct { Power bool /* 是否允许匿名登录FTP服务器,默认设置为YES允许 用户可使用用户名ftp或anonymous进行ftp登录,口令为用户的E-mail地址。 如不允许匿名访问则设置为NO */ Anonymous_enable bool /* 是否允许本地用户对FTP服务器文件具有写权限,默认设置为YES允许 */ Write_enable bool /* 是否允许匿名用户上传文件,须将全局的write_enable=YES。默认为YES */ Anon_upload_enable bool Ftpd_banner string /* 设置数据传输中断间隔时间,此语句表示空闲的用户会话中断时间为600秒 即当数据传输结束后,用户连接FTP服务器的时间不应超过600秒。可以根据实际情况对该值进行修改 */ Idle_session_timeout int /* 设置数据连接超时时间,该语句表示数据连接超时时间为120秒,可根据实际情况对其个修改 */ Data_connection_timeout int /* 是否以ASCII方式传输数据。默认情况下,服务器会忽略ASCII方式的请求。 启用此选项将允许服务器以ASCII方式传输数据 不过,这样可能会导致由"SIZE /big/file"方式引起的DoS攻击 */ Ascii_upload_enable bool Ascii_download_enable bool /* 是否允许递归查询。默认为关闭,以防止远程用户造成过量的I/O */ Ls_recurse_enable bool //文件夹最大显示文件数。默认是10000 Max_show_sum int Version string }
func NewFtpConf ¶
func NewFtpConf() *SftpConf
type StatExtended ¶
StatExtended contains additional, extended information for a FileStat.
type StatVFS ¶
type StatVFS struct { ID uint32 Bsize uint64 /* file system block size */ Frsize uint64 /* fundamental fs block size */ Blocks uint64 /* number of blocks (unit f_frsize) */ Bfree uint64 /* free blocks in file system */ Bavail uint64 /* free blocks for non-root */ Files uint64 /* total file inodes */ Ffree uint64 /* free file inodes */ Favail uint64 /* free file inodes for to non-root */ Fsid uint64 /* file system id */ Flag uint64 /* bit mask of f_flag values */ Namemax uint64 /* maximum filename length */ }
A StatVFS contains statistics about a filesystem.
func (*StatVFS) MarshalBinary ¶
Convert to ssh_FXP_EXTENDED_REPLY packet binary format
func (*StatVFS) TotalSpace ¶
TotalSpace calculates the amount of total space in a filesystem.
type StatusError ¶
type StatusError struct { Code uint32 // contains filtered or unexported fields }
A StatusError is returned when an SFTP operation fails, and provides additional information about the failure.
func (*StatusError) Error ¶
func (s *StatusError) Error() string