Example #1
0
        public DriveFile InsertEntry(Stream fileStream, string title, string parentId, bool folder = false)
        {
            var mimeType = folder ? GoogleLoginProvider.GoogleDriveMimeTypeFolder : MimeMapping.GetMimeMapping(title);

            var body = FileConstructor(title, mimeType, parentId);

            if (folder)
            {
                var requestFolder = _driveService.Files.Create(body);
                requestFolder.Fields = GoogleLoginProvider.FilesFields;
                return(requestFolder.Execute());
            }

            var request = _driveService.Files.Create(body, fileStream, mimeType);

            request.Fields = GoogleLoginProvider.FilesFields;

            var result = request.Upload();

            if (result.Exception != null)
            {
                if (request.ResponseBody == null)
                {
                    throw result.Exception;
                }
                Log.Error("Error while trying to insert entity. GoogleDrive insert returned an error.", result.Exception);
            }
            return(request.ResponseBody);
        }
Example #2
0
        private static string GetCorrectExt(JToken jsonFile)
        {
            var mimeType = (jsonFile.Value <string>("mimeType") ?? "").ToLower();

            var ext = MimeMapping.GetExtention(mimeType);

            if (!GoogleLoginProvider.GoogleDriveExt.Contains(ext))
            {
                var title = (jsonFile.Value <string>("name") ?? "").ToLower();
                ext = FileUtility.GetFileExtension(title);

                if (MimeMapping.GetMimeMapping(ext) != mimeType)
                {
                    var originalFilename = (jsonFile.Value <string>("originalFilename") ?? "").ToLower();
                    ext = FileUtility.GetFileExtension(originalFilename);

                    if (MimeMapping.GetMimeMapping(ext) != mimeType)
                    {
                        ext = MimeMapping.GetExtention(mimeType);

                        Global.Logger.Debug("GoogleDriveApp: Try GetCorrectExt - " + ext + " for - " + mimeType);
                    }
                }
            }
            return(ext);
        }
Example #3
0
        private static string GetCorrectExt(JObject jsonFile)
        {
            string ext;
            var    mimeType = (jsonFile.Value <string>("mimeType") ?? "").ToLower();

            FileType fileType;

            if (GoogleMimeTypes.TryGetValue(mimeType, out fileType))
            {
                ext = FileUtility.InternalExtension[fileType];
            }
            else
            {
                var title = (jsonFile.Value <string>("title") ?? "").ToLower();
                ext = FileUtility.GetFileExtension(title);

                if (MimeMapping.GetMimeMapping(ext) != mimeType)
                {
                    var originalFilename = (jsonFile.Value <string>("originalFilename") ?? "").ToLower();
                    ext = FileUtility.GetFileExtension(originalFilename);

                    if (MimeMapping.GetMimeMapping(ext) != mimeType)
                    {
                        ext = MimeMapping.GetExtention(mimeType);

                        Global.Logger.Debug("GoogleDriveApp: Try GetCorrectExt - " + ext + " for - " + mimeType);
                    }
                }
            }
            return(ext);
        }
Example #4
0
        public Uri Save(string domain, string path, Stream stream, string contentType,
                        string contentDisposition, ACL acl, string contentEncoding = null, int cacheDays = 5)
        {
            var buffered = stream.GetBuffered();

            if (QuotaController != null)
            {
                QuotaController.QuotaUsedCheck(buffered.Length);
            }

            using (var client = GetClient())
                using (var uploader = new TransferUtility(client))
                {
                    var mime = string.IsNullOrEmpty(contentType)
                                  ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                  : contentType;

                    var request = new TransferUtilityUploadRequest
                    {
                        BucketName  = _bucket,
                        Key         = MakePath(domain, path),
                        CannedACL   = acl == ACL.Auto ? GetDomainACL(domain) : GetS3Acl(acl),
                        ContentType = mime,
                        ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256,
                        InputStream     = buffered,
                        AutoCloseStream = false,
                        Headers         =
                        {
                            CacheControl = string.Format("public, maxage={0}", (int)TimeSpan.FromDays(cacheDays).TotalSeconds),
                            Expires      = DateTime.UtcNow.Add(TimeSpan.FromDays(cacheDays))
                        }
                    };


                    if (!string.IsNullOrEmpty(contentDisposition))
                    {
                        request.Headers.ContentDisposition = contentDisposition;
                    }
                    else if (mime == "application/octet-stream")
                    {
                        request.Headers.ContentDisposition = "attachment";
                    }

                    if (!string.IsNullOrEmpty(contentEncoding))
                    {
                        request.Headers.ContentEncoding = contentEncoding;
                    }

                    uploader.Upload(request);

                    InvalidateCloudFront(MakePath(domain, path));

                    QuotaUsedAdd(domain, buffered.Length);

                    return(GetUri(domain, path));
                }
        }
Example #5
0
        private string ReplaceUris(Match match, string serverpath, HttpContext context)
        {
            if (match.Success)
            {
                if (match.Groups[1].Success)
                {
                    string path = match.Groups[1].Value.Trim('\'', '"');
                    if (Uri.IsWellFormedUriString(path, UriKind.Relative))
                    {
                        path = PathCombine(serverpath, path);

                        if (ClientSettings.IsResourceStoreEnabled)
                        {
                            var rootpath     = context.Server.MapPath("~/").ToLower();
                            var physicalPath = context.Server.MapPath(path).ToLower();

                            physicalPath = physicalPath.Remove(0, rootpath.Length);
                            physicalPath = physicalPath.Replace("\\", "/");
                            path         = WebPath.GetPath(physicalPath);
                        }
                    }

                    if (ClientSettings.IsImageEmbeddingEnabled)
                    {
                        string base64Encoded;
                        if (!_embeddedImageCache.TryGetValue(path, out base64Encoded))
                        {
                            //Try add
                            string filePath = context.Server.MapPath(path);
                            if (File.Exists(filePath))
                            {
                                var info = new FileInfo(filePath);
                                if (info.Length < _maxEmbeddableSize)
                                {
                                    //Embed!!!!
                                    byte[] data = File.ReadAllBytes(filePath);
                                    base64Encoded = string.Format("data:{0};base64,{1}",
                                                                  MimeMapping.GetMimeMapping(filePath),
                                                                  Convert.ToBase64String(data));
                                }
                                else
                                {
                                    base64Encoded = string.Format("\"{0}\"", path);//Just path
                                }
                                _embeddedImageCache[path] = base64Encoded;
                            }
                        }
                        return(match.Value.Replace(match.Groups[1].Value, base64Encoded));
                    }


                    //If embedding is disabled just return path
                    return(match.Value.Replace(match.Groups[1].Value, string.Format("{0}", path)));
                }
            }
            return(match.Value);
        }
        public DriveFile SaveStream(string fileId, Stream fileStream, string fileTitle)
        {
            var mimeType = MimeMapping.GetMimeMapping(fileTitle);
            var file     = FileConstructor(fileTitle, mimeType);

            var request = _driveService.Files.Update(file, fileId, fileStream, mimeType);

            request.Fields = GoogleLoginProvider.FilesField;
            request.Upload();

            return(request.ResponseBody);
        }
