C# example for uploading a large document

using Newtonsoft.Json;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Net;
using System.Security.Cryptography.X509Certificates;
using System.Text;
using System.Threading.Tasks;

namespace UploadingLargeFilesInSB
{
    class Program
    {
        //Authentication Info.
        public static string BaseURI = "https://app.sharebase.com/sharebaseapi/";
        public static string Token = "";
        public static string ShareBaseEmailId = "user";
        public static string ShareBasePassword = "password";
        public static string Origin = "http://{your-computer-name-here}";

        //Upload information.
        private static int chunkSize = 1024 * 512; // This is the current chunk size in SB.

        private static readonly long folderId = 2;
        private static readonly string largeFileName = "LargeImage.jpg";
        private static readonly string largeFilePath = $"M:\\{largeFileName}";

        static void Main(string[] args)
        {
            //Authenticate for Sharebase User.
            Authenticate(ShareBaseEmailId, ShareBasePassword);

            UploadLargeDocuemnt();
        }

        public static void UploadLargeDocuemnt()
        {
            //Initialize large document upload.
            var uploadObject = InitializeLargeUpload();

            //Large document upload in chunks.
            LargeDocumentUpload(uploadObject);

            //Finalize large document upload.
            FinalizeLargeUpload(uploadObject);
        }

        private static UploadObject InitializeLargeUpload()
        {
            HttpWebRequest request = Program.RequestManager.GeneratePOSTRequest(Program.BaseURI + $"api/folders/{folderId}/temp?filename={largeFileName}", string.Empty, string.Empty, string.Empty, true);
            HttpWebResponse response = Program.RequestManager.GetResponse(request);
            var content = Program.RequestManager.GetResponseContent(response);
            return JsonConvert.DeserializeObject<UploadObject>(content);
        }

        private static UploadObject LargeDocumentUpload(UploadObject uploadObject)
        {
            var largeFileSize = new System.IO.FileInfo(largeFilePath).Length;
            var toBeReadFileSize = largeFileSize;

            var fileStream = new FileStream(largeFilePath, FileMode.Open, FileAccess.Read);
            byte[] toBeUploadedContent = GetNextNChucks(ref fileStream, ref toBeReadFileSize);

            uploadObject = UploadInChunks(uploadObject.Links.Location, toBeUploadedContent);
            while (uploadObject.CurrentSize < largeFileSize)
            {
                toBeUploadedContent = GetNextNChucks(ref fileStream, ref toBeReadFileSize);
                uploadObject = UploadInChunks(uploadObject.Links.Location, toBeUploadedContent);
            }

            fileStream.Close();
            return uploadObject;
        }

        private static void FinalizeLargeUpload(UploadObject obj)
        {
            HttpWebRequest request = Program.RequestManager.GeneratePOSTRequest(Program.BaseURI + $"api/folders/{folderId}/documents", string.Empty, string.Empty, string.Empty, true);
            request.Headers.Add("x-sharebase-fileref", JsonConvert.SerializeObject(obj));
            HttpWebResponse response = Program.RequestManager.GetResponse(request);
            var content = Program.RequestManager.GetResponseContent(response);

        }
        private static UploadObject UploadInChunks(string uri, byte[] contentChunk)
        {
            HttpWebRequest request = Program.RequestManager.GenerateRequest(uri, contentChunk, "PATCH", string.Empty, string.Empty, true);
            HttpWebResponse response = Program.RequestManager.GetResponse(request);
            var content = Program.RequestManager.GetResponseContent(response);
            return JsonConvert.DeserializeObject<UploadObject>(content);
        }
        private static byte[] GetNextNChucks(ref FileStream fileStream, ref long toBeReadFileSize)
        {
            if (toBeReadFileSize < chunkSize)
            {
                chunkSize = (int)toBeReadFileSize;
            }
            byte[] buffer = new byte[chunkSize];
            fileStream.Read(buffer, 0, buffer.Length);
            toBeReadFileSize = toBeReadFileSize - chunkSize;
            return buffer;
        }

        public static void Authenticate(string email, string password)
        {
            Token = "Basic " + System.Convert.ToBase64String(System.Text.Encoding.UTF8.GetBytes(email + ":" + password));
            HttpWebRequest request = RequestManager.GenerateGETRequest(BaseURI + "authenticate", string.Empty, string.Empty, true);

            request.KeepAlive = true;
            HttpWebResponse response = RequestManager.GetResponse(request);

            dynamic responseContent = RequestManager.GetJsonResponseContent(response);
            Token = RequestManager.GetValueFromJsonObject(responseContent, "Token");
            Token = "PHOENIX-TOKEN " + Token;
        }

        public static class RequestManager
        {

