sftp: github.com/pkg/sftp Index | Examples | Files | Directories

package sftp

import "github.com/pkg/sftp"

Package sftp implements the SSH File Transfer Protocol as described in https://tools.ietf.org/html/draft-ietf-secsh-filexfer-02

Code:

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)

Index

Examples

Package Files

attrs.go attrs_unix.go client.go conn.go match.go packet-manager.go packet-typing.go packet.go release.go request-attrs.go request-errors.go request-example.go request-interfaces.go request-server.go request-unix.go request.go server.go server_statvfs_impl.go server_statvfs_linux.go server_unix.go sftp.go

Constants

const (
    ErrSshFxOk               = fxerr(ssh_FX_OK)
    ErrSshFxEof              = fxerr(ssh_FX_EOF)
    ErrSshFxNoSuchFile       = fxerr(ssh_FX_NO_SUCH_FILE)
    ErrSshFxPermissionDenied = fxerr(ssh_FX_PERMISSION_DENIED)
    ErrSshFxFailure          = fxerr(ssh_FX_FAILURE)
    ErrSshFxBadMessage       = fxerr(ssh_FX_BAD_MESSAGE)
    ErrSshFxNoConnection     = fxerr(ssh_FX_NO_CONNECTION)
    ErrSshFxConnectionLost   = fxerr(ssh_FX_CONNECTION_LOST)
    ErrSshFxOpUnsupported    = fxerr(ssh_FX_OP_UNSUPPORTED)
)
const (
    SftpServerWorkerCount = 8
)

Variables

var ErrBadPattern = path.ErrBadPattern

ErrBadPattern indicates a globbing pattern was malformed.

var InternalInconsistency = errors.New("internal inconsistency")

InternalInconsistency indicates the packets sent and the data queued to be written to the file don't match up. It is an unusual error and usually is caused by bad behavior server side or connection issues. The error is limited in scope to the call where it happened, the client object is still OK to use as long as the connection is still open.

var MaxFilelist int64 = 100

MaxFilelist is the max number of files to return in a readdir batch.

func Join Uses

func Join(elem ...string) string

Join joins any number of path elements into a single path, adding a Separator if necessary. all empty strings are ignored.

func Match Uses

func Match(pattern, name string) (matched bool, err error)

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 Split Uses

func Split(path string) (dir, file string)

Split splits path immediately following the final Separator, separating it into a directory and file name component. If there is no Separator in path, Split returns an empty dir and file set to path. The returned values have the property that path = dir+file.

type Client Uses

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 NewClient Uses

func NewClient(conn *ssh.Client, opts ...ClientOption) (*Client, error)

NewClient creates a new SFTP client on conn, using zero or more option functions.

func NewClientPipe Uses

func NewClientPipe(rd io.Reader, wr io.WriteCloser, opts ...ClientOption) (*Client, error)

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).

Code:

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

func (*Client) Chmod Uses

func (c *Client) Chmod(path string, mode os.FileMode) error

Chmod changes the permissions of the named file.

func (*Client) Chown Uses

func (c *Client) Chown(path string, uid, gid int) error

Chown changes the user and group owners of the named file.

func (*Client) Chtimes Uses

func (c *Client) Chtimes(path string, atime time.Time, mtime time.Time) error

Chtimes changes the access and modification times of the named file.

func (*Client) Close Uses

func (c *Client) Close() error

Close closes the SFTP session.

func (*Client) Create Uses

func (c *Client) Create(path string) (*File, error)

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. If you need more control over the flags/mode used to open the file see client.OpenFile.

func (*Client) Getwd Uses

func (c *Client) Getwd() (string, error)

Getwd returns the current working directory of the server. Operations involving relative paths will be based at this location.

func (*Client) Glob Uses

func (c *Client) Glob(pattern string) (matches []string, err error)

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 Uses

func (c *Client) Join(elem ...string) string

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 Uses

func (c *Client) Lstat(p string) (os.FileInfo, error)

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 Uses

func (c *Client) Mkdir(path string) error

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).

Code:

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

