Documentation
¶
Overview ¶
Package supportupload is the appliance-side client for M6 "Optional secure upload" (docs/support/SECURE-UPLOAD-ARCHITECTURE.md §4): a resumable, SSRF-guarded, chunked, outbound-only HTTPS uploader to a TAC upload gateway.
It is a PURE ENGINE — it opens no connections on its own and is wired to no trigger. The caller supplies the (already E2E-encrypted) bundle bytes and the per-bundle identity; the client performs init → offset-idempotent chunk PUTs → complete, and returns the gateway's signed receipt. The queue/state machine and the per-bundle consent gate that decide WHETHER and WHEN to call it live in later slices; nothing here can cause egress until something invokes it.
Every outbound dial is SSRF-guarded at the network layer (ssrf.SafeDialContext checks the post-resolution address, closing the DNS-rebind window) and on every redirect hop (ssrf.PrivateHost) — a compromised or misconfigured origin cannot be pointed at internal infrastructure.
Index ¶
- type Client
- func (c *Client) Complete(ctx context.Context, uploadID, bundleSHA256 string) (Receipt, error)
- func (c *Client) Init(ctx context.Context, m Meta) (uploadID string, chunkSize int64, err error)
- func (c *Client) PutChunk(ctx context.Context, uploadID string, offset int64, chunk []byte) (receivedOffset int64, err error)
- func (c *Client) Status(ctx context.Context, uploadID string) (receivedOffset int64, err error)
- func (c *Client) Upload(ctx context.Context, m Meta, ra io.ReaderAt, size int64) (Receipt, error)
- type Config
- type GatewayError
- type Meta
- type Receipt
Constants ¶
This section is empty.
Variables ¶
This section is empty.
Functions ¶
This section is empty.
Types ¶
type Client ¶
type Client struct {
// contains filtered or unexported fields
}
Client is a resumable, SSRF-guarded upload client. Safe for sequential use by one uploader; the queue serializes per-bundle transfers.
func NewClient ¶
NewClient validates the origin (https + host) and builds an SSRF-guarded client: the transport dials only public resolved addresses (ssrf.SafeDialContext) and every redirect hop is re-checked. Inline url.Parse + scheme + host so the guard is visible at the construction boundary.
func (*Client) Complete ¶
Complete finalizes the upload. The gateway re-verifies bundleSHA256 against the bytes it received and returns the signed receipt; Complete ALSO re-checks the receipt's hash equals the expected bundleSHA256 so EVERY completion path — the Upload convenience wrapper and the queue's direct Init/Status/PutChunk/Complete resume path — rejects a corrupted or mis-issued receipt identically.
func (*Client) Init ¶
Init opens an upload session and returns its id + the gateway-chosen chunk size.
func (*Client) PutChunk ¶
func (c *Client) PutChunk(ctx context.Context, uploadID string, offset int64, chunk []byte) (receivedOffset int64, err error)
PutChunk uploads one chunk at the given offset. Idempotent per offset (a re-sent offset is a no-op on the gateway), so a retry after a drop is safe. Returns the gateway's new received offset.
func (*Client) Status ¶
Status returns the gateway's current received offset — the resume point after a dropped connection or a process restart.
func (*Client) Upload ¶
Upload runs the full resumable transfer of ra[0:size] and returns the signed receipt. It consults the gateway's received offset first, so re-invoking it on the same freshly-init'd session only sends missing chunks; cross-restart resume is driven by the queue via the exposed Init/Status/PutChunk/Complete methods. The receipt hash is re-checked against meta.BundleSHA256 (defense in depth over the gateway's own complete-time check).
type Config ¶
type Config struct {
Origin string // TAC upload base URL (https)
Credential string // per-appliance bearer credential (tenant-scoped)
Timeout time.Duration // per-request timeout (default 60s)
}
Config constructs a Client.
type GatewayError ¶
GatewayError is returned for a non-2xx gateway response, preserving the status so the caller (queue) can classify entitlement/format/hash rejections vs transient 5xx for retry decisions.
func (*GatewayError) Error ¶
func (e *GatewayError) Error() string
type Meta ¶
type Meta struct {
CaseID string `json:"case_id"`
BundleID string `json:"bundle_id"`
BundleSHA256 string `json:"bundle_sha256"`
Size int64 `json:"size"`
KeyID string `json:"key_id,omitempty"`
}
Meta is the per-bundle identity sent at init (SECURE-UPLOAD-ARCHITECTURE.md §4). BundleSHA256 is the hash of the bytes being uploaded (the encrypted bundle); the gateway re-verifies it at complete and echoes it in the receipt.