Skip to content
Shiny.NET

HTTP Transfers

NuGet package Shiny.AppDeviceBridge.HttpTransfers

The HTTP transfers bridge queues background uploads and downloads to and from the file roots. Progress arrives as events, and completion reaches the page or background.js. It’s backed by Shiny.Net.Http.

Terminal window
dotnet add package Shiny.AppDeviceBridge.HttpTransfers
builder.UseAppDeviceBridge(
bridge => bridge.AddHttpTransfersBridge(),
webApp => { /* … */ }
);
Client C# TypeScript
ITransfersBridge AddTransfersBridgeClient() TransfersBridge
Topic Details
Queuing POST /_bridge/transfers with a type (Download, UploadMultipart or UploadRaw), a url, and a file as root plus path, the same names /_bridge/files uses. Uploads can add method, headers, formDataName and a small multipart body. Downloads can pass "overwrite": false.
Downloads land whole the file is written beside its destination under a hidden name and moved into place when it completes. The destination is checked again at that moment.
Limits http and https only. Loopback URLs are refused unless you change AllowUrl. Connection, length and proxy headers are refused. At most MaxTransfers (32) are queued at once.
Ownership the page only lists and cancels its own transfers. DELETE /_bridge/transfers leaves the native app’s transfers running.
Finishing in the background transfer.completed and transfer.failed reach the page, or background.js when no page is open. Progress is an event only, at most every ProgressInterval (250 ms) per transfer.
Platform setup Android needs FOREGROUND_SERVICE_DATA_SYNC. On iOS and Mac Catalyst, override HandleEventsForBackgroundUrl in the app delegate and pass it to Shiny.Hosting.Host.Lifecycle.OnHandleEventsForBackgroundUrl, or transfers that finish while the app is suspended wait for the next launch. macOS and Linux run transfers in-process only.

Transfers run in the operating system’s background transfer service, so they keep going with the app closed. Downloads land in a file root; uploads read from one.

import { TransfersBridge } from "@shinyorg/appdevicebridge";
const transfers = new TransfersBridge();
await transfers.onProgress(t => bar.value = t.percentComplete ?? 0);
await transfers.onCompleted(t => console.log("saved to", t.root, t.path));
await transfers.onFailed(t => console.warn(t.statusCode, t.error));
const t = await transfers.queue({
type: "Download",
url: "https://example.com/big.zip",
root: "data",
path: "downloads/big.zip",
overwrite: true
});
GET/_bridge/transfers#

The web app's transfers.

C#ITransfersBridge.GetTransfersAsyncTSTransfersBridge.getTransfers
Response
200 TransferList
TransferList · 1 field
transfersTransferInfo[]
POST/_bridge/transfers#

Queues a transfer. Fails with 403 for a URL the app does not allow, 404 for an unknown root or a missing upload file, 409 when a download's destination exists and overwrite is off, 429 when too many are queued.

C#ITransfersBridge.QueueAsyncTSTransfersBridge.queue
Body
application/json · TransferRequest
TransferRequest · 10 fields
typeTransferType
urlstringAn absolute http or https URL. Loopback is refused unless the app allows it.
rootstringThe file root a download goes into or an upload comes from.
pathstringThe file inside the root.
methodstring | nullGET, POST, PUT or PATCH; the transfer type's default when null.
headersRecord<string, string> | nullAt most 32. Hop-by-hop, content and proxy headers are refused.
useMeteredConnectionbooleanWhether the transfer may run on a metered network.
formDataNamestring | nullThe file's form field name for a multipart upload; file when null.
bodyTransferBody | nullAn extra form part, for a multipart upload only.
overwritebooleanWhether a download may replace an existing file.
Response
200 TransferInfo
TransferInfo · 13 fields
idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.
Errors
403Forbidden404Not found409Conflict429Too many
DELETE/_bridge/transfers#

Cancels every web app transfer, and none of the native app's.

C#ITransfersBridge.CancelAllAsyncTSTransfersBridge.cancelAll
Response
204 No content
GET/_bridge/transfers/{id}#

One transfer. Fails with 404 when there is no such transfer.

C#ITransfersBridge.GetTransferAsyncTSTransfersBridge.getTransfer
ParameterInType
idpathstringrequired
Response
200 TransferInfo
TransferInfo · 13 fields
idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.
Errors
404Not found
DELETE/_bridge/transfers/{id}#

Cancels a transfer.

C#ITransfersBridge.CancelAsyncTSTransfersBridge.cancel
ParameterInType
idpathstringrequired
Response
204 No content
POST/_bridge/transfers/{id}/pause#

Pauses a transfer.

C#ITransfersBridge.PauseAsyncTSTransfersBridge.pause
ParameterInType
idpathstringrequired
Response
204 No content
POST/_bridge/transfers/{id}/resume#

Resumes a paused transfer.

C#ITransfersBridge.ResumeAsyncTSTransfersBridge.resume
ParameterInType
idpathstringrequired
Response
204 No content
EVENTtransfer.progress#

A transfer moved on or changed state. Throttled per transfer; a state change always comes through.

C#ITransfersBridge.OnProgressAsyncTSTransfersBridge.onProgress
Payload
TransferInfo
idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.
EVENTtransfer.completed#

A transfer completed; a download is in place at its path.

C#ITransfersBridge.OnCompletedAsyncTSTransfersBridge.onCompleted
Payload
TransferInfo
idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.
EVENTtransfer.failed#

A transfer failed.

C#ITransfersBridge.OnFailedAsyncTSTransfersBridge.onFailed
Payload
TransferInfo
idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.
EVENTtransfer.cancelled#

A transfer was cancelled.

C#ITransfersBridge.OnCancelledAsyncTSTransfersBridge.onCancelled
Payload
TransferInfo
idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.

JSON property names are camelCase and enums travel as their names. A ? marks a property the payload may omit;| null one that may be null.

TransferInfoobject#

A transfer.

idstring
typeTransferType
urlstring
rootstring | nullThe file root, while the file is inside one.
pathstring | null
statusTransferState
bytesTransferrednumber
bytesToTransfernumber | null
bytesPerSecondnumber | null
percentCompletenumber | null0–1, when the size is known.
createdAtstring | null
statusCodenumber | nullThe server's status, for a failure that had one.
errorstring | nullWhy it failed.
TransferTypeenum#
"UploadMultipart""UploadRaw""Download"
TransferStateenum#
"Unknown""Pending""Paused""PausedByNoNetwork""PausedByCostedNetwork""InProgress""Error""Canceled""Completed"
TransferRequestobject#

A transfer to queue.

typeTransferType
urlstringAn absolute http or https URL. Loopback is refused unless the app allows it.
rootstringThe file root a download goes into or an upload comes from.
pathstringThe file inside the root.
method?string | nullGET, POST, PUT or PATCH; the transfer type's default when null.
headers?Record<string, string> | nullAt most 32. Hop-by-hop, content and proxy headers are refused.
useMeteredConnection?booleanWhether the transfer may run on a metered network.
formDataName?string | nullThe file's form field name for a multipart upload; file when null.
body?TransferBody | nullAn extra form part, for a multipart upload only.
overwrite?booleanWhether a download may replace an existing file.
TransferBodyobject#

An extra form part sent with a multipart upload.

contentstringAt most 1 MB.
contentType?string | nulltext/plain when null.
formDataName?string | null

These routes sit under AppDeviceBridgePolicies.Bridges like every other bridge: callers on this device by default. See Security.