sshFxFailure := uint32(4)
mkdirParents := func(client *sftp.Client, dir string) (err error) {
    var parents string

    if path.IsAbs(dir) {
        // Otherwise, an absolute path given below would be turned in to a relative one
        // by splitting on "/"
        parents = "/"
    }

    for _, name := range strings.Split(dir, "/") {
        if name == "" {
            // Paths with double-/ in them should just move along
            // this will also catch the case of the first character being a "/", i.e. an absolute path
            continue
        }
        parents = path.Join(parents, name)
        err = client.Mkdir(parents)
        if status, ok := err.(*sftp.StatusError); ok {
            if status.Code == sshFxFailure {
                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)
}

func (*Client) MkdirAll Uses

func (c *Client) MkdirAll(path string) error

MkdirAll creates a directory named path, along with any necessary parents, and returns nil, or else returns an error. If path is already a directory, MkdirAll does nothing and returns nil. If path contains a regular file, an error is returned

func (*Client) Open Uses

func (c *Client) Open(path string) (*File, error)

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 Uses

func (c *Client) OpenFile(path string, f int) (*File, error)

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) PosixRename Uses

func (c *Client) PosixRename(oldname, newname string) error

PosixRename renames a file using the posix-rename@openssh.com extension which will replace newname if it already exists.

func (*Client) ReadDir Uses

func (c *Client) ReadDir(p string) ([]os.FileInfo, error)

ReadDir reads the directory named by dirname and returns a list of directory entries.

func (c *Client) ReadLink(p string) (string, error)

ReadLink reads the target of a symbolic link.

func (*Client) Remove Uses

func (c *Client) Remove(path string) error

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 Uses

func (c *Client) RemoveDirectory(path string) error

RemoveDirectory removes a directory path.

func (*Client) Rename Uses

func (c *Client) Rename(oldname, newname string) error

Rename renames a file.

func (*Client) Stat Uses

func (c *Client) Stat(p string) (os.FileInfo, error)

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 Uses

func (c *Client) StatVFS(path string) (*StatVFS, error)

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.

func (c *Client) Symlink(oldname, newname string) error

Symlink creates a symbolic link at 'newname', pointing at target 'oldname'

func (*Client) Truncate Uses

func (c *Client) Truncate(path string, size int64) error

Truncate sets the size of the named 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.

func (*Client) Walk Uses

func (c *Client) Walk(root string) *fs.Walker

Walk returns a new Walker rooted at root.

type ClientOption Uses

type ClientOption func(*Client) error

A ClientOption is a function which applies configuration to a Client.

func MaxPacket Uses

func MaxPacket(size int) ClientOption

MaxPacket sets the maximum size of the payload, measured in bytes. This option only accepts sizes servers should support, ie. <= 32768 bytes. This is a synonym for MaxPacketChecked that provides backward compatibility.

If you get the error "failed to send packet header: EOF" when copying a large file, try lowering this number.

The default packet size is 32768 bytes.

func MaxPacketChecked Uses

func MaxPacketChecked(size int) ClientOption

MaxPacketChecked sets the maximum size of the payload, measured in bytes. This option only accepts sizes servers should support, ie. <= 32768 bytes.

If you get the error "failed to send packet header: EOF" when copying a large file, try lowering this number.

The default packet size is 32768 bytes.

func MaxPacketUnchecked Uses

func MaxPacketUnchecked(size int) ClientOption

MaxPacketUnchecked sets the maximum size of the payload, measured in bytes. It accepts sizes larger than the 32768 bytes all servers should support. Only use a setting higher than 32768 if your application always connects to the same server or after sufficiently broad testing.

If you get the error "failed to send packet header: EOF" when copying a large file, try lowering this number.

The default packet size is 32768 bytes.

type File Uses

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

File represents a remote file.

func (*File) Chmod Uses

func (f *File) Chmod(mode os.FileMode) error

Chmod changes the permissions of the current file.

func (*File) Chown Uses

func (f *File) Chown(uid, gid int) error

Chown changes the uid/gid of the current file.

func (*File) Close Uses

func (f *File) Close() error

Close closes the File, rendering it unusable for I/O. It returns an error, if any.

func (*File) Name Uses

func (f *File) Name() string

Name returns the name of the file as presented to Open or Create.

func (*File) Read Uses

func (f *File) Read(b []byte) (int, error)

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.

To maximise throughput for transferring the entire file (especially over high latency links) it is recommended to use WriteTo rather than calling Read multiple times. io.Copy will do this automatically.

func (*File) ReadFrom Uses

func (f *File) ReadFrom(r io.Reader) (int64, error)

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.

This method is preferred over calling Write multiple times to maximise throughput for transferring the entire file (especially over high latency links).

Code:

// Using Bufio to buffer writes going to an sftp.File won't buffer as it
// skips buffering if the underlying writer support ReadFrom. The
// workaround is to wrap your writer in a struct that only implements
// io.Writer.
//
// For background see github.com/pkg/sftp/issues/125

var data_source io.Reader
var f *sftp.File
type writerOnly struct{ io.Writer }
bw := bufio.NewWriter(writerOnly{f}) // no ReadFrom()
bw.ReadFrom(data_source)

func (*File) Seek Uses

func (f *File) Seek(offset int64, whence int) (int64, error)

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) Stat Uses