Example #7
0
        public override Uri UploadWithoutQuota(string domain, string path, Stream stream, string contentType, string contentDisposition)
        {
            ACL acl = ACL.Auto;

            using (AmazonS3 client = GetClient())
            {
                var util = new Amazon.S3.Transfer.TransferUtility(client);

                var request = new Amazon.S3.Transfer.TransferUtilityUploadRequest();

                string mime = string.IsNullOrEmpty(contentType)
                                  ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                  : contentType;

                const int uploadTimeout = 10 * 60 * 1000;

                request.BucketName  = _bucket;
                request.Key         = MakePath(domain, path);
                request.CannedACL   = acl == ACL.Auto ? GetDomainACL(domain) : GetS3Acl(acl);
                request.ContentType = mime;
                request.Timeout     = uploadTimeout;

                var headers = new NameValueCollection();
                headers.Add("Cache-Control", string.Format("public, maxage={0}", (int)TimeSpan.FromDays(5).TotalSeconds));
                headers.Add("Etag", (DateTime.UtcNow.Ticks).ToString(CultureInfo.InvariantCulture));
                headers.Add("Last-Modified", DateTime.UtcNow.ToString("R"));
                headers.Add("Expires", DateTime.UtcNow.Add(TimeSpan.FromDays(5)).ToString("R"));
                if (!string.IsNullOrEmpty(contentDisposition))
                {
                    headers.Add("Content-Disposition", Uri.EscapeDataString(contentDisposition));
                }
                else if (mime == "application/octet-stream")
                {
                    headers.Add("Content-Disposition", "attachment");
                }

                request.AddHeaders(headers);

                //Send body
                var buffered = stream.GetBuffered();

                request.AutoCloseStream = false;

                request.InputStream = buffered;

                util.Upload(request);

                InvalidateCloudFront(MakePath(domain, path));

                return(GetUri(domain, path));
            }
        }
        public Uri Save(string domain, string path, Stream stream, string contentType,
                        string contentDisposition, ACL acl, string contentEncoding = null, int cacheDays = 5)
        {
            var buffered = TempStream.GetBuffered(stream);

            if (QuotaController != null)
            {
                QuotaController.QuotaUsedCheck(buffered.Length);
            }

            var mime = string.IsNullOrEmpty(contentType)
                        ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                        : contentType;

            using var storage = GetStorage();

            var uploadObjectOptions = new UploadObjectOptions
            {
                PredefinedAcl = acl == ACL.Auto ? GetDomainACL(domain) : GetGoogleCloudAcl(acl)
            };

            buffered.Position = 0;

            var uploaded = storage.UploadObject(_bucket, MakePath(domain, path), mime, buffered, uploadObjectOptions, null);

            uploaded.ContentEncoding = contentEncoding;
            uploaded.CacheControl    = string.Format("public, maxage={0}", (int)TimeSpan.FromDays(cacheDays).TotalSeconds);

            if (uploaded.Metadata == null)
            {
                uploaded.Metadata = new Dictionary <string, string>();
            }

            uploaded.Metadata["Expires"] = DateTime.UtcNow.Add(TimeSpan.FromDays(cacheDays)).ToString("R");

            if (!string.IsNullOrEmpty(contentDisposition))
            {
                uploaded.ContentDisposition = contentDisposition;
            }
            else if (mime == "application/octet-stream")
            {
                uploaded.ContentDisposition = "attachment";
            }

            storage.UpdateObject(uploaded);

            //           InvalidateCloudFront(MakePath(domain, path));

            QuotaUsedAdd(domain, buffered.Length);

            return(GetUri(domain, path));
        }
Example #9
0
        public ResumableUploadSession CreateResumableSession(DriveFile driveFile, long contentLength)
        {
            if (driveFile == null)
            {
                throw new ArgumentNullException("driveFile");
            }

            var fileId   = string.Empty;
            var method   = "POST";
            var body     = string.Empty;
            var folderId = driveFile.Parents.FirstOrDefault();

            if (driveFile.Id != null)
            {
                fileId = "/" + driveFile.Id;
                method = "PATCH";
            }
            else
            {
                var titleData  = !string.IsNullOrEmpty(driveFile.Name) ? string.Format("\"name\":\"{0}\"", driveFile.Name) : "";
                var parentData = !string.IsNullOrEmpty(folderId) ? string.Format(",\"parents\":[\"{0}\"]", folderId) : "";

                body = !string.IsNullOrEmpty(titleData + parentData) ? string.Format("{{{0}{1}}}", titleData, parentData) : "";
            }

            var request = WebRequest.Create(GoogleLoginProvider.GoogleUrlFileUpload + fileId + "?uploadType=resumable");

            request.Method = method;

            var bytes = Encoding.UTF8.GetBytes(body);

            request.ContentLength = bytes.Length;
            request.ContentType   = "application/json; charset=UTF-8";
            request.Headers.Add("X-Upload-Content-Type", MimeMapping.GetMimeMapping(driveFile.Name));
            request.Headers.Add("X-Upload-Content-Length", contentLength.ToString(CultureInfo.InvariantCulture));
            request.Headers.Add("Authorization", "Bearer " + AccessToken);

            request.GetRequestStream().Write(bytes, 0, bytes.Length);

            var uploadSession = new ResumableUploadSession(driveFile.Id, folderId, contentLength);

            using (var response = request.GetResponse())
            {
                uploadSession.Location = response.Headers["Location"];
            }
            uploadSession.Status = ResumableUploadSessionStatus.Started;

            return(uploadSession);
        }
