Documentation
¶
Overview ¶
Package sftp is a pure-Go (CGO=0), MRI-faithful reimplementation of the wire codec behind Ruby's Net::SFTP — the SFTP protocol (draft-ietf-secsh-filexfer) packet encode/decode for versions 1 through 6.
SFTP runs over an SSH channel. This package owns only the deterministic, interpreter-independent part: framing FXP_* request packets, parsing FXP_* response packets, the version-aware file-attributes (ATTRS) structure, Name entries, request-id correlation, and protocol-version negotiation. The SSH transport itself — opening the channel, encryption, and the channel read/write of the framed bytes — is the host's responsibility (the "channel seam"): the host writes the bytes from Packet.Frame to the channel, and feeds bytes read from the channel into a PacketParser. No Ruby runtime and no real SSH are required to use, or to fully test, this library.
Index ¶
- Constants
- Variables
- func FramePacket(typ byte, payload []byte) []byte
- func InitPacket(version int) []byte
- func NegotiateVersion(serverVersion uint32, clientHighest int) (int, error)
- func NormalizeOpenFlags(mode string) (int, error)
- func OpenFlagsV1(flags int) uint32
- func OpenFlagsV5(flags int) (sftpFlags, desiredAccess uint32)
- func ParseResponse(pkt Packet, version int) (any, error)
- func ResponseID(payload []byte) (uint32, error)
- func StatusDescription(code uint32) string
- type ACL
- type Attributes
- type AttrsResponse
- type DataResponse
- type ExtPair
- type HandleResponse
- type Name
- type NameResponse
- type Packet
- type PacketParser
- type Protocol
- func (p *Protocol) Block(handle []byte, offset, length uint64, mask uint32) (uint32, []byte, error)
- func (p *Protocol) Close(handle []byte) (uint32, []byte)
- func (p *Protocol) Fsetstat(handle []byte, attrs *Attributes) (uint32, []byte)
- func (p *Protocol) Fstat(handle []byte, flags *uint32) (uint32, []byte)
- func (p *Protocol) Link(newLinkPath, existingPath string, symlink bool) (uint32, []byte, error)
- func (p *Protocol) Lstat(path string, flags *uint32) (uint32, []byte)
- func (p *Protocol) Mkdir(path string, attrs *Attributes) (uint32, []byte)
- func (p *Protocol) Open(path string, sftpFlags, desiredAccess uint32, attrs *Attributes) (uint32, []byte)
- func (p *Protocol) Opendir(path string) (uint32, []byte)
- func (p *Protocol) Read(handle []byte, offset uint64, length uint32) (uint32, []byte)
- func (p *Protocol) Readdir(handle []byte) (uint32, []byte)
- func (p *Protocol) Readlink(path string) (uint32, []byte, error)
- func (p *Protocol) Realpath(path string) (uint32, []byte)
- func (p *Protocol) Remove(filename string) (uint32, []byte)
- func (p *Protocol) Rename(name, newName string, flags *uint32) (uint32, []byte, error)
- func (p *Protocol) Rmdir(path string) (uint32, []byte)
- func (p *Protocol) Setstat(path string, attrs *Attributes) (uint32, []byte)
- func (p *Protocol) Stat(path string, flags *uint32) (uint32, []byte)
- func (p *Protocol) Symlink(path, target string) (uint32, []byte, error)
- func (p *Protocol) Unblock(handle []byte, offset, length uint64) (uint32, []byte, error)
- func (p *Protocol) Version() int
- func (p *Protocol) Write(handle []byte, offset uint64, data []byte) (uint32, []byte)
- type Reader
- func (r *Reader) EOF() bool
- func (r *Reader) ReadBool() (bool, error)
- func (r *Reader) ReadByte() (byte, error)
- func (r *Reader) ReadString() ([]byte, error)
- func (r *Reader) ReadStringStr() (string, error)
- func (r *Reader) ReadUint32() (uint32, error)
- func (r *Reader) ReadUint64() (uint64, error)
- func (r *Reader) Remaining() int
- type StatusException
- type StatusResponse
- type VersionInfo
- type Writer
- func (w *Writer) Bytes() []byte
- func (w *Writer) Len() int
- func (w *Writer) PutByte(b byte) *Writer
- func (w *Writer) WriteBool(v bool) *Writer
- func (w *Writer) WriteBytes(b []byte) *Writer
- func (w *Writer) WriteRaw(b []byte) *Writer
- func (w *Writer) WriteString(s string) *Writer
- func (w *Writer) WriteUint32(v uint32) *Writer
- func (w *Writer) WriteUint64(v uint64) *Writer
Constants ¶
const ( FSize = 0x00000001 FUIDGID = 0x00000002 // v1-v3 only FPermissions = 0x00000004 FACModTime = 0x00000008 // v1-v3 only (atime+mtime as 32-bit) // v4+ flags FAccessTime = 0x00000008 FCreateTime = 0x00000010 FModifyTime = 0x00000020 FACL = 0x00000040 FOwnerGroup = 0x00000080 FSubsecondTime = 0x00000100 // v6+ flags FBits = 0x00000200 FAllocationSize = 0x00000400 FTextHint = 0x00000800 FMimeType = 0x00001000 FLinkCount = 0x00002000 FUntranslatedName = 0x00004000 FCTime = 0x00008000 FExtended = 0x80000000 )
Attribute-structure presence flags. The version-1 layout (also used by v2/v3) uses F_SIZE/F_UIDGID/F_PERMISSIONS/F_ACMODTIME/F_EXTENDED; versions 4+ reuse the low bits for richer fields. These mirror the F_* constants on each Net::SFTP::Protocol::V0x::Attributes class.
const ( FXP_INIT = 1 FXP_VERSION = 2 FXP_OPEN = 3 FXP_CLOSE = 4 FXP_READ = 5 FXP_WRITE = 6 FXP_LSTAT = 7 FXP_FSTAT = 8 FXP_SETSTAT = 9 FXP_FSETSTAT = 10 FXP_OPENDIR = 11 FXP_READDIR = 12 FXP_REMOVE = 13 FXP_MKDIR = 14 FXP_RMDIR = 15 FXP_REALPATH = 16 FXP_STAT = 17 FXP_RENAME = 18 FXP_READLINK = 19 FXP_SYMLINK = 20 FXP_LINK = 21 FXP_BLOCK = 22 FXP_UNBLOCK = 23 FXP_STATUS = 101 FXP_HANDLE = 102 FXP_DATA = 103 FXP_NAME = 104 FXP_ATTRS = 105 FXP_EXTENDED = 200 FXP_EXTENDED_REPLY = 201 )
Packet type bytes for SFTP protocol versions 1 through 6 (Net::SFTP::Constants::PacketTypes).
const ( RenameOverwrite = 0x00000001 RenameAtomic = 0x00000002 RenameNative = 0x00000004 )
FXP_RENAME flags, valid from protocol version 5 (Net::SFTP::Constants::RenameFlags).
const ( FX_OK = 0 FX_EOF = 1 FX_NO_SUCH_FILE = 2 FX_PERMISSION_DENIED = 3 FX_FAILURE = 4 FX_BAD_MESSAGE = 5 FX_NO_CONNECTION = 6 FX_CONNECTION_LOST = 7 FX_OP_UNSUPPORTED = 8 FX_INVALID_HANDLE = 9 FX_NO_SUCH_PATH = 10 FX_FILE_ALREADY_EXISTS = 11 FX_WRITE_PROTECT = 12 FX_NO_MEDIA = 13 FX_NO_SPACE_ON_FILESYSTEM = 14 FX_QUOTA_EXCEEDED = 15 FX_UNKNOWN_PRINCIPLE = 16 FX_LOCK_CONFLICT = 17 FX_DIR_NOT_EMPTY = 18 FX_NOT_A_DIRECTORY = 19 FX_INVALID_FILENAME = 20 FX_LINK_LOOP = 21 )
FXP_STATUS codes (Net::SFTP::Constants::StatusCodes). FX_OK..FX_LINK_LOOP map to the human-readable descriptions returned by StatusDescription.
const ( FV1_READ = 0x00000001 FV1_WRITE = 0x00000002 FV1_APPEND = 0x00000004 FV1_CREAT = 0x00000008 FV1_TRUNC = 0x00000010 FV1_EXCL = 0x00000020 )
Open-mode flags understood by protocol versions 1-4 (Net::SFTP::Constants::OpenFlags::FV1).
const ( FV5_CREATE_NEW = 0x00000000 FV5_CREATE_TRUNCATE = 0x00000001 FV5_OPEN_EXISTING = 0x00000002 FV5_OPEN_OR_CREATE = 0x00000003 FV5_TRUNCATE_EXISTING = 0x00000004 FV5_APPEND_DATA = 0x00000008 FV5_APPEND_DATA_ATOMIC = 0x00000010 FV5_TEXT_MODE = 0x00000020 FV5_READ_LOCK = 0x00000040 FV5_WRITE_LOCK = 0x00000080 FV5_DELETE_LOCK = 0x00000100 FV6_ADVISORY_LOCK = 0x00000200 FV6_NOFOLLOW = 0x00000400 FV6_DELETE_ON_CLOSE = 0x00000800 FV6_ACCESS_AUDIT_ALARM_INFO = 0x00001000 FV6_ACCESS_BACKUP = 0x00002000 FV6_BACKUP_STREAM = 0x00004000 FV6_OVERRIDE_OWNER = 0x00008000 )
Open-mode flags understood by protocol versions 5 and 6 (Net::SFTP::Constants::OpenFlags::FV5 / FV6).
const ( LockRead = FV5_READ_LOCK LockWrite = FV5_WRITE_LOCK LockDelete = FV5_DELETE_LOCK LockAdvisory = FV6_ADVISORY_LOCK )
Byte-range lock types for FXP_BLOCK, protocol version 6 (Net::SFTP::Constants::LockTypes).
const ( ACEAccessAllowed = 0x00000000 ACEAccessDenied = 0x00000001 ACESystemAudit = 0x00000002 ACESystemAlarm = 0x00000003 )
Access-control entry types, from protocol version 4 (Net::SFTP::Constants::ACE::Type).
const ( ACEFileInherit = 0x00000001 ACEDirectoryInherit = 0x00000002 ACENoPropagateInherit = 0x00000004 ACEInheritOnly = 0x00000008 ACESuccessfulAccess = 0x00000010 ACEFailedAccess = 0x00000020 ACEIdentifierGroup = 0x00000040 )
Access-control entry flags, from protocol version 4 (Net::SFTP::Constants::ACE::Flag).
const ( ACEReadData = 0x00000001 ACEListDirectory = 0x00000001 ACEWriteData = 0x00000002 ACEAddFile = 0x00000002 ACEAppendData = 0x00000004 ACEAddSubdirectory = 0x00000004 ACEReadNamedAttrs = 0x00000008 ACEWriteNamedAttrs = 0x00000010 ACEExecute = 0x00000020 ACEDeleteChild = 0x00000040 ACEReadAttributes = 0x00000080 ACEWriteAttributes = 0x00000100 ACEDelete = 0x00010000 ACEReadACL = 0x00020000 ACEWriteACL = 0x00040000 ACEWriteOwner = 0x00080000 ACESynchronize = 0x00100000 )
Access-control entry masks, from protocol version 4 (Net::SFTP::Constants::ACE::Mask).
const ( TRegular = 1 TDirectory = 2 TSymlink = 3 TSpecial = 4 TUnknown = 5 TSocket = 6 TCharDevice = 7 TBlockDevice = 8 TFIFO = 9 )
File-type codes inferred from the permission bits of an Attributes value (Net::SFTP::Protocol::V01::Attributes T_* constants).
const ( IORDONLY = 0x0000 IOWRONLY = 0x0001 IORDWR = 0x0002 IOAPPEND = 0x0008 IOCREAT = 0x0200 IOTRUNC = 0x0400 IOEXCL = 0x0800 )
IO-mode bits, matching Ruby's File::Constants used by Net::SFTP's open-flag translation. These are the conventional POSIX values MRI exposes via IO::*.
const DefaultStatFlags = FSize | FPermissions | FAccessTime | FCreateTime | FModifyTime | FACL | FOwnerGroup | FSubsecondTime | FExtended
DefaultStatFlags is the flag mask used for stat/lstat/fstat requests in protocol versions 4 and above when no explicit flags are given (Net::SFTP::Protocol::V04::Base::DEFAULT_FLAGS).
const HighestProtocolVersionSupported = 6
HighestProtocolVersionSupported is the newest SFTP protocol version this codec implements (Net::SFTP::Session::HIGHEST_PROTOCOL_VERSION_SUPPORTED).
Variables ¶
var ErrShortBuffer = errors.New("sftp: buffer underrun")
ErrShortBuffer is returned by a Reader when a read runs past the end of the underlying bytes. MRI's Net::SSH::Buffer returns nil in that case and the SFTP layer then raises; here the error is surfaced explicitly so callers can decide.
Functions ¶
func FramePacket ¶
FramePacket builds the on-the-wire bytes for a packet: a uint32 length prefix (payload length + 1 for the type byte), the type byte, then the payload. This is the framing Net::SFTP::Session#send_packet performs before handing the bytes to the SSH channel — the host writes the returned slice to the channel.
func InitPacket ¶
InitPacket builds an FXP_INIT frame advertising the client's highest supported protocol version (Net::SFTP::Session#do_init). The returned bytes are written to the SSH channel by the host to begin the session.
func NegotiateVersion ¶
NegotiateVersion returns the protocol version both peers agree on: the lesser of the server's version and the client's highest supported version (Net::SFTP::Session#do_version). It errors if the negotiated version is below 1.
func NormalizeOpenFlags ¶
NormalizeOpenFlags converts a mode string ("r", "r+", "w", "w+", "a", "a+", optionally with a "b") into the IO-bit combination Net::SFTP uses (Protocol::V01::Base#normalize_open_flags). It errors on an unsupported mode.
func OpenFlagsV1 ¶
OpenFlagsV1 translates an IO-bit combination into the FV1 SFTP open-flag word used by protocol versions 1-4 (Protocol::V01::Base#open).
func OpenFlagsV5 ¶
OpenFlagsV5 translates an IO-bit combination into the (sftpFlags, desiredAccess) pair used by protocol versions 5 and 6 (Protocol::V05::Base#open). sftpFlags is one of the FV5_* dispositions (optionally OR'd with APPEND_DATA); desiredAccess is the ACE access mask.
func ParseResponse ¶
ParseResponse decodes a response packet by its type byte, returning a typed value (*StatusResponse, *HandleResponse, *DataResponse, *NameResponse, or *AttrsResponse). It errors on a request (non-response) or unknown type, matching Protocol::Base#parse.
func ResponseID ¶
ResponseID reads just the request id (the first field) from any response payload, so a host can correlate a packet to its request before dispatching to the type-specific parser.
func StatusDescription ¶
StatusDescription returns the human-readable name for a status code, matching Net::SFTP::Response::MAP. Unknown codes return "" (as MAP[code] would be nil).
Types ¶
type ACL ¶
ACL is one entry of an access-control list (v4+), Net::SFTP::Protocol::V04::Attributes::ACL.
type Attributes ¶
type Attributes struct {
Type *uint8 // v4+ leading type byte
Size *uint64
AllocationSize *uint64 // v6+
UID *uint32 // v1-v3
GID *uint32 // v1-v3
Owner *string // v4+
Group *string // v4+
Permissions *uint32
Atime *uint64 // 32-bit on v1-v3, 64-bit on v4+
AtimeNanos *uint32 // v4+ subsecond
CreateTime *uint64 // v4+
CreateTimeNanos *uint32 // v4+ subsecond
Mtime *uint64 // 32-bit on v1-v3, 64-bit on v4+
MtimeNanos *uint32 // v4+ subsecond
CTime *uint64 // v6+
CTimeNanos *uint32 // v6+ subsecond
ACL []ACL // v4+
AttribBits *uint32 // v6+
AttribBitsValid *uint32 // v6+
TextHint *uint8 // v6+
MimeType *string // v6+
LinkCount *uint32 // v6+
UntranslatedName *string // v6+
Extended []ExtPair
}
Attributes is the version-aware file-attributes (ATTRS) structure. Optional fields are pointers: a nil pointer means the corresponding presence bit is clear, matching MRI where an absent key leaves the flag unset. Encode and Decode are parameterised by protocol version so the same struct serialises into the v1, v4/v5, or v6 element layout.
func DecodeAttributes ¶
func DecodeAttributes(r *Reader, version int) (*Attributes, error)
DecodeAttributes parses an attribute structure for the given protocol version from r, mirroring Attributes.from_buffer. Fields whose presence bit is clear are left nil.
func (*Attributes) Encode ¶
func (a *Attributes) Encode(version int) []byte
Encode serialises the attributes for the given protocol version. It first computes the flags word from which fields are present, writes it, then writes each present element in layout order. The result matches Attributes#to_s.
func (*Attributes) FileType ¶
func (a *Attributes) FileType() int
FileType classifies the attributes from their permission bits, returning one of the T_* constants (Net::SFTP::Protocol::V01::Attributes#type). It returns TUnknown when no permissions are set.
func (*Attributes) IsDirectory ¶
func (a *Attributes) IsDirectory() (val, known bool)
IsDirectory reports whether the attributes describe a directory; the second return is false when the type is indeterminate (TUnknown), mirroring MRI's nil.
func (*Attributes) IsFile ¶
func (a *Attributes) IsFile() (val, known bool)
IsFile reports whether the attributes describe a regular file (see IsDirectory).
func (*Attributes) IsSymlink ¶
func (a *Attributes) IsSymlink() (val, known bool)
IsSymlink reports whether the attributes describe a symlink (see IsDirectory).
type AttrsResponse ¶
type AttrsResponse struct {
ID uint32
Attrs *Attributes
}
AttrsResponse is a parsed FXP_ATTRS packet wrapping a single attribute structure.
func ParseAttrs ¶
func ParseAttrs(payload []byte, version int) (*AttrsResponse, error)
ParseAttrs decodes an FXP_ATTRS payload for the given protocol version (Net::SFTP::Protocol::V01::Base#parse_attrs_packet).
type DataResponse ¶
DataResponse is a parsed FXP_DATA packet carrying file data read from the server.
func ParseData ¶
func ParseData(payload []byte) (*DataResponse, error)
ParseData decodes an FXP_DATA payload (Net::SFTP::Protocol::V01::Base#parse_data_packet).
type ExtPair ¶
ExtPair is one name/value pair of the F_EXTENDED extended-attribute map. A slice preserves order so encode/decode round-trips byte-for-byte.
type HandleResponse ¶
HandleResponse is a parsed FXP_HANDLE packet wrapping an opaque file or directory handle.
func ParseHandle ¶
func ParseHandle(payload []byte) (*HandleResponse, error)
ParseHandle decodes an FXP_HANDLE payload (Net::SFTP::Protocol::V01::Base#parse_handle_packet).
type Name ¶
type Name struct {
Filename string
// Longname is the server-supplied display string (v1-v3). For v4+ it is empty
// on the wire; call LongnameFor to render an ls-style line from the attributes.
Longname string
Attributes *Attributes
}
Name is one entry of an FXP_NAME response: a remote filename, its attributes, and (in protocol versions 1-3) a server-supplied "longname" display string. From version 4 onward the wire format drops the longname field, and Longname is synthesised on demand from the attributes (Net::SFTP::Protocol::V04::Name).
func (*Name) IsDirectory ¶
IsDirectory reports whether the entry is a directory (see Attributes.IsDirectory).
type NameResponse ¶
NameResponse is a parsed FXP_NAME packet: the list of directory entries returned by FXP_READDIR / FXP_REALPATH.
func ParseName ¶
func ParseName(payload []byte, version int) (*NameResponse, error)
ParseName decodes an FXP_NAME payload for the given protocol version. In v1-3 each entry carries filename, longname, and attributes; from v4 the longname field was dropped (Net::SFTP::Protocol::V04::Base#parse_name_packet).
type Packet ¶
Packet is a decoded SFTP packet: a type byte and the raw payload that follows it (the bytes after the length prefix and type, Net::SFTP::Packet). Use FramePacket to build the on-the-wire bytes and ParsePacket to split a framed packet back into type + payload.
func ParsePacket ¶
ParsePacket splits a single framed packet (length prefix + type + payload) into its type and payload. It is the inverse of FramePacket and reports an error if the buffer is shorter than the declared length.
type PacketParser ¶
type PacketParser struct {
// contains filtered or unexported fields
}
PacketParser reassembles whole SFTP packets from a stream of channel bytes, mirroring Net::SFTP::Session#when_channel_polled. The host feeds it the bytes read from the SSH channel (in any chunking) via Feed; Next then yields each complete packet as it becomes available. This decouples the codec from the transport: no SSH, just the byte boundary logic.
func NewPacketParser ¶
func NewPacketParser() *PacketParser
NewPacketParser returns an empty parser.
func (*PacketParser) Feed ¶
func (p *PacketParser) Feed(b []byte)
Feed appends channel bytes to the parser's input buffer.
func (*PacketParser) Next ¶
func (p *PacketParser) Next() (pkt Packet, ok bool)
Next returns the next complete packet, or ok=false if more bytes are needed. Call it in a loop after each Feed until it reports ok=false.
type Protocol ¶
type Protocol struct {
// contains filtered or unexported fields
}
Protocol is a version-specific SFTP request builder and response parser, mirroring the Net::SFTP::Protocol::V0x::Base hierarchy. It allocates request ids monotonically from -1 (so the first id is 0, exactly as MRI does) and frames each request as on-the-wire bytes the host writes to the SSH channel.
Every request method returns the request id and the framed packet bytes; the id lets the host correlate the eventual FXP_STATUS / FXP_HANDLE / … response back to the request (responses echo the id as their first field).
func NewProtocol ¶
NewProtocol returns a request builder for the negotiated protocol version (1-6). It panics for an out-of-range version, matching Protocol.load's raise.
func (*Protocol) Block ¶
Block builds an FXP_BLOCK byte-range-lock request (v6 only). mask is a combination of the Lock* constants.
func (*Protocol) Fsetstat ¶
func (p *Protocol) Fsetstat(handle []byte, attrs *Attributes) (uint32, []byte)
Fsetstat builds an FXP_FSETSTAT request, applying attrs to an open handle.
func (*Protocol) Fstat ¶
Fstat builds an FXP_FSTAT request for an open handle. flags is honoured from v4.
func (*Protocol) Link ¶
Link builds an FXP_LINK request (v6 only): create newLinkPath pointing at existingPath; symlink selects a symbolic (true) or hard (false) link.
func (*Protocol) Mkdir ¶
func (p *Protocol) Mkdir(path string, attrs *Attributes) (uint32, []byte)
Mkdir builds an FXP_MKDIR request with the given directory attributes.
func (*Protocol) Open ¶
func (p *Protocol) Open(path string, sftpFlags, desiredAccess uint32, attrs *Attributes) (uint32, []byte)
Open builds an FXP_OPEN request. sftpFlags is the protocol-specific open flag word (an FV1_* combination for v1-4, an FV5_* combination for v5-6); for v5+, desiredAccess is the ACE access mask that precedes the flags on the wire. attrs may be nil (an empty attribute structure is sent). Callers translate IO-style flags into sftpFlags / desiredAccess; OpenFlagsV1 and OpenFlagsV5 help.
func (*Protocol) Rename ¶
Rename builds an FXP_RENAME request. It is unavailable in v1 (returns an error). In v2-4 the flags word is omitted; in v5+ a flags word is appended (0 when nil).
func (*Protocol) Setstat ¶
func (p *Protocol) Setstat(path string, attrs *Attributes) (uint32, []byte)
Setstat builds an FXP_SETSTAT request, applying attrs to the file at path.
func (*Protocol) Stat ¶
Stat builds an FXP_STAT request (follows symlinks). flags is honoured from v4.
func (*Protocol) Symlink ¶
Symlink builds a symlink request. Unavailable before v3. In v3-5 it emits an FXP_SYMLINK packet; in v6 the older packet was removed, so it is expressed as an FXP_LINK with the symbolic flag set (Net::SFTP::Protocol::V06::Base#symlink).
func (*Protocol) Unblock ¶
Unblock builds an FXP_UNBLOCK request releasing a byte-range lock (v6 only).
type Reader ¶
type Reader struct {
// contains filtered or unexported fields
}
Reader consumes SSH2-encoded values from a byte slice, mirroring Net::SSH::Buffer's read_* methods.
func (*Reader) EOF ¶
EOF reports whether the read position is at the end of the buffer (Net::SSH::Buffer#eof?).
func (*Reader) ReadBool ¶
ReadBool consumes one byte and reports whether it is non-zero (#read_bool, 'C' rules).
func (*Reader) ReadString ¶
ReadString consumes a uint32-length-prefixed byte string and returns its bytes (#read_string).
func (*Reader) ReadStringStr ¶
ReadStringStr is ReadString returning a Go string.
func (*Reader) ReadUint32 ¶
ReadUint32 consumes a 32-bit network-byte-order integer (#read_long).
func (*Reader) ReadUint64 ¶
ReadUint64 consumes a 64-bit network-byte-order integer (#read_int64).
type StatusException ¶
StatusException reports a non-success FXP_STATUS result, mirroring Net::SFTP::StatusException. Code is the FX_ status code, Description the human-readable name (the server-supplied message when present, else the canonical StatusDescription), and Text any incident-specific context.
func NewStatusException ¶
func NewStatusException(s *StatusResponse, text string) *StatusException
NewStatusException builds an exception from an FXP_STATUS response. If the server message is empty, the canonical description for the code is used, as StatusException#initialize does.
func (*StatusException) Error ¶
func (e *StatusException) Error() string
Error formats the exception as MRI's StatusException#message does: `<text> (<code>, "<description>")`, with the leading text omitted when blank.
type StatusResponse ¶
StatusResponse is a parsed FXP_STATUS packet. Code is the FX_ status code; from protocol version 3, an error message and language tag follow on the wire.
func ParseStatus ¶
func ParseStatus(payload []byte, version int) (*StatusResponse, error)
ParseStatus decodes an FXP_STATUS payload for the given protocol version. The message and language fields are present from version 3 onward; for v1/v2 only the code is read (Net::SFTP::Protocol::V01::Base#parse_status_packet).
func (*StatusResponse) EOF ¶
func (s *StatusResponse) EOF() bool
EOF reports whether the status is FX_EOF (Net::SFTP::Response#eof?).
func (*StatusResponse) OK ¶
func (s *StatusResponse) OK() bool
OK reports whether the status is FX_OK (Net::SFTP::Response#ok?).
type VersionInfo ¶
VersionInfo is the parsed result of an FXP_VERSION packet: the server's advertised protocol version and any name/value protocol extensions that follow.
func ParseVersion ¶
func ParseVersion(payload []byte) (VersionInfo, error)
ParseVersion decodes an FXP_VERSION payload (Net::SFTP::Session#do_version): the server version followed by zero or more (name, data) extension pairs until the buffer is exhausted.
type Writer ¶
type Writer struct {
// contains filtered or unexported fields
}
Writer accumulates SSH2-encoded values, mirroring Net::SSH::Buffer's write_* methods byte-for-byte: 32-bit and 64-bit integers in network byte order, length-prefixed strings, single bytes, and 'C'-rule booleans.
func (*Writer) Bytes ¶
Bytes returns the accumulated payload. The returned slice aliases the Writer's internal storage, so callers that retain it must not mutate the Writer further.
func (*Writer) WriteBytes ¶
WriteBytes appends a length-prefixed byte slice (the binary form of #write_string).
func (*Writer) WriteRaw ¶
WriteRaw appends bytes with no length prefix (the :raw element type used when embedding an already-serialised attributes blob).
func (*Writer) WriteString ¶
WriteString appends a uint32 length prefix followed by the raw bytes (#write_string). The string is treated as binary, exactly as MRI does.
func (*Writer) WriteUint32 ¶
WriteUint32 appends a 32-bit network-byte-order integer (#write_long).
func (*Writer) WriteUint64 ¶
WriteUint64 appends a 64-bit network-byte-order integer (#write_int64). MRI splits the value into a (hi, lo) pair of 32-bit words; the result is identical to a single big-endian uint64.