            public static HttpWebResponse SendPOSTRequest(string uri, string content, string login, string password, bool allowAutoRedirect)
            {
                HttpWebRequest request = GeneratePOSTRequest(uri, content, login, password, allowAutoRedirect);
                return GetResponse(request);
            }

            public static HttpWebResponse SendGETRequest(string uri, string login, string password, bool allowAutoRedirect)
            {
                HttpWebRequest request = GenerateGETRequest(uri, login, password, allowAutoRedirect);
                return GetResponse(request);
            }

            public static HttpWebResponse SendRequest(string uri, string content, string method, string login, string password, bool allowAutoRedirect)
            {
                HttpWebRequest request = GenerateRequest(uri, content, method, login, password, allowAutoRedirect);
                return GetResponse(request);
            }

            public static HttpWebRequest GenerateGETRequest(string uri, string login, string password, bool allowAutoRedirect)
            {
                return GenerateRequest(uri, string.Empty, "GET", null, null, allowAutoRedirect);
            }

            public static HttpWebRequest GeneratePOSTRequest(string uri, string content, string login, string password, bool allowAutoRedirect)
            {
                return GenerateRequest(uri, content, "POST", null, null, allowAutoRedirect);
            }
            public static HttpWebRequest GeneratePOSTRequest(string uri, byte[] content, string login, string password, bool allowAutoRedirect)
            {
                return GenerateRequest(uri, content, "POST", null, null, allowAutoRedirect);
            }

            internal static HttpWebRequest GenerateRequest(string uri, byte[] content, string method, string login, string password, bool allowAutoRedirect)
            {
                if (uri == null)
                {
                    throw new ArgumentNullException("uri");
                }
                HttpWebRequest request = (HttpWebRequest)HttpWebRequest.Create(uri);
                request.Method = method;

                request.AllowAutoRedirect = allowAutoRedirect;

                // If login is empty use defaul credentials
                if (string.IsNullOrEmpty(login))
                {
                    request.Credentials = CredentialCache.DefaultNetworkCredentials;
                }
                else
                {
                    request.Credentials = new NetworkCredential(login, password);
                }

                request.Headers.Add("Authorization", Token);
                request.Headers.Add("x-phoenix-app-id", "ShareBase");


                if (method == "POST" || method == "PATCH" || method == "PUT")
                {
                    request.Accept = "application/json";
                    request.ContentType = "application/json";

                    using (var streamWriter = request.GetRequestStream())
                    {
                        streamWriter.Write(content, 0, content.Length);
                    }

                    request.Headers.Add("Origin", Origin);

                }
                return request;
            }
            internal static HttpWebRequest GenerateRequest(string uri, string content, string method, string login, string password, bool allowAutoRedirect)
            {
                byte[] contentBytes = Encoding.UTF8.GetBytes(content);
                return GenerateRequest(uri, contentBytes, method, login, password, allowAutoRedirect);
            }

            internal static HttpWebResponse GetResponse(HttpWebRequest request)
            {
                if (request == null)
                {
                    throw new ArgumentNullException("request");
                }
                HttpWebResponse response = null;
                try
                {
                    response = (HttpWebResponse)request.GetResponse();

                }
                catch (WebException ex)
                {
                    Console.WriteLine("Web exception occurred. Status code: {0}", ex.Status);
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                return response;
            }

            public static string GetResponseContent(HttpWebResponse response)
            {
                if (response == null)
                {
                    throw new ArgumentNullException("response");
                }
                Stream dataStream = null;
                StreamReader reader = null;
                string responseFromServer = null;

                try
                {
                    // Get the stream containing content returned by the server.
                    dataStream = response.GetResponseStream();
                    // Open the stream using a StreamReader for easy access.
                    reader = new StreamReader(dataStream);
                    // Read the content.
                    responseFromServer = reader.ReadToEnd();
                    // Cleanup the streams and the response.
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
                finally
                {
                    if (reader != null)
                    {
                        reader.Close();
                    }
                    if (dataStream != null)
                    {
                        dataStream.Close();
                    }
                    response.Close();
                }
                return responseFromServer;
            }

            public static object GetJsonResponseContent(HttpWebResponse response)
            {
                string responseFromServer = GetResponseContent(response);
                return JsonConvert.DeserializeObject(responseFromServer);

            }

            public static string GetValueFromJsonObject(dynamic json, string propertyName)
            {
                string val = string.Empty;
                foreach (var ma in json)
                {
                    if (ma != null && ma.Name.ToString() == propertyName)
                    {
                        val = ma.Value.ToString();
                        break;
                    }
                }
                return val;
            }
        }
    }

    public class UploadObject
    {
        public class UploadLinks
        {
            public string Location { get; set; }
        }

        public UploadLinks Links { get; set; }
        public string Identifier { get; set; }
        public string FileName { get; set; }
        public long CurrentSize { get; set; }
        public long VolumeId { get; set; }
    }
}