Example #10
0
        public Stream DownloadStream(DriveFile file, int offset = 0)
        {
            if (file == null)
            {
                throw new ArgumentNullException("file");
            }

            var downloadArg = string.Format("{0}?alt=media", file.Id);

            var ext = MimeMapping.GetExtention(file.MimeType);

            if (GoogleLoginProvider.GoogleDriveExt.Contains(ext))
            {
                var internalExt      = FileUtility.GetGoogleDownloadableExtension(ext);
                var requiredMimeType = MimeMapping.GetMimeMapping(internalExt);

                downloadArg = string.Format("{0}/export?mimeType={1}",
                                            file.Id,
                                            HttpUtility.UrlEncode(requiredMimeType));
            }

            var request = WebRequest.Create(GoogleLoginProvider.GoogleUrlFile + downloadArg);

            request.Method = "GET";
            request.Headers.Add("Authorization", "Bearer " + AccessToken);

            var response = (HttpWebResponse)request.GetResponse();

            if (offset == 0 && file.Size.HasValue && file.Size > 0)
            {
                return(new ResponseStream(response.GetResponseStream(), file.Size.Value));
            }

            var tempBuffer = new FileStream(Path.GetTempFileName(), FileMode.OpenOrCreate, FileAccess.ReadWrite, FileShare.Read, 8096, FileOptions.DeleteOnClose);

            using (var str = response.GetResponseStream())
            {
                if (str != null)
                {
                    str.CopyTo(tempBuffer);
                    tempBuffer.Flush();
                    tempBuffer.Seek(offset, SeekOrigin.Begin);
                }
            }

            return(tempBuffer);
        }
Example #11
0
        public override Uri UploadWithoutQuota(string domain, string path, Stream stream, string contentType, string contentDisposition)
        {
            var acl = ACL.Auto;

            using (var client = GetClient())
            {
                var util = new TransferUtility(client);
                var mime = string.IsNullOrEmpty(contentType)
                                  ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                  : contentType;

                var buffered = stream.GetBuffered();
                var request  = new TransferUtilityUploadRequest
                {
                    BucketName      = _bucket,
                    Key             = MakePath(domain, path),
                    CannedACL       = acl == ACL.Auto ? GetDomainACL(domain) : GetS3Acl(acl),
                    ContentType     = mime,
                    InputStream     = buffered,
                    AutoCloseStream = false,
                    Headers         =
                    {
                        CacheControl = string.Format("public, maxage={0}",            (int)TimeSpan.FromDays(5).TotalSeconds),
                        ContentMD5   = Hasher.Base64Hash(buffered.GetCorrectBuffer(), HashAlg.MD5),
                        Expires      = DateTime.UtcNow.Add(TimeSpan.FromDays(5))
                    }
                };

                if (!string.IsNullOrEmpty(contentDisposition))
                {
                    request.Headers.ContentDisposition = Uri.EscapeDataString(contentDisposition);
                }
                else if (mime == "application/octet-stream")
                {
                    request.Headers.ContentDisposition = "attachment";
                }

                util.Upload(request);

                InvalidateCloudFront(MakePath(domain, path));

                return(GetUri(domain, path));
            }
        }
Example #12
0
        public DriveFile SaveStream(string fileId, Stream fileStream, string fileTitle)
        {
            var mimeType = MimeMapping.GetMimeMapping(fileTitle);
            var file     = FileConstructor(fileTitle, mimeType);

            var request = _driveService.Files.Update(file, fileId, fileStream, mimeType);

            request.Fields = GoogleLoginProvider.FilesFields;
            var result = request.Upload();

            if (result.Exception != null)
            {
                if (request.ResponseBody == null)
                {
                    throw result.Exception;
                }
                Log.Error("Error while trying to insert entity. GoogleDrive save returned an error.", result.Exception);
            }

            return(request.ResponseBody);
        }
 public FileToUpload(HttpContext context)
 {
     if (IsHtml5Upload(context))
     {
         FileName        = GetFileName(context);
         InputStream     = context.Request.InputStream;
         FileContentType = GetFileContentType(context);
         ContentLength   = (int)context.Request.InputStream.Length;
     }
     else
     {
         var file = context.Request.Files[0];
         FileName        = file.FileName;
         InputStream     = file.InputStream;
         FileContentType = file.ContentType;
         ContentLength   = file.ContentLength;
     }
     if (string.IsNullOrEmpty(FileContentType))
     {
         FileContentType = MimeMapping.GetMimeMapping(FileName) ?? string.Empty;
     }
     FileName = FileName.Replace("'", "_").Replace("\"", "_");
 }
Example #14
0
        public Uri Save(string domain, string path, Stream stream, string contentType,
                        string contentDisposition, ACL acl, string contentEncoding = null, int cacheDays = 5)
        {
            bool postWriteCheck = false;

            if (QuotaController != null)
            {
                try
                {
                    QuotaController.QuotaUsedAdd(_modulename, domain, _dataList.GetData(domain), stream.Length);
                }
                catch (TenantQuotaException)
                {
                    //this exception occurs only if tenant has no free space
                    //or if file size larger than allowed by quota
                    //so we can exit this function without stream buffering etc
                    throw;
                }
                catch (Exception)
                {
                    postWriteCheck = true;
                }
            }


            using (AmazonS3 client = GetClient())
            {
                var    request = new PutObjectRequest();
                string mime    = string.IsNullOrEmpty(contentType)
                                  ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                  : contentType;

                request.BucketName  = _bucket;
                request.Key         = MakePath(domain, path);
                request.CannedACL   = acl == ACL.Auto ? GetDomainACL(domain) : GetS3Acl(acl);
                request.ContentType = mime;

                request.ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256;

                var requestHeaders = new NameValueCollection();
                requestHeaders.Add("Cache-Control", string.Format("public, maxage={0}", (int)TimeSpan.FromDays(cacheDays).TotalSeconds));
                requestHeaders.Add("Etag", (DateTime.UtcNow.Ticks).ToString(CultureInfo.InvariantCulture));
                requestHeaders.Add("Last-Modified", DateTime.UtcNow.ToString("R"));
                requestHeaders.Add("Expires", DateTime.UtcNow.Add(TimeSpan.FromDays(cacheDays)).ToString("R"));

                if (!string.IsNullOrEmpty(contentDisposition))
                {
                    requestHeaders.Add("Content-Disposition", contentDisposition);
                }
                else if (mime == "application/octet-stream")
                {
                    requestHeaders.Add("Content-Disposition", "attachment");
                }

                if (!string.IsNullOrEmpty(contentEncoding))
                {
                    requestHeaders.Add("Content-Encoding", contentEncoding);
                }

                request.AddHeaders(requestHeaders);

                //Send body
                var buffered = stream.GetBuffered();
                if (postWriteCheck)
                {
                    QuotaController.QuotaUsedAdd(_modulename, domain, _dataList.GetData(domain), buffered.Length);
                }
                request.AutoCloseStream = false;

                request.InputStream = buffered;

                PutObjectResponse response            = client.PutObject(request);
                var destinationObjectEncryptionStatus = response.ServerSideEncryptionMethod;

                //..ServerSideEncryptionMethod;

                InvalidateCloudFront(MakePath(domain, path));

                return(GetUri(domain, path));
            }
        }