func (f *File) Stat() (os.FileInfo, error)

Stat returns the FileInfo structure describing file. If there is an error.

func (*File) Truncate Uses

func (f *File) Truncate(size int64) error

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.

func (*File) Write Uses

func (f *File) Write(b []byte) (int, error)

Write writes len(b) bytes to the File. It returns the number of bytes written and an error, if any. Write returns a non-nil error when n != len(b).

To maximise throughput for transferring the entire file (especially over high latency links) it is recommended to use ReadFrom rather than calling Write multiple times. io.Copy will do this automatically.

func (*File) WriteTo Uses

func (f *File) WriteTo(w io.Writer) (int64, error)

WriteTo writes the file to w. The return value is the number of bytes written. Any error encountered during the write is also returned.

This method is preferred over calling Read multiple times to maximise throughput for transferring the entire file (especially over high latency links).

type FileAttrFlags Uses

type FileAttrFlags struct {
    Size, UidGid, Permissions, Acmodtime bool
}

Flags that indicate whether SFTP file attributes were passed. When a flag is true the corresponding attribute should be available from the FileStat object returned by Attributes method. Used with SetStat.

type FileCmder Uses

type FileCmder interface {
    Filecmd(*Request) error
}

FileCmder should return an error Note in cases of an error, the error text will be sent to the client. Called for Methods: Setstat, Rename, Rmdir, Mkdir, Symlink, Remove

type FileLister Uses

type FileLister interface {
    Filelist(*Request) (ListerAt, error)
}

FileLister should return an object that fulfils the ListerAt interface Note in cases of an error, the error text will be sent to the client. Called for Methods: List, Stat, Readlink

type FileOpenFlags Uses

type FileOpenFlags struct {
    Read, Write, Append, Creat, Trunc, Excl bool
}

File Open and Write Flags. Correlate directly with with os.OpenFile flags (https://golang.org/pkg/os/#pkg-constants).

type FileReader Uses

type FileReader interface {
    Fileread(*Request) (io.ReaderAt, error)
}

FileReader should return an io.ReaderAt for the filepath Note in cases of an error, the error text will be sent to the client. Called for Methods: Get

type FileStat Uses

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(). It is also used server side to store the unmarshalled values for SetStat.

func (FileStat) FileMode Uses

func (a FileStat) FileMode() os.FileMode

FileMode returns the Mode SFTP file attributes wrapped as os.FileMode

type FileWriter Uses

type FileWriter interface {
    Filewrite(*Request) (io.WriterAt, error)
}

FileWriter should return an io.WriterAt for the filepath.

The request server code will call Close() on the returned io.WriterAt ojbect if an io.Closer type assertion succeeds. Note in cases of an error, the error text will be sent to the client. Called for Methods: Put, Open

type Handlers Uses

type Handlers struct {
    FileGet  FileReader
    FilePut  FileWriter
    FileCmd  FileCmder
    FileList FileLister
}

Handlers contains the 4 SFTP server request handlers.

func InMemHandler Uses

func InMemHandler() Handlers

InMemHandler returns a Hanlders object with the test handlers.

type ListerAt Uses

type ListerAt interface {
    ListAt([]os.FileInfo, int64) (int, error)
}

ListerAt does for file lists what io.ReaderAt does for files. ListAt should return the number of entries copied and an io.EOF error if at end of list. This is testable by comparing how many you copied to how many could be copied (eg. n < len(ls) below). The copy() builtin is best for the copying. Note in cases of an error, the error text will be sent to the client.

type Request Uses

type Request struct {
    // Get, Put, Setstat, Stat, Rename, Remove
    // Rmdir, Mkdir, List, Readlink, Symlink
    Method   string
    Filepath string
    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 Uses

func NewRequest(method, path string) *Request

NewRequest creates a new Request object.

func (*Request) AttrFlags Uses

func (r *Request) AttrFlags() FileAttrFlags

FileAttrFlags returns a FileAttrFlags boolean struct based on the bitmap/uint32 file attribute flags from the SFTP packaet.

func (*Request) Attributes Uses

func (r *Request) Attributes() *FileStat

Attributres parses file attributes byte blob and return them in a FileStat object.

func (*Request) Context Uses

func (r *Request) Context() context.Context

Context returns the request's context. To change the context, use WithContext.

The returned context is always non-nil; it defaults to the background context.

For incoming server requests, the context is canceled when the request is complete or the client's connection closes.

func (*Request) Pflags Uses

func (r *Request) Pflags() FileOpenFlags

Pflags converts the bitmap/uint32 from SFTP Open packet pflag values, into a FileOpenFlags struct with booleans set for flags set in bitmap.

func (*Request) WithContext Uses

func (r *Request) WithContext(ctx context.Context) *Request

WithContext returns a copy of r with its context changed to ctx. The provided ctx must be non-nil.

type RequestServer Uses

type RequestServer struct {
    Handlers Handlers
    // contains filtered or unexported fields
}

RequestServer abstracts the sftp protocol with an http request-like protocol

func NewRequestServer Uses

func NewRequestServer(rwc io.ReadWriteCloser, h Handlers) *RequestServer

NewRequestServer creates/allocates/returns new RequestServer. Normally there there will be one server per user-session.

func (*RequestServer) Close Uses

func (rs *RequestServer) Close() error

Close the read/write/closer to trigger exiting the main server loop

func (*RequestServer) Serve Uses

func (rs *RequestServer) Serve() error

Serve requests for user session

type Server Uses

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 Uses

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.

func (*Server) Serve Uses

func (svr *Server) Serve() error

Serve serves SFTP connections until the streams stop or the SFTP subsystem is stopped.

type ServerOption Uses

type ServerOption func(*Server) error

A ServerOption is a function which applies configuration to a Server.

func ReadOnly Uses

func ReadOnly() ServerOption

ReadOnly configures a Server to serve files in read-only mode.

func WithDebug Uses

func WithDebug(w io.Writer) ServerOption

WithDebug enables Server debugging output to the supplied io.Writer.

type StatExtended Uses

type StatExtended struct {
    ExtType string
    ExtData string
}

StatExtended contains additional, extended information for a FileStat.

type StatVFS Uses

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) FreeSpace Uses

func (p *StatVFS) FreeSpace() uint64

FreeSpace calculates the amount of free space in a filesystem.

func (*StatVFS) MarshalBinary Uses

func (p *StatVFS) MarshalBinary() ([]byte, error)

Convert to ssh_FXP_EXTENDED_REPLY packet binary format

func (*StatVFS) TotalSpace Uses

func (p *StatVFS) TotalSpace() uint64

TotalSpace calculates the amount of total space in a filesystem.

type StatusError Uses

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 Uses

func (s *StatusError) Error() string

Directories

PathSynopsis
examples/buffered-read-benchmarkbuffered-read-benchmark benchmarks the peformance of reading from /dev/zero on the server to a []byte on the client via io.Copy.
examples/buffered-write-benchmarkbuffered-write-benchmark benchmarks the peformance of writing a single large []byte on the client to /dev/null on the server via io.Copy.
examples/request-serverAn example SFTP server implementation using the golang SSH package.
examples/sftp-serverAn example SFTP server implementation using the golang SSH package.
examples/streaming-read-benchmarkstreaming-read-benchmark benchmarks the peformance of reading from /dev/zero on the server to /dev/null on the client via io.Copy.
examples/streaming-write-benchmarkstreaming-write-benchmark benchmarks the peformance of writing from /dev/zero on the client to /dev/null on the server via io.Copy.
server_standalone

Package sftp imports 23 packages (graph) and is imported by 190 packages. Updated 2018-05-26. Refresh now. Tools for package owners.