Configuration
Clients
A FilesClient connects to one Files.com site with one set of credentials. FilesClient.Create(config) makes an
independent client. Its properties, such as client.Users or client.RemoteFiles, run operations with that
client, and the objects and lists they return keep using it. Make one client for each site or user you work
with; clients can be used at the same time.
Create copies the configuration, so later changes to config do not affect the client. Reuse the client because each client has its own connection pool.
new FilesClient(config) makes the default client, which static methods such as User.Find(id) use. Making
another replaces the default for later static calls, but an object keeps the client it came from. A client made
this way reads config as each operation starts, so changes you make apply to operations started afterward;
its connections keep the ConnectTimeout it was made with.
Closing a Client
Dispose a client when you no longer need it; await using or using does it for you. From then on, the client,
and the objects, lists and transfers it returned, throw ObjectDisposedException for any new operation. Disposing
cancels the operations the client is running, and closes its connections once the SDK has finished with what they
use: their requests, responses and temporary files, and a stream an operation owns, such as the one
UploadFileAsync(destinationPath, stream, ...) disposes. DisposeAsync completes when that is done and the
connections are closed; Dispose does the same without waiting. A list or enumerator that is not loading a page does
not delay closing.
DisposeAsync does not wait for the operations' own tasks: await each one for its outcome. A running operation
usually ends with OperationCanceledException, as when its token is cancelled, but one whose response had already
arrived can still succeed, and an upload whose final request had been sent may have completed the file. Its task can
complete after DisposeAsync does, for example while it turns the response it received into its result.
An operation reading or writing a stream you gave it waits for that stream's current read or write, which the
SDK never forces closed, so a stream that ignores cancellation also delays DisposeAsync. Do not await
DisposeAsync inside a progress handler of the client's own transfer, which waits for the handler; Dispose
returns at once there.
Disposing the default client leaves it as the default, so later static calls throw ObjectDisposedException
until you make a new one. Making a new default client does not dispose the previous one.
HTTP Transport
To send a client's requests through your own proxy, TLS settings, certificate checks or instrumentation, give it
an HttpTransport. The SDK still decides everything above the handlers, for API requests and file transfers
alike: the endpoint and credentials of each request, which redirects to follow and which headers go with them,
retries, timeouts and cancellation.
HttpTransport.FromHandlerFactory(() => new HttpClientHandler { ... })gives the client handlers to own. It calls your function whenever it needs a new handler, including when it replaces its handlers from time to time to pick up DNS changes, and disposes each handler when it is done with it, and every remaining one when the client is disposed. Return a new handler each time.HttpTransport.FromSharedHandler(handler)sends through a handler you own and share. Clients never change or dispose the shared handler. Dispose it after disposing every client that uses it.
The SDK follows redirects itself, so that credentials never go to another origin. It turns off redirects on the
handlers your factory returns, and refuses a shared HttpClientHandler or SocketsHttpHandler whose
AllowAutoRedirect is true. A handler of another kind must not follow redirects or retry requests itself: the SDK
sends a request that can change something, such as a DELETE or the one that completes an upload, once per attempt,
and again only where Files.com redirects it, and it cannot know that a handler sent one again.
Configuration Options
Base URL
Set this to the full https:// URL of your Files.com subdomain (e.g. https://MY-SUBDOMAIN.files.com).
This is not required in most cases, but one benefit of setting it is that it ensures that authentication failures will be logged to your site's API logs. Without setting this, we won't know which site to associate the authentication failure with, and it won't be logged to your site's API logs.
This is always required if your site is configured to disable global acceleration.
This can also be set to use a mock server in development or CI.
Connect Timeout
How long, in seconds, to wait to connect to a server. The default value is 30.
On .NET 8 and later the client applies it to the handlers it makes itself, and to a SocketsHttpHandler from an
HttpTransport factory whose own ConnectTimeout is not set. A connection that it ends was never made, so nothing
was sent, and the request is retried, within Maximum Network Retries, even when it can change something.
It is not applied to any other handler: a shared handler, whose settings the SDK never changes, or a factory's handler
of another type or whose own ConnectTimeout is already set. Such a handler connects as it is configured, with its
own connection settings in effect. On .NET Framework, or any other runtime that uses the SDK's .NET Standard 2.0
build, the handlers the client makes itself have no separate connect timeout.
Whatever the handler, connecting also counts toward the wait that follows it: the Read Timeout for an API request or
a download, and the Write Timeout for an upload part or a request with file attachments. Whichever limit runs out
first ends the attempt. When that wait runs out before a connection is made, as it does where no shorter connect
timeout applies, the request fails with NetworkTimeoutException for that timeout, and a request that can change
something is not sent again after it, since the SDK cannot tell that nothing was sent.
None of the timeouts limits how long a whole request, transfer or connection takes: each limits one wait on the network.
Read Timeout
How long, in seconds, a request may wait for its response once it has been sent, and then between the parts of the response as they arrive. The default value is 80.
It limits a stalled connection, not how long a response takes: a download that keeps receiving data continues
however long it lasts. A request that times out fails with NetworkTimeoutException, after the retries a
connection failure gets. An error response whose body stops arriving fails with its HTTP status, as an
InvalidResponseException, and is retried as that status is.
Write Timeout
How long, in seconds, an upload part may go without sending any data: to connect and start, and then each time it sends more. The default value is 80.
It limits a stalled connection, not how long an upload takes, and time spent reading your file or stream is not counted. A part that times out is retried like one whose connection failed.
Maximum Network Retries
MaxNetworkRetries limits the SDK's retries after temporary failures. The default is 3; 0 disables
SDK retries. Eligible failures are connection failures, timeouts, HTTP 408, HTTP 429, and 5xx other than 501.
Each SDK retry is logged with its reason, number and wait.
| Request | When the SDK retries |
|---|---|
Reads, such as GET | After an eligible temporary failure. |
| Requests that can change data, such as creating a user | Only when the request certainly did not take effect: nothing was sent, or a trusted regional-relocation response allows it to move. |
| Transfer requests explicitly safe to repeat | Like reads: for example, obtaining an upload part's address or creating a folder that may already exist. |
| Upload completion | Never automatically retried. Check the remote file if completion is uncertain. |
For a potentially mutating request, a lost answer, timeout or error response can occur after the change took
effect. The SDK does not replay it, even with retries left. Its exception has RequestMayHaveBeenProcessed set:
check the outcome before sending the request again. No error status or body, including a rate-limit response,
proves that the change did not begin.
A false flag alone does not guarantee safe replay. For example, an InvalidResponseException with httpStatus = 0
can mean a successful response was unusable by CreateAsync: the change took effect, and no error response is attached.
Transfer parts have their own retry rules. New file downloads can retry into staging; downloads into your stream, and earlier whole-file download methods, cannot retry after writing bytes. See Transfers.
HTTP Handler and Redirect Caveats
This setting counts SDK retries, not every network send. Within an attempt, .NET's handler can resend a read after
a connection closes without an answer; even 0 does not guarantee a single send. The SDK gives mutating requests
content, including an empty body for a DELETE, to prevent the handler's automatic replay of bodyless requests.
SDK-managed redirects are still followed within an attempt: 307 and 308 resend the method and body to the new
address. This is routing, and neither redirects nor retry settings guarantee exactly-once processing. A custom
HttpTransport handler must not perform its own retries or follow redirects, since the SDK could not track them
or reliably report whether a change may have taken effect.
Certificate failures, refused redirects and failures of caller-owned streams are not retried.
Initial Network Retry Delay
The wait, in seconds, before the first retry of a Files.com API request. Each later retry waits twice as long as the one before, up to the Maximum Retry Delay. The default value is 0.1, so the default retries wait 0.1, 0.2 and 0.4 seconds.
File-transfer retry behavior is described in Transfers.
Maximum Retry Delay
The longest wait, in seconds, before a retry of a Files.com API request. The default value is 2.
Regional Relocation
When a site is served from another region's address, Files.com answers a request sent elsewhere with
LockoutRegionMismatchException and the site's address, its domain or its URL. With the default,
RegionRelocationPolicy.Automatic, the client then sends the request again to that address, with the same
credentials and body, when:
- the answer came from the address the request was sent to, over HTTPS whose certificate the client's handler
checked as strictly as .NET does by default, against the system's trusted roots or a custom trust store, at every
request since the handler's first (as the client saw its settings when each request started and when its answer
arrived), and not after a redirect to another origin. The handler is the client's own or
one from
HttpTransport.FromHandlerFactory: a client cannot see how a shared handler checked the servers it connected to before, or for other code; - the address is an HTTPS origin on port 443 with a public DNS name, such as the site's own domain, and not the one already used;
- the operation has not moved already and has a retry left: moving is one of its Maximum Network Retries, so with 0 the error is thrown instead.
The operation sends its remaining requests there, and so do the objects and lists it returns, for their own operations and next pages. The client's configuration is unchanged, and other operations start at the Base URL.
RegionRelocationPolicy.Disabled never moves: the error is thrown for your application to act on, such as by changing
its Base URL. RegionRelocationPolicy.OnlyBetween(from, to), with more pairs added by OrBetween, moves only from the
first origin of a pair you list to its second; a pair moves one way, so list the way back as another pair. The origins
may use another port, a local name or plain HTTP, as a development site may need, or answer through a handler whose
certificate checks the client cannot see or that relaxes them, such as a shared handler, a
RemoteCertificateValidationCallback of your own, or a CertificateChainPolicy with
AllowUnknownCertificateAuthority, even one tightened after the handler's first request.
When the operation does not move, the exception's RequestedOrigin is the address Files.com named, and Refusal says
why, such as RegionRelocationRefusal.Disabled or RetriesExhausted. For UntrustedIssuer, the message says which
condition the answer failed, and names the pair that would allow the move only when a pair can.
Logging
Set LoggerFactory to your application's ILoggerFactory to receive SDK messages under categories named for SDK classes in the FilesCom namespace. Each client uses its own factory, so clients in one process can use different log destinations without global configuration. A client without a factory uses log4net, as described in Logs.
MinimumLogLevel filters out a client's messages below that level, even if its logger enables them. Setting LogLevel.Warning excludes that client's Information messages. Each client retains the logger factory and minimum level set when it was created.
Product Identity
ProductName and ProductVersion name the application or module using the SDK. A client sends them as the first
product of its User-Agent header, before the SDK's own, Files.com DOTNET SDK and its version, which it always
sends. Each must be an HTTP token, without spaces; a client with any other value is refused as it is made, with
ArgumentException. A client keeps the values it was made with.