Ejemplo n.º 1
0
        private void Initialize()
        {
            if (_file.Size.DefaultValue > MaxFileSize)
            {
                throw new OverflowException("Not supported file size.", new Exception($"The maximum file size is {MaxFileSize} byte. Currently file size is {_file.Size.DefaultValue} byte."));
            }

            var boundary = Guid.NewGuid();

            //// Boundary request building.
            var boundaryBuilder = new StringBuilder();

            boundaryBuilder.AppendFormat("------{0}\r\n", boundary);
            boundaryBuilder.AppendFormat("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\n", HttpUtility.UrlEncode(_file.Name));
            boundaryBuilder.AppendFormat("Content-Type: {0}\r\n\r\n", ConstSettings.GetContentType(_file.Extension));

            var endBoundaryBuilder = new StringBuilder();

            endBoundaryBuilder.AppendFormat("\r\n------{0}--\r\n", boundary);

            _endBoundaryRequest = Encoding.UTF8.GetBytes(endBoundaryBuilder.ToString());
            var boundaryRequest = Encoding.UTF8.GetBytes(boundaryBuilder.ToString());

            var url = new Uri($"{_shard.Url}?cloud_domain=2&{_account.LoginName}");

            _request                 = (HttpWebRequest)WebRequest.Create(url.OriginalString);
            _request.Proxy           = _account.Proxy;
            _request.CookieContainer = _account.Cookies;
            _request.Method          = "POST";

            _request.ContentLength = _file.Size.DefaultValue + boundaryRequest.LongLength + _endBoundaryRequest.LongLength;
            //_request.SendChunked = true;

            _request.Referer = $"{ConstSettings.CloudDomain}/home/{HttpUtility.UrlEncode(_file.Path)}";
            _request.Headers.Add("Origin", ConstSettings.CloudDomain);
            _request.Host        = url.Host;
            _request.ContentType = $"multipart/form-data; boundary=----{boundary}";
            _request.Accept      = "*/*";
            _request.UserAgent   = ConstSettings.UserAgent;
            _request.AllowWriteStreamBuffering = false;


            //_request.GetRequestStream();

            _task = Task.Factory.FromAsync(
                _request.BeginGetRequestStream,
                asyncResult =>
                _request.EndGetRequestStream(asyncResult),
                null);

            _task = _task.ContinueWith
                    (
                (t, m) =>
            {
                try
                {
                    var token = (CancellationToken)m;
                    var s     = t.Result;
                    WriteBytesInStream(boundaryRequest, s, token, boundaryRequest.Length);
                }
                catch (Exception)
                {
                    return((Stream)null);
                }
                return(t.Result);
            },
                _cancelToken.Token, TaskContinuationOptions.OnlyOnRanToCompletion);
        }
        /// <summary>
        /// Upload file on the server asynchronously, if not use async await will be use synchronously operation.
        /// </summary>
        /// <param name="file">File info.</param>
        /// <param name="destinationPath">Destination path on the server.</param>
        /// <returns>True or false result of the operation.</returns>
        public async Task <bool> UploadFileAsync(FileInfo file, string destinationPath)
        {
            var maxFileSize = 2L * 1024L * 1024L * 1024L;

            if (file.Length > maxFileSize)
            {
                throw new OverflowException("Not supported file size.", new Exception(string.Format("The maximum file size is {0} byte. Currently file size is {1} byte.", maxFileSize, file.Length)));
            }

            this.CheckAuth();
            var shard    = this.GetShardInfo(ShardType.Upload);
            var boundary = Guid.NewGuid();

            //// Boundary request building.
            var boundaryBuilder = new StringBuilder();

            boundaryBuilder.AppendFormat("------{0}\r\n", boundary);
            boundaryBuilder.AppendFormat("Content-Disposition: form-data; name=\"file\"; filename=\"{0}\"\r\n", file.Name);
            boundaryBuilder.AppendFormat("Content-Type: {0}\r\n\r\n", ConstSettings.GetContentType(file.Extension));

            var endBoundaryBuilder = new StringBuilder();

            endBoundaryBuilder.AppendFormat("\r\n------{0}--\r\n", boundary);

            var endBoundaryRequest = Encoding.UTF8.GetBytes(endBoundaryBuilder.ToString());
            var boundaryRequest    = Encoding.UTF8.GetBytes(boundaryBuilder.ToString());

            var url     = new Uri(string.Format("{0}?cloud_domain=2&{1}", shard.Url, this.Account.LoginName));
            var request = (HttpWebRequest)WebRequest.Create(url.OriginalString);

            request.Proxy           = this.Account.Proxy;
            request.CookieContainer = this.Account.Cookies;
            request.Method          = "POST";
            request.ContentLength   = file.Length + boundaryRequest.LongLength + endBoundaryRequest.LongLength;
            request.Referer         = string.Format("{0}/home{1}", ConstSettings.CloudDomain, destinationPath);
            request.Headers.Add("Origin", ConstSettings.CloudDomain);
            request.Host        = url.Host;
            request.ContentType = string.Format("multipart/form-data; boundary=----{0}", boundary.ToString());
            request.Accept      = "*/*";
            request.UserAgent   = ConstSettings.UserAgent;
            request.AllowWriteStreamBuffering = false;

            var task = Task.Factory.FromAsync(request.BeginGetRequestStream, asyncResult => request.EndGetRequestStream(asyncResult), (object)null);

            return(await task.ContinueWith((t) =>
            {
                try
                {
                    using (var s = t.Result)
                    {
                        this.WriteBytesInStream(boundaryRequest, s);
                        this.WriteBytesInStream(file, s, true);
                        this.WriteBytesInStream(endBoundaryRequest, s);

                        using (var response = (HttpWebResponse)request.GetResponse())
                        {
                            if (response.StatusCode == HttpStatusCode.OK)
                            {
                                var resp = ReadResponseAsText(response).Split(new char[] { ';' });
                                var hashResult = resp[0];
                                var sizeResult = long.Parse(resp[1].Replace("\r\n", string.Empty));

                                this.AddFileInCloud(new File()
                                {
                                    Name = file.Name,
                                    FulPath = destinationPath + file.Name,
                                    Hash = hashResult,
                                    Size = sizeResult
                                });
                            }
                            else
                            {
                                throw new Exception();
                            }
                        }
                    }

                    return true;
                }
                finally
                {
                    if (t.Result != null)
                    {
                        t.Result.Dispose();
                    }
                }
            }));
        }