Example #15
0
        public Uri Save(string domain, string path, Stream stream, string contentType,
                        string contentDisposition, ACL acl, string contentEncoding = null, int cacheDays = 5,
                        DateTime?deleteAt = null, long?deleteAfter = null)
        {
            var buffered = stream.GetBuffered();

            if (QuotaController != null)
            {
                QuotaController.QuotaUsedCheck(buffered.Length);
            }

            var client = GetClient();

            var mime = string.IsNullOrEmpty(contentType)
                                 ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                 : contentType;

            if (mime == "application/octet-stream")
            {
                contentDisposition = "attachment";
            }

            var customHeaders = new Dictionary <string, string>();

            if (cacheDays > 0)
            {
                customHeaders.Add("Cache-Control", string.Format("public, maxage={0}", (int)TimeSpan.FromDays(cacheDays).TotalSeconds));
                customHeaders.Add("Expires", DateTime.UtcNow.Add(TimeSpan.FromDays(cacheDays)).ToString());
            }

            if (deleteAt.HasValue)
            {
                var ts            = deleteAt.Value - new DateTime(1970, 1, 1, 0, 0, 0);
                var unixTimestamp = (long)ts.TotalSeconds;

                customHeaders.Add("X-Delete-At", unixTimestamp.ToString());
            }

            if (deleteAfter.HasValue)
            {
                customHeaders.Add("X-Delete-After", deleteAfter.ToString());
            }


            if (!string.IsNullOrEmpty(contentEncoding))
            {
                customHeaders.Add("Content-Encoding", contentEncoding);
            }

            var cannedACL = acl == ACL.Auto ? GetDomainACL(domain) : ACL.Read;

            if (cannedACL == ACL.Read)
            {
                try
                {
                    using (var emptyStream = TempStream.Create())
                    {
                        var headers = new Dictionary <string, string>
                        {
                            { "X-Object-Manifest", string.Format("{0}/{1}", _private_container, MakePath(domain, path)) }
                        };
                        // create symlink
                        client.CreateObject(_public_container,
                                            emptyStream,
                                            MakePath(domain, path),
                                            mime,
                                            4096,
                                            headers,
                                            _region
                                            );

                        emptyStream.Close();
                    }

                    client.PurgeObjectFromCDN(_public_container, MakePath(domain, path));
                }
                catch (Exception exp)
                {
                    _logger.InfoFormat("The invalidation {0} failed", _public_container + "/" + MakePath(domain, path));
                    _logger.Error(exp);
                }
            }
            stream.Position = 0;

            client.CreateObject(_private_container,
                                stream,
                                MakePath(domain, path),
                                mime,
                                4096,
                                customHeaders,
                                _region
                                );

            QuotaUsedAdd(domain, buffered.Length);

            return(GetUri(domain, path));
        }
Example #16
0
        public Uri Save(string domain, string path, Stream stream, string contentType,
                        string contentDisposition, ACL acl, string contentEncoding = null, int cacheDays = 5, DateTime?deleteAt = null, long?deleteAfter = null)
        {
            var client = GetClient().Result;


            var buffered = stream.GetBuffered();

            if (QuotaController != null)
            {
                QuotaController.QuotaUsedCheck(buffered.Length);
            }

            var mime = string.IsNullOrEmpty(contentType)
                                ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                : contentType;

            if (mime == "application/octet-stream")
            {
                contentDisposition = "attachment";
            }

            var customHeaders = new Dictionary <string, object>();

            if (cacheDays > 0)
            {
                customHeaders.Add("Cache-Control", String.Format("public, maxage={0}", (int)TimeSpan.FromDays(cacheDays).TotalSeconds));
                customHeaders.Add("Expires", DateTime.UtcNow.Add(TimeSpan.FromDays(cacheDays)));
            }

            if (!String.IsNullOrEmpty(contentEncoding))
            {
                customHeaders.Add("Content-Encoding", contentEncoding);
            }

            client.UploadFileAsync(_private_container, MakePath(domain, path), false, true, buffered, null, contentDisposition, mime, deleteAt, deleteAfter, customHeaders).Wait();

            var cannedACL = acl == ACL.Auto ? GetDomainACL(domain) : ACL.Read;

            if (cannedACL == ACL.Read)
            {
                var createSymLinkStatus = client.CreateSymLink(
                    _public_container,
                    MakePath(domain, path),
                    SelectelSharp.Models.Link.Symlink.SymlinkType.Symlink,
                    String.Format("/{0}/{1}/", _private_container, MakePath(domain, path))).Result;

                if (!createSymLinkStatus)
                {
                    _logger.ErrorFormat("Symlink '{0}; not created", _public_container + "/" + MakePath(domain, path));

                    throw new Exception(String.Format("Symlink '{0}; not created", _public_container + "/" + MakePath(domain, path)));
                }

                try
                {
                    var invalidationResult = client.CDNIvalidation(_public_container, new[] { MakePath(domain, path) }).Result;
                }
                catch (Exception exp)
                {
                    _logger.InfoFormat("The invalidation {0} failed", _public_container + "/" + MakePath(domain, path));
                    _logger.Error(exp);
                }
            }

            QuotaUsedAdd(domain, buffered.Length);

            return(GetUri(domain, path));
        }
Example #17
0
        public Uri Save(string domain, string path, Stream stream, string contentType,
                        string contentDisposition, ACL acl, string contentEncoding = null, int cacheDays = 5)
        {
            bool postWriteCheck = false;

            if (QuotaController != null)
            {
                try
                {
                    QuotaController.QuotaUsedAdd(_modulename, domain, _dataList.GetData(domain), stream.Length);
                }
                catch (TenantQuotaException)
                {
                    //this exception occurs only if tenant has no free space
                    //or if file size larger than allowed by quota
                    //so we can exit this function without stream buffering etc
                    throw;
                }
                catch (Exception)
                {
                    postWriteCheck = true;
                }
            }


            using (var client = GetClient())
                using (var uploader = new TransferUtility(client))
                {
                    var mime = string.IsNullOrEmpty(contentType)
                                  ? MimeMapping.GetMimeMapping(Path.GetFileName(path))
                                  : contentType;
                    var buffered = stream.GetBuffered();

                    var request = new TransferUtilityUploadRequest
                    {
                        BucketName  = _bucket,
                        Key         = MakePath(domain, path),
                        CannedACL   = acl == ACL.Auto ? GetDomainACL(domain) : GetS3Acl(acl),
                        ContentType = mime,
                        ServerSideEncryptionMethod = ServerSideEncryptionMethod.AES256,
                        InputStream     = buffered,
                        AutoCloseStream = false,
                        Headers         =
                        {
                            CacheControl = string.Format("public, maxage={0}", (int)TimeSpan.FromDays(cacheDays).TotalSeconds),
                            Expires      = DateTime.UtcNow.Add(TimeSpan.FromDays(cacheDays))
                        }
                    };


                    if (!string.IsNullOrEmpty(contentDisposition))
                    {
                        request.Headers.ContentDisposition = contentDisposition;
                    }
                    else if (mime == "application/octet-stream")
                    {
                        request.Headers.ContentDisposition = "attachment";
                    }

                    if (!string.IsNullOrEmpty(contentEncoding))
                    {
                        request.Headers.ContentEncoding = contentEncoding;
                    }

                    //Send body
                    if (postWriteCheck)
                    {
                        QuotaController.QuotaUsedAdd(_modulename, domain, _dataList.GetData(domain), buffered.Length);
                    }

                    uploader.Upload(request);

                    InvalidateCloudFront(MakePath(domain, path));

                    return(GetUri(domain, path));
                }
        }
        public MailAttachment AttachFile(int tenant, string user, int messageId,
                                         string name, Stream inputStream, string streamId)
        {
            if (messageId < 0)
            {
                throw new AttachmentsException(AttachmentsException.Types.BadParams, "Field 'id_message' must have non-negative value.");
            }

            if (tenant < 0)
            {
                throw new AttachmentsException(AttachmentsException.Types.BadParams, "Field 'id_tenant' must have non-negative value.");
            }

            if (String.IsNullOrEmpty(user))
            {
                throw new AttachmentsException(AttachmentsException.Types.BadParams, "Field 'id_user' is empty.");
            }

            if (inputStream.Length == 0)
            {
                throw new AttachmentsException(AttachmentsException.Types.EmptyFile, "Empty files not supported.");
            }

            if (string.IsNullOrEmpty(streamId))
            {
                throw new AttachmentsException(AttachmentsException.Types.MessageNotFound, "Message not found.");
            }

            var message = GetMailInfo(tenant, user, messageId, false, false);

            if (message == null || streamId != message.StreamId)
            {
                throw new AttachmentsException(AttachmentsException.Types.MessageNotFound, "Message not found.");
            }

            var totalSize = GetAttachmentsTotalSize(messageId) + inputStream.Length;

            if (totalSize > ATTACHMENTS_TOTAL_SIZE_LIMIT)
            {
                throw new AttachmentsException(AttachmentsException.Types.TotalSizeExceeded, "Total size of all files exceeds limit!");
            }

            var fileNumber = GetMaxAttachmentNumber(messageId, tenant);

            var attachment = new MailAttachment
            {
                fileName    = name,
                contentType = MimeMapping.GetMimeMapping(name),
                fileNumber  = fileNumber,
                size        = inputStream.Length,
                data        = inputStream.GetCorrectBuffer(),
                streamId    = streamId,
                tenant      = tenant,
                user        = user,
                mailboxId   = message.MailboxId
            };

            QuotaUsedAdd(tenant, inputStream.Length);
            try
            {
                StoreAttachmentWithoutQuota(tenant, user, attachment);
            }
            catch
            {
                QuotaUsedDelete(tenant, inputStream.Length);
                throw;
            }

            using (var db = GetDb())
            {
                using (var tx = db.BeginTransaction())
                {
                    attachment.fileId = SaveAttachment(db, tenant, messageId, attachment);
                    UpdateMessageChainAttachmentsFlag(db, tenant, user, messageId);

                    tx.Commit();
                }
            }

            return(attachment);
        }
Example #19
0
        public MailAttachment AttachFile(int id_tenant, string id_user, int id_message,
                                         string name, Stream input_stream, string id_stream)
        {
            if (id_message < 0)
            {
                throw new AttachmentsException(AttachmentsException.Types.BAD_PARAMS, "Field 'id_message' must have non-negative value.");
            }

            if (id_tenant < 0)
            {
                throw new AttachmentsException(AttachmentsException.Types.BAD_PARAMS, "Field 'id_tenant' must have non-negative value.");
            }

            if (String.IsNullOrEmpty(id_user))
            {
                throw new AttachmentsException(AttachmentsException.Types.BAD_PARAMS, "Field 'id_user' is empty.");
            }

            if (input_stream.Length == 0)
            {
                throw new AttachmentsException(AttachmentsException.Types.EMPTY_FILE, "Empty files not supported.");
            }


            if (string.IsNullOrEmpty(id_stream))
            {
                throw new AttachmentsException(AttachmentsException.Types.MESSAGE_NOT_FOUND, "Message not found.");
            }

            var total_size = GetAttachmentsTotalSize(id_message) + input_stream.Length;

            if (total_size > ATTACHMENTS_TOTAL_SIZE_LIMIT)
            {
                throw new AttachmentsException(AttachmentsException.Types.TOTAL_SIZE_EXCEEDED, "Total size of all files exceeds limit!");
            }

            var file_number = GetMaxAttachmentNumber(id_message);

            var attachment = new MailAttachment
            {
                fileName    = name,
                contentType = MimeMapping.GetMimeMapping(name),
                fileNumber  = file_number,
                size        = input_stream.Length,
                data        = input_stream.GetCorrectBuffer(),
                streamId    = id_stream,
                tenant      = id_tenant,
                user        = id_user
            };

            QuotaUsedAdd(id_tenant, input_stream.Length);
            try
            {
                StoreAttachmentWithoutQuota(id_tenant, id_user, attachment);
            }
            catch
            {
                QuotaUsedDelete(id_tenant, input_stream.Length);
                throw;
            }

            try
            {
                using (var db = GetDb())
                {
                    using (var tx = db.BeginTransaction())
                    {
                        attachment.fileId = SaveAttachment(db, id_tenant, id_message, attachment);
                        UpdateMessageChainAttachmentsFlag(db, id_tenant, id_user, id_message);

                        tx.Commit();
                    }
                }
            }
            catch
            {
                //TODO: If exception has happened, need to remove stored files from s3 and remove quota
                throw;
            }

            return(attachment);
        }
Example #20
0
        private static string CreateFile(Stream content, string fileName, string folderId, Token token)
        {
            Global.Logger.Debug("GoogleDriveApp: create file");

            var request = (HttpWebRequest)WebRequest.Create(GoogleLoginProvider.GoogleUrlFileUpload + "?uploadType=multipart");

            using (var tmpStream = new MemoryStream())
            {
                var boundary = DateTime.UtcNow.Ticks.ToString("x");

                var folderdata   = string.IsNullOrEmpty(folderId) ? "" : string.Format(",\"parents\":[\"{0}\"]", folderId);
                var metadata     = string.Format("{{\"name\":\"{0}\"{1}}}", fileName, folderdata);
                var metadataPart = string.Format("\r\n--{0}\r\nContent-Type: application/json; charset=UTF-8\r\n\r\n{1}", boundary, metadata);
                var bytes        = Encoding.UTF8.GetBytes(metadataPart);
                tmpStream.Write(bytes, 0, bytes.Length);

                var mediaPartStart = string.Format("\r\n--{0}\r\nContent-Type: {1}\r\n\r\n", boundary, MimeMapping.GetMimeMapping(fileName));
                bytes = Encoding.UTF8.GetBytes(mediaPartStart);
                tmpStream.Write(bytes, 0, bytes.Length);

                content.CopyTo(tmpStream);

                var mediaPartEnd = string.Format("\r\n--{0}--\r\n", boundary);
                bytes = Encoding.UTF8.GetBytes(mediaPartEnd);
                tmpStream.Write(bytes, 0, bytes.Length);

                request.Method = "POST";
                request.Headers.Add("Authorization", "Bearer " + token);
                request.ContentType   = "multipart/related; boundary=" + boundary;
                request.ContentLength = tmpStream.Length;
                Global.Logger.Debug("GoogleDriveApp: create file totalSize - " + tmpStream.Length);

                const int bufferSize = 2048;
                var       buffer     = new byte[bufferSize];
                int       readed;
                tmpStream.Seek(0, SeekOrigin.Begin);
                while ((readed = tmpStream.Read(buffer, 0, bufferSize)) > 0)
                {
                    request.GetRequestStream().Write(buffer, 0, readed);
                }
            }

            try
            {
                using (var response = request.GetResponse())
                    using (var responseStream = response.GetResponseStream())
                    {
                        string result = null;
                        if (responseStream != null)
                        {
                            using (var readStream = new StreamReader(responseStream))
                            {
                                result = readStream.ReadToEnd();
                            }
                        }

                        Global.Logger.Debug("GoogleDriveApp: create file response - " + result);
                        return(result);
                    }
            }
            catch (WebException e)
            {
                Global.Logger.Error("GoogleDriveApp: Error create file", e);
                request.Abort();

                var httpResponse = (HttpWebResponse)e.Response;
                if (httpResponse.StatusCode == HttpStatusCode.Forbidden)
                {
                    throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException, e);
                }
            }
            return(null);
        }
Example #21
0
        private static string CreateConvertedFile(string driveFile, Token token)
        {
            var jsonFile = JObject.Parse(driveFile);
            var fileName = GetCorrectTitle(jsonFile);

            fileName = FileUtility.ReplaceFileExtension(fileName, FileUtility.GetInternalExtension(fileName));

            var folderId = (string)jsonFile.SelectToken("parents[0]");

            Global.Logger.Info("GoogleDriveApp: create copy - " + fileName);

            var ext    = GetCorrectExt(jsonFile);
            var fileId = jsonFile.Value <string>("id");

            if (GoogleLoginProvider.GoogleDriveExt.Contains(ext))
            {
                var fileType         = FileUtility.GetFileTypeByExtention(ext);
                var internalExt      = FileUtility.InternalExtension[fileType];
                var requiredMimeType = MimeMapping.GetMimeMapping(internalExt);

                var downloadUrl = GoogleLoginProvider.GoogleUrlFile
                                  + string.Format("{0}/export?mimeType={1}",
                                                  fileId,
                                                  HttpUtility.UrlEncode(requiredMimeType));

                var request = (HttpWebRequest)WebRequest.Create(downloadUrl);
                request.Method = "GET";
                request.Headers.Add("Authorization", "Bearer " + token);

                Global.Logger.Debug("GoogleDriveApp: download exportLink - " + downloadUrl);
                try
                {
                    using (var response = request.GetResponse())
                        using (var fileStream = new ResponseStream(response))
                        {
                            driveFile = CreateFile(fileStream, fileName, folderId, token);
                        }
                }
                catch (WebException e)
                {
                    Global.Logger.Error("GoogleDriveApp: Error download exportLink", e);
                    request.Abort();
                }
            }
            else
            {
                var downloadUrl = GoogleLoginProvider.GoogleUrlFile + fileId + "?alt=media";

                var convertedUrl = ConvertFile(downloadUrl, ext, token);

                if (string.IsNullOrEmpty(convertedUrl))
                {
                    Global.Logger.ErrorFormat("GoogleDriveApp: Error convertUrl. size {0}", FileSizeComment.FilesSizeToString(jsonFile.Value <int>("size")));
                    throw new Exception(FilesCommonResource.ErrorMassage_DocServiceException + " (convert)");
                }

                driveFile = CreateFile(convertedUrl, fileName, folderId, token);
            }

            jsonFile = JObject.Parse(driveFile);
            return(jsonFile.Value <string>("id"));
        }
Example #22
0
        public void SaveFile(string fileId, string fileType, string downloadUrl, Stream stream)
        {
            Global.Logger.Debug("GoogleDriveApp: save file stream " + fileId +
                                (stream == null
                                     ? " from - " + downloadUrl
                                     : " from stream"));
            fileId = ThirdPartySelector.GetFileId(fileId);

            var token = Token.GetToken(AppAttr);

            var driveFile = GetDriveFile(fileId, token);

            if (driveFile == null)
            {
                Global.Logger.Error("GoogleDriveApp: file is null");
                throw new Exception("File not found");
            }

            var jsonFile    = JObject.Parse(driveFile);
            var currentType = GetCorrectExt(jsonFile);

            if (!fileType.Equals(currentType))
            {
                try
                {
                    var key = DocumentServiceConnector.GenerateRevisionId(downloadUrl ?? Guid.NewGuid().ToString());
                    if (stream != null)
                    {
                        using (var tmpStream = new MemoryStream())
                        {
                            stream.CopyTo(tmpStream);

                            Global.Logger.Debug("GoogleDriveApp: GetExternalUri format: " + fileType);
                            downloadUrl = DocumentServiceConnector.GetExternalUri(tmpStream, fileType, key);
                        }
                    }

                    Global.Logger.Debug("GoogleDriveApp: GetConvertedUri from " + fileType + " to " + currentType + " - " + downloadUrl);

                    DocumentServiceConnector.GetConvertedUri(downloadUrl, fileType, currentType, key, false, out downloadUrl);
                    stream = null;
                }
                catch (Exception e)
                {
                    Global.Logger.Error("GoogleDriveApp: Error convert", e);
                }
            }

            var request = (HttpWebRequest)WebRequest.Create(GoogleLoginProvider.GoogleUrlFileUpload + "/{fileId}?uploadType=media".Replace("{fileId}", fileId));

            request.Method = "PATCH";
            request.Headers.Add("Authorization", "Bearer " + token);
            request.ContentType = MimeMapping.GetMimeMapping(currentType);

            if (stream != null)
            {
                request.ContentLength = stream.Length;

                const int bufferSize = 2048;
                var       buffer     = new byte[bufferSize];
                int       readed;
                while ((readed = stream.Read(buffer, 0, bufferSize)) > 0)
                {
                    request.GetRequestStream().Write(buffer, 0, readed);
                }
            }
            else
            {
                var downloadRequest = (HttpWebRequest)WebRequest.Create(downloadUrl);
                using (var downloadStream = new ResponseStream(downloadRequest.GetResponse()))
                {
                    request.ContentLength = downloadStream.Length;

                    const int bufferSize = 2048;
                    var       buffer     = new byte[bufferSize];
                    int       readed;
                    while ((readed = downloadStream.Read(buffer, 0, bufferSize)) > 0)
                    {
                        request.GetRequestStream().Write(buffer, 0, readed);
                    }
                }
            }

            try
            {
                using (var response = request.GetResponse())
                    using (var responseStream = response.GetResponseStream())
                    {
                        string result = null;
                        if (responseStream != null)
                        {
                            using (var readStream = new StreamReader(responseStream))
                            {
                                result = readStream.ReadToEnd();
                            }
                        }

                        Global.Logger.Debug("GoogleDriveApp: save file stream response - " + result);
                    }
            }
            catch (WebException e)
            {
                Global.Logger.Error("GoogleDriveApp: Error save file stream", e);
                request.Abort();
                var httpResponse = (HttpWebResponse)e.Response;
                if (httpResponse.StatusCode == HttpStatusCode.Forbidden)
                {
                    throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException, e);
                }
                throw;
            }
        }
        private void UploadToCdn()
        {
            try
            {
                // one thread only
                if (Interlocked.CompareExchange(ref work, 1, 0) == 0)
                {
                    var @continue = false;
                    try
                    {
                        CdnItem item;
                        if (queue.TryDequeue(out item))
                        {
                            @continue = true;

                            var cdnpath = GetCdnPath(item.Bundle.Path);
                            var key     = new Uri(cdnpath).PathAndQuery.TrimStart('/');
                            var path    = key.Remove(0, _container.Length + 1);

                            var content     = Encoding.UTF8.GetBytes(item.Response.Content);
                            var inputStream = new MemoryStream();

                            if (ClientSettings.GZipEnabled)
                            {
                                using (var zip = new GZipStream(inputStream, CompressionMode.Compress, true))
                                {
                                    zip.Write(content, 0, content.Length);
                                    zip.Flush();
                                }
                            }
                            else
                            {
                                inputStream.Write(content, 0, content.Length);
                            }

                            inputStream.Position = 0;

                            bool upload = true;

                            var client = new SelectelClient();

                            client.AuthorizeAsync(_authUser, _authPwd).Wait();

                            var etag = SelectelSharp.Common.Helpers.CalculateSHA1(item.Response.Content);

                            var fileInfo = client.GetContainerFilesAsync(_container, 1, null, path, null, null).Result;

                            if (fileInfo != null && fileInfo.Any())
                            {
                                upload = fileInfo.Single().Hash != etag;
                            }

                            if (upload)
                            {
                                var contentType = String.Empty;

                                var mime = string.IsNullOrEmpty(contentType) ? MimeMapping.GetMimeMapping(Path.GetFileName(key))
                             : contentType;

                                var customHeaders = new Dictionary <string, object>();

                                if (ClientSettings.GZipEnabled)
                                {
                                    customHeaders.Add("Content-Encoding", "gzip");
                                }

                                var cache = TimeSpan.FromDays(365);

                                customHeaders.Add("Cache-Control", String.Format("public, maxage={0}", (int)cache.TotalSeconds));
                                customHeaders.Add("Expires", DateTime.UtcNow.Add(cache));

                                client.UploadFileAsync(_container, path, true, true, inputStream, etag, null, mime, null, null, customHeaders).Wait();
                            }
                            else
                            {
                                inputStream.Close();
                            }

                            item.Bundle.CdnPath = cdnpath;
                        }
                    }
                    catch (Exception err)
                    {
                        log.Error(err);
                    }
                    finally
                    {
                        work = 0;
                        if (@continue)
                        {
                            Action upload = () => UploadToCdn();
                            upload.BeginInvoke(null, null);
                        }
                    }
                }
            }
            catch (Exception fatal)
            {
                log.Fatal(fatal);
            }
        }
Example #24
0
        private static void DownloadFile(int attachmentId, HttpContext context)
        {
            var auth = context.Request[FilesLinkUtility.AuthKey];

            var openTempStream = false;

            if (!string.IsNullOrEmpty(auth))
            {
                var stream = context.Request.QueryString["stream"];

                if (!string.IsNullOrEmpty(stream))
                {
                    int validateTimespan;
                    int.TryParse(ConfigurationManagerExtension.AppSettings["files.stream-url-minute"], out validateTimespan);
                    if (validateTimespan <= 0)
                    {
                        validateTimespan = 5;
                    }

                    var validateResult = EmailValidationKeyProvider.ValidateEmailKey(attachmentId + stream, auth, TimeSpan.FromMinutes(validateTimespan));
                    if (validateResult != EmailValidationKeyProvider.ValidationResult.Ok)
                    {
                        var exc = new HttpException((int)HttpStatusCode.Forbidden, "You don't have enough permission to perform the operation");
                        //Global.Logger.Error(string.Format("{0} {1}: {2}", CommonLinkUtility.AuthKey, validateResult, context.Request.Url), exc);
                        throw exc;
                    }

                    openTempStream = true;
                }
            }
            else
            {
                if (!SecurityContext.IsAuthenticated)
                {
                    throw new HttpException(403, "Access denied.");
                }
            }

            var engine     = new EngineFactory(TenantId, Username);
            var attachment = engine.AttachmentEngine.GetAttachment(
                openTempStream
                    ? (IAttachmentExp) new ConcreteTenantAttachmentExp(attachmentId, TenantId)
                    : new ConcreteUserAttachmentExp(attachmentId, TenantId, Username));

            long offset    = 0;
            long endOffset = -1;
            long length    = attachment.size;

            if (context.Request.Headers["Range"] != null)
            {
                var range = context.Request.Headers["Range"].Split('=', '-');
                offset = Convert.ToInt64(range[1]);

                if (range.Count() > 2 && !string.IsNullOrEmpty(range[2]))
                {
                    endOffset = Convert.ToInt64(range[2]);
                }
                if (endOffset < 0 || endOffset >= attachment.size)
                {
                    endOffset = attachment.size - 1;
                }

                length = endOffset - offset + 1;

                if (length <= 0)
                {
                    throw new HttpException("Wrong Range header");
                }

                context.Response.StatusCode = 206;
                context.Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", offset, endOffset, attachment.size));
            }

            using (var file = attachment.ToAttachmentStream((int)offset))
            {
                context.Response.AddHeader("Accept-Ranges", "bytes");
                context.Response.AddHeader("Content-Length", length.ToString(CultureInfo.InvariantCulture));
                context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(file.FileName));
                context.Response.ContentType = MimeMapping.GetMimeMapping(file.FileName);

                if (endOffset != attachment.size - 1)
                {
                    file.FileStream.CopyTo(context.Response.OutputStream);
                }
                else
                {
                    file.FileStream.StreamCopyTo(context.Response.OutputStream, (int)length);
                }
            }
        }
        public void StoreAttachments(int tenant, string user, List <MailAttachment> attachments, string streamId, int mailboxId)
        {
            if (!attachments.Any() || string.IsNullOrEmpty(streamId))
            {
                return;
            }

            var storage = MailDataStore.GetDataStore(tenant);

            if (storage == null)
            {
                throw new NullReferenceException("GetDataStore has returned null reference.");
            }

            var quotaAddSize = attachments.Sum(a => a.data.LongLength);

            QuotaUsedAdd(tenant, quotaAddSize);

            try
            {
                foreach (var attachment in attachments)
                {
                    var isAttachmentNameHasBadName = string.IsNullOrEmpty(attachment.fileName) ||
                                                     attachment.fileName.IndexOfAny(Path.GetInvalidPathChars()) != -1 ||
                                                     attachment.fileName.IndexOfAny(Path.GetInvalidFileNameChars()) != -1;
                    if (isAttachmentNameHasBadName)
                    {
                        attachment.fileName = string.Format("attacment{0}{1}", attachment.fileNumber,
                                                            MimeMapping.GetExtention(attachment.contentType));
                    }

                    attachment.streamId = streamId;
                    attachment.tenant   = tenant;
                    attachment.user     = user;
                    StoreAttachmentWithoutQuota(tenant, user, attachment, storage);

                    //This is dirty hack needed for mailbox updating on attachment processing. If we doesn't update mailbox checktime, it will be reset.
                    if (mailboxId > 0)
                    {
                        LockMailbox(mailboxId);
                    }
                }
            }
            catch
            {
                var storedAttachmentsKeys = attachments
                                            .Where(a => !string.IsNullOrEmpty(a.storedFileUrl))
                                            .Select(MailStoragePathCombiner.GerStoredFilePath)
                                            .ToList();

                //Todo: Rewrite this ugly code
                var isQuotaCleaned = false;
                if (storedAttachmentsKeys.Any())
                {
                    var s3Storage = storage as S3Storage;
                    if (s3Storage != null)
                    {
                        // ToDo: Delete with quota argument needs to be moved to IDataStore!
                        storedAttachmentsKeys
                        .ForEach(key => s3Storage.Delete(string.Empty, key, false));
                    }
                    else
                    {
                        isQuotaCleaned = true;
                        storedAttachmentsKeys.ForEach(key => storage.Delete(string.Empty, key));
                    }
                }

                if (!isQuotaCleaned)
                {
                    QuotaUsedDelete(tenant, quotaAddSize);
                }

                _log.Debug(String.Format("Problems with attachment saving in mailboxId={0}. All message attachments was deleted.", mailboxId));
                throw;
            }
        }
Example #26
0
        private static string CreateConvertedFile(string driveFile, Token token)
        {
            var jsonFile = JObject.Parse(driveFile);
            var fileName = GetCorrectTitle(jsonFile);

            fileName = FileUtility.ReplaceFileExtension(fileName, FileUtility.GetInternalExtension(fileName));

            var folderId = (string)jsonFile.SelectToken("parents[0].id");

            Global.Logger.Info("GoogleDriveApp: create copy - " + fileName);

            var ext = GetCorrectExt(jsonFile);

            if (GoogleLoginProvider.GoogleDriveExt.Contains(ext))
            {
                var links = jsonFile["exportLinks"];
                if (links == null)
                {
                    Global.Logger.Error("GoogleDriveApp: exportLinks is null");
                    throw new Exception("exportLinks is null");
                }

                var fileType         = FileUtility.GetFileTypeByExtention(ext);
                var internalExt      = FileUtility.InternalExtension[fileType];
                var requiredMimeType = MimeMapping.GetMimeMapping(internalExt);

                var exportLinks = links.ToObject <Dictionary <string, string> >();
                var downloadUrl = exportLinks[requiredMimeType] ?? "";

                if (string.IsNullOrEmpty(downloadUrl))
                {
                    Global.Logger.Error("GoogleDriveApp: exportLinks without requested mime - " + links);
                    throw new Exception("exportLinks without requested mime");
                }


                var request = (HttpWebRequest)WebRequest.Create(downloadUrl);
                request.Method = "GET";
                request.Headers.Add("Authorization", "Bearer " + token);

                Global.Logger.Debug("GoogleDriveApp: download exportLink - " + downloadUrl);
                try
                {
                    using (var response = request.GetResponse())
                        using (var fileStream = new ResponseStream(response))
                        {
                            driveFile = CreateFile(fileStream, fileName, folderId, token);
                        }
                }
                catch (WebException e)
                {
                    Global.Logger.Error("GoogleDriveApp: Error download exportLink", e);
                    request.Abort();

                    var httpResponse = (HttpWebResponse)e.Response;
                    if (httpResponse.StatusCode == HttpStatusCode.Unauthorized && fileType == FileType.Spreadsheet)
                    {
                        throw new SecurityException(FilesCommonResource.AppDriveSpreadsheetException, e);
                    }
                }
            }
            else
            {
                var downloadUrl = jsonFile.Value <string>("downloadUrl");

                var convertedUrl = ConvertFile(downloadUrl, ext, token);

                if (string.IsNullOrEmpty(convertedUrl))
                {
                    Global.Logger.ErrorFormat("GoogleDriveApp: Error convertUrl. FileSize {0}", FileSizeComment.FilesSizeToString(jsonFile.Value <int>("fileSize")));
                    throw new Exception(FilesCommonResource.ErrorMassage_DocServiceException + " (convert)");
                }

                driveFile = CreateFile(convertedUrl, fileName, folderId, token);
            }

            jsonFile = JObject.Parse(driveFile);
            return(jsonFile.Value <string>("id"));
        }