Upload files
Here you can find all the detailed information and API specification for uploading files to a transfer.
Files can be added to a transfer after it has been initialized with Initialize. It is also possible to add files to existing transfers after they are completed (after calling Complete). Follow these guidelines to send files effecitvley:
Use POST method.
Use
Content-Type: application/octet-stream
request header and send binary file data directly in the POST body. E.g. in .NET useByteArrayContent
together withPostAsync
method of aHttpClient
.Specify upload parameters in the request query string. Please note that the request body is reserved for file binary data.
File upload URL is returned in the
data.transferurl
field of the JSON response after calling Initialize. Expect a value similar tohttps://8888.filemail.com/savefile.ashx
.In case the server returns HTTP status
406
or449
during file upload - retry the request.If you are uploading lots of smaller files you will benefit from uploading a few files in parallel. Keep the number of parallel files on a reasonably low level (2 ... 4) in order to prevent bandwidth saturation.
Chunking
Key points around chunking:
Chunking allows to keep HTTP requests small and in turn makes retrying failed chunks easy. In case of a non-chunked upload a network failure at e.g. 90% of a 1GB file makes the retry-logic very inefficient.
Pick a chunk size in the range of 5...50MB and add the number of bytes as query string parameter e.g. for a 5MB chunk use
...&chunksize=5000000&...
. Note: this value should be constant for all chunks for a given file, even for the last chunk of a file (which is usually smaller than all the other chunks).Calculate total number of chunks as
Math.Ceiling(FileSize/ChunkSize)
and add it to every chunk request e.g....&chunks=13&...
Note: when uploading an empty (zero-byte) file - specify
chunks=1
.For every chunk specify
chunk
parameter - this is the 0-based chunk index.It is possible to upload multiple chunks in parallel - this may improve upload overall performance. We recommend to upload at most 4 chunks in parallel.
Query string parameters:
transferid
- Text - retrieved from Initialize ->data.transferid
transferkey
- Text - retrieved from Initialize->data.transferkey
thefilename
- Text - name of the file as it will appear in the transfer. Make sure this value is properly URL-encoded.chunksize
- Number - The expected number of bytes in every chunk. This value must be constant for all chunks of a given file - even for the last chunk. When a file contains 2 chunks, first chunk is 1MB and the second is 700kB - in the second chunk request specify the samechunksize
as in the firsrt one (i.e.chunksize=1000000
). Required when using chunking, otherwise optional.chunks
- Number - The total number of chunks in the file. When file size is 0 bytes this value should be set to 1. Required when using chunking, otherwise optional.chunk
- Number - Zero-based index of the current chunk being uploaded. Required when using chunking, otherwise optional.md5
- Text - Base64-encoded MD5 hash of bytes sent in current HTTP request. When using chunking calculate this value for every chunk. E.g.MmdYzU+gCb+g/PqavfGttA==
. If the calculated hash on our server is different, then HTTP Status 449 is returned - meaning that the chunk must be uploaded again. Optional.compressed
- Bool - Set to true if the data being sent is a compressed (zipped) stream. If this parameter is true our servers will unzip file contents on the fly before they are stored on our servers. Optional.retry
- Number - Zero-based index of the current retry attempt (if retries are in use). This value is used only for tracking/logging purposes. Optional.
Example Request (without body)
POST https://8888.filemail.com/savefile.ashx?
transferid=JIRPAXTDQMVAJZB&
transferkey=5812ea4388e24035abe5ba7cb06b3b47&
thefilename=big%20file.jpg&
chunksize=10000000&
chunks=13&
chunk=7&
retry=2
Host: 8888.filemail.com
Content-Type: application/octet-stream
Example Response
HTTP 200 OK (empty response body)
.NET code snippet - chunked upload
Below code illustrates how you can upload a single file with chunking, but without any parallelism. Here we use 5 MB chunks.
// WARNING: example code, not production-ready
public async Task UploadFile(string filePath)
{
/// ----- values obtained from /transfer/initialize
var transferid = "...";
var transferkey = "...";
var transferurl = "...";
/// -----
const int chunkSize = 5000000;
var chunk = -1;
var fi = new FileInfo(filePath);
var chunks = (int)Math.Ceiling((double)fi.Length / chunkSize);
var query = System.Web.HttpUtility.ParseQueryString(string.Empty);
query["transferid"] = transferid;
query["transferkey"] = transferkey;
query["thefilename"] = fi.Name;
query["chunks"] = chunks.ToString();
query["chunksize"] = chunkSize.ToString();
var buffer = new byte[chunkSize];
var httpClient = new HttpClient();
var uriBuilder = new UriBuilder(transferurl);
using (var fs = fi.OpenRead())
{
int read;
while ((read = await fs.ReadAsync(buffer, 0, buffer.Length)) > 0)
{
chunk += 1;
query["chunk"] = chunk.ToString();
uriBuilder.Query = query.ToString();
var request = new HttpRequestMessage(HttpMethod.Post, uriBuilder.ToString());
request.Content = new ByteArrayContent(buffer, 0, read);
request.Content.Headers.ContentType = new System.Net.Http.Headers.MediaTypeHeaderValue(System.Net.Mime.MediaTypeNames.Application.Octet);
var response = await httpClient.SendAsync(request);
// a single chunk is uploaded now
// TODO: do something with the chunk response
}
}
// entire file is uploaded now - move on to next file in the transfer
}
Last updated
Was this helpful?