Repository navigation
feat(vm): bind net-sftp — require "net/sftp" (Net::SFTP over injected SSH channel) - #203
Closed
tannevaled wants to merge 1 commit into
Closed
tannevaled wants to merge 1 commit into
tannevaled wants to merge 1 commit into
Conversation
… SSH channel) Bind the pure-Go SFTP wire codec github.com/go-ruby-net-sftp/net-sftp into rbgo as require "net/sftp", exposing the Ruby Net::SFTP surface. SFTP runs over an SSH channel. The library owns only the deterministic packet codec (framing, the version-aware ATTRS struct, request-id correlation, version negotiation); the encrypted SSH transport is the host's job — the "channel seam". rbgo has no go-ruby-ssh yet, so Net::SFTP.start / Session.new take an injected channel object responding to #write(bytes) / #read(n) (a duck-typed SSH channel, e.g. a StringIO), mirroring how Redis.new takes an injected IO connection. The binding drives the library's request builders and response parsers over that channel: it writes FXP_INIT, negotiates the version from FXP_VERSION, then for each operation writes the request frame and reads the id-correlated response. Surface: - Session: protocol_version/version, open!/close!/read!/write!, stat!/lstat!/ fstat!/setstat!/fsetstat!, opendir!/readdir!, remove!/mkdir!/rmdir!/realpath!, rename!/readlink!/symlink!/link!/block!/unblock!, upload!/download!, dir, file. - Operations::Dir#foreach/#entries; Operations::FileFactory#open/#directory?; Operations::File#read/#write/#pos/#close. - Value objects: Protocol::V01::Attributes (size/uid/gid/owner/group/permissions/ atime/mtime/type + directory?/file?/symlink?) and Name (name/filename/longname/ attributes + predicates), with v4+ longname synthesised on demand. - Net::SFTP::Exception < StandardError and Net::SFTP::StatusException carrying code/description/text/message; Net::SFTP::Constants StatusCodes/PacketTypes. Wired: providedFeatures["net/sftp"], vm.registerNetSFTP() after registerNetHTTP (nests under the existing Net module), and classOf cases for the six wrapper types. 100% coverage of the new files via a deterministic in-process channel (Chan) whose reply frames are built with the same wire codec — no SSH, network, or goroutine. gofmt/vet clean, -race clean, green on all six 64-bit arches. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Contributor
Author
|
Superseded by the net-wave consolidation PR (single merge onto main; shared builtins/require/object_model). Work preserved verbatim; branch kept. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Binds the pure-Go SFTP wire codec go-ruby-net-sftp/net-sftp into rbgo as
require "net/sftp", soNet::SFTPworks with no.rbfile.SFTP runs over an SSH channel. The library owns only the deterministic packet codec (framing, the version-aware
ATTRSstruct, request-id correlation, version negotiation); the encrypted SSH transport is the host's job — the channel seam. rbgo has nogo-ruby-sshyet, soNet::SFTP.start/Session.newtake an injected channel object responding to#write(bytes)/#read(n)(a duck-typed SSH channel, e.g. aStringIO), mirroring howRedis.newtakes an injected IO connection. The binding writesFXP_INIT, negotiates the version fromFXP_VERSION, then for each operation writes the request frame and reads the id-correlated response.Ruby surface
protocol_version/version,open!/close!/read!/write!,stat!/lstat!/fstat!/setstat!/fsetstat!,opendir!/readdir!,remove!/mkdir!/rmdir!/realpath!,rename!/readlink!/symlink!/link!/block!/unblock!,upload!/download!,dir,file.#foreach/#entries; Operations::FileFactory#open/#directory?; Operations::File#read/#write/#pos/#close.Protocol::V01::Attributes(size/uid/gid/owner/group/permissions/atime/mtime/type+directory?/file?/symlink?) andName(name/filename/longname/attributes+ predicates), with the v4+ longname synthesised on demand.Net::SFTP::Exception < StandardErrorandNet::SFTP::StatusExceptioncarryingcode/description/text/message;Net::SFTP::Constants(StatusCodes/PacketTypes).Wiring
providedFeatures["net/sftp"],vm.registerNetSFTP()afterregisterNetHTTP(nests under the existingNetmodule), andclassOfcases for the six wrapper types.Verification
go build ./...and 6-arch build (amd64/arm64/riscv64/loong64/ppc64le/s390x) — no FAIL.net_sftp.go,net_sftp_bind.go) via a deterministic in-process channel whose reply frames are built with the same wire codec — no SSH, network, or goroutine.internal/vmsuite green;gofmt -lclean;go vetclean;-raceclean.🤖 Generated with Claude Code