private static void SendStreamByChunks(HttpContext context, long toRead, string title, Stream fileStream, ref bool flushed)
        {
            context.Response.Buffer = false;
            context.Response.AddHeader("Connection", "Keep-Alive");
            context.Response.AddHeader("Content-Length", toRead.ToString(CultureInfo.InvariantCulture));
            context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(title));
            context.Response.ContentType = MimeMapping.GetMimeMapping(title);

            const int bufferSize = 32 * 1024; // 32KB
            var       buffer     = new byte[bufferSize];

            while (toRead > 0)
            {
                var length = fileStream.Read(buffer, 0, bufferSize);

                if (context.Response.IsClientConnected)
                {
                    context.Response.OutputStream.Write(buffer, 0, length);
                    context.Response.Flush();
                    flushed = true;
                    toRead -= length;
                }
                else
                {
                    toRead = -1;
                    Global.Logger.Warn(string.Format("IsClientConnected is false. Why? Download file {0} Connection is lost. ", title));
                }
            }
        }
Beispiel #2
0
        private 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);

                        Logger.Debug("GoogleDriveApp: Try GetCorrectExt - " + ext + " for - " + mimeType);
                    }
                }
            }
            return(ext);
        }
Beispiel #3
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);
            }

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

            var storage = GetStorage();

            UploadObjectOptions 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));
        }
        private static void TempFile(HttpContext context)
        {
            var fileName = context.Request[FilesLinkUtility.FileTitle];
            var auth     = context.Request[FilesLinkUtility.AuthKey];

            var validateResult = EmailValidationKeyProvider.ValidateEmailKey(fileName, auth ?? "", Global.StreamUrlExpire);

            if (validateResult != EmailValidationKeyProvider.ValidationResult.Ok)
            {
                var exc = new HttpException((int)HttpStatusCode.Forbidden, FilesCommonResource.ErrorMassage_SecurityException);

                Global.Logger.Error(string.Format("{0} {1}: {2}", FilesLinkUtility.AuthKey, validateResult, context.Request.Url), exc);

                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                context.Response.Write(FilesCommonResource.ErrorMassage_SecurityException);
                return;
            }

            context.Response.Clear();
            context.Response.ContentType = MimeMapping.GetMimeMapping(fileName);
            context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(fileName));

            var store = Global.GetStore();

            var path = Path.Combine("temp_stream", fileName);

            if (!store.IsFile(FileConstant.StorageDomainTmp, path))
            {
                context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                context.Response.Write(FilesCommonResource.ErrorMassage_FileNotFound);
                return;
            }

            using (var readStream = store.GetReadStream(FileConstant.StorageDomainTmp, path))
            {
                context.Response.AddHeader("Content-Length", readStream.Length.ToString(CultureInfo.InvariantCulture));
                readStream.StreamCopyTo(context.Response.OutputStream);
            }

            store.Delete(FileConstant.StorageDomainTmp, path);

            try
            {
                context.Response.Flush();
                context.Response.SuppressContent = true;
                context.ApplicationInstance.CompleteRequest();
            }
            catch (HttpException he)
            {
                Global.Logger.ErrorFormat("TempFile", he);
            }
        }
        public object UploadFile(T folderId, UploadModel uploadModel)
        {
            if (uploadModel.StoreOriginalFileFlag.HasValue)
            {
                FilesSettingsHelper.StoreOriginalFiles = uploadModel.StoreOriginalFileFlag.Value;
            }

            IEnumerable <IFormFile> files = HttpContextAccessor.HttpContext.Request.Form.Files;

            if (files == null || !files.Any())
            {
                files = uploadModel.Files;
            }

            if (files != null && files.Any())
            {
                if (files.Count() == 1)
                {
                    //Only one file. return it
                    var postedFile = files.First();
                    return(InsertFile(folderId, postedFile.OpenReadStream(), postedFile.FileName, uploadModel.CreateNewIfExist, uploadModel.KeepConvertStatus));
                }

                //For case with multiple files
                return(uploadModel.Files.Select(postedFile => InsertFile(folderId, postedFile.OpenReadStream(), postedFile.FileName, uploadModel.CreateNewIfExist, uploadModel.KeepConvertStatus)).ToList());
            }

            if (uploadModel.File != null)
            {
                var fileName = "file" + MimeMapping.GetExtention(uploadModel.ContentType.MediaType);
                if (uploadModel.ContentDisposition != null)
                {
                    fileName = uploadModel.ContentDisposition.FileName;
                }

                return(new List <FileWrapper <T> >
                {
                    InsertFile(folderId, uploadModel.File.OpenReadStream(), fileName, uploadModel.CreateNewIfExist, uploadModel.KeepConvertStatus)
                });
            }

            throw new InvalidOperationException("No input files");
        }
Beispiel #6
0
        private string CreateConvertedFile(string driveFile, Token token)
        {
            var jsonFile = JObject.Parse(driveFile);
            var fileName = GetCorrectTitle(jsonFile);

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

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

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

            if (GoogleLoginProvider.GoogleDriveExt.Contains(ext))
            {
                var internalExt = FileUtility.GetGoogleDownloadableExtension(ext);
                fileName = FileUtility.ReplaceFileExtension(fileName, internalExt);
                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);

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

                    var httpResponse = (HttpWebResponse)e.Response;
                    if (httpResponse.StatusCode == HttpStatusCode.Forbidden || httpResponse.StatusCode == HttpStatusCode.Unauthorized)
                    {
                        throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException, e);
                    }
                }
            }
            else
            {
                var convertedUrl = ConvertFile(fileId, ext);

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

                var toExt = FileUtility.GetInternalExtension(fileName);
                fileName  = FileUtility.ReplaceFileExtension(fileName, toExt);
                driveFile = CreateFile(convertedUrl, fileName, folderId, token);
            }

            jsonFile = JObject.Parse(driveFile);
            return(jsonFile.Value <string>("id"));
        }
Beispiel #7
0
        private string CreateFile(Stream content, string fileName, string folderId, Token token)
        {
            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;
                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();
                            }
                        }

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

                var httpResponse = (HttpWebResponse)e.Response;
                if (httpResponse.StatusCode == HttpStatusCode.Forbidden || httpResponse.StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException, e);
                }
            }
            return(null);
        }
Beispiel #8
0
        public void SaveFile(string fileId, string fileType, string downloadUrl, Stream stream)
        {
            Logger.Debug("GoogleDriveApp: save file stream " + fileId +
                         (stream == null
                                     ? " from - " + downloadUrl
                                     : " from stream"));
            fileId = ThirdPartySelector.GetFileId(fileId);

            var token = TokenHelper.GetToken(AppAttr);

            var driveFile = GetDriveFile(fileId, token);

            if (driveFile == null)
            {
                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
                {
                    if (stream != null)
                    {
                        downloadUrl = PathProvider.GetTempUrl(stream, fileType);
                        downloadUrl = DocumentServiceConnector.ReplaceCommunityAdress(downloadUrl);
                    }

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

                    var key = DocumentServiceConnector.GenerateRevisionId(downloadUrl);
                    DocumentServiceConnector.GetConvertedUri(downloadUrl, fileType, currentType, key, null, false, out downloadUrl);
                    stream = null;
                }
                catch (Exception e)
                {
                    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();
                }

                Logger.Debug("GoogleDriveApp: save file stream response - " + result);
            }
            catch (WebException e)
            {
                Logger.Error("GoogleDriveApp: Error save file stream", e);
                request.Abort();
                var httpResponse = (HttpWebResponse)e.Response;
                if (httpResponse.StatusCode == HttpStatusCode.Forbidden || httpResponse.StatusCode == HttpStatusCode.Unauthorized)
                {
                    throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException, e);
                }
                throw;
            }
        }
Beispiel #9
0
 private static string MakeContentTypeHeader(string fileName)
 {
     return(string.Format("Content-Type: {0}\r\n", MimeMapping.GetMimeMapping(fileName)));
 }
        private static void DifferenceFile(HttpContext context)
        {
            try
            {
                using (var fileDao = Global.DaoFactory.GetFileDao())
                {
                    var id = context.Request[FilesLinkUtility.FileId];
                    int version;
                    int.TryParse(context.Request[FilesLinkUtility.Version] ?? "", out version);
                    var doc = context.Request[FilesLinkUtility.DocShareKey];

                    File file;
                    var  linkRight = FileShareLink.Check(doc, fileDao, out file);
                    if (linkRight == FileShare.Restrict && !SecurityContext.IsAuthenticated)
                    {
                        var auth           = context.Request[FilesLinkUtility.AuthKey];
                        var validateResult = EmailValidationKeyProvider.ValidateEmailKey(id + version, auth ?? "", Global.StreamUrlExpire);
                        if (validateResult != EmailValidationKeyProvider.ValidationResult.Ok)
                        {
                            var exc = new HttpException((int)HttpStatusCode.Forbidden, FilesCommonResource.ErrorMassage_SecurityException);

                            Global.Logger.Error(string.Format("{0} {1}: {2}", FilesLinkUtility.AuthKey, validateResult, context.Request.Url), exc);

                            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                            context.Response.Write(FilesCommonResource.ErrorMassage_SecurityException);
                            return;
                        }
                    }

                    fileDao.InvalidateCache(id);

                    if (file == null ||
                        version > 0 && file.Version != version)
                    {
                        file = version > 0
                                   ? fileDao.GetFile(id, version)
                                   : fileDao.GetFile(id);
                    }

                    if (file == null)
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        return;
                    }

                    if (linkRight == FileShare.Restrict && SecurityContext.IsAuthenticated && !Global.GetFilesSecurity().CanRead(file))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return;
                    }

                    if (!string.IsNullOrEmpty(file.Error))
                    {
                        context.Response.StatusDescription = file.Error;
                        context.Response.StatusCode        = (int)HttpStatusCode.BadRequest;
                        return;
                    }

                    context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(".zip"));
                    context.Response.ContentType = MimeMapping.GetMimeMapping(".zip");

                    using (var stream = fileDao.GetDifferenceStream(file))
                    {
                        context.Response.AddHeader("Content-Length", stream.Length.ToString(CultureInfo.InvariantCulture));
                        stream.StreamCopyTo(context.Response.OutputStream);
                    }
                }
            }
            catch (Exception ex)
            {
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.Response.Write(ex.Message);
                Global.Logger.Error("Error for: " + context.Request.Url, ex);
                return;
            }

            try
            {
                context.Response.Flush();
                context.Response.SuppressContent = true;
                context.ApplicationInstance.CompleteRequest();
            }
            catch (HttpException he)
            {
                Global.Logger.ErrorFormat("DifferenceFile", he);
            }
        }
        private static void EmptyFile(HttpContext context)
        {
            try
            {
                var fileName = context.Request[FilesLinkUtility.FileTitle];
                if (!string.IsNullOrEmpty(FileUtility.SignatureSecret))
                {
                    try
                    {
                        var header = context.Request.Headers[FileUtility.SignatureHeader];
                        if (string.IsNullOrEmpty(header) || !header.StartsWith("Bearer "))
                        {
                            throw new Exception("Invalid header " + header);
                        }
                        header = header.Substring("Bearer ".Length);

                        JsonWebToken.JsonSerializer = new DocumentService.JwtSerializer();

                        var stringPayload = JsonWebToken.Decode(header, FileUtility.SignatureSecret);

                        Global.Logger.Debug("DocService EmptyFile payload: " + stringPayload);
                        //var data = JObject.Parse(stringPayload);
                        //if (data == null)
                        //{
                        //    throw new ArgumentException("DocService EmptyFile header is incorrect");
                        //}

                        //var signedStringUrl = data["url"] ?? (data["payload"] != null ? data["payload"]["url"] : null);
                        //if (signedStringUrl == null)
                        //{
                        //    throw new ArgumentException("DocService EmptyFile header url is incorrect");
                        //}
                        //var signedUrl = new Uri(signedStringUrl.ToString());

                        //var signedQuery = signedUrl.Query;
                        //if (!context.Request.Url.Query.Equals(signedQuery))
                        //{
                        //    throw new SecurityException(string.Format("DocService EmptyFile header id not equals: {0} and {1}", context.Request.Url.Query, signedQuery));
                        //}
                    }
                    catch (Exception ex)
                    {
                        Global.Logger.Error("Download stream header " + context.Request.Url, ex);
                        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        context.Response.Write(FilesCommonResource.ErrorMassage_SecurityException);
                        return;
                    }
                }

                var toExtension   = FileUtility.GetFileExtension(fileName);
                var fileExtension = FileUtility.GetInternalExtension(toExtension);
                fileName = "new" + fileExtension;
                var path = FileConstant.NewDocPath
                           + (CoreContext.Configuration.CustomMode ? "ru-RU/" : "default/")
                           + fileName;

                var storeTemplate = Global.GetStoreTemplate();
                if (!storeTemplate.IsFile("", path))
                {
                    context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                    context.Response.Write(FilesCommonResource.ErrorMassage_FileNotFound);
                    return;
                }

                context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(fileName));
                context.Response.ContentType = MimeMapping.GetMimeMapping(fileName);

                using (var stream = storeTemplate.GetReadStream("", path))
                {
                    context.Response.AddHeader("Content-Length",
                                               stream.CanSeek
                                                   ? stream.Length.ToString(CultureInfo.InvariantCulture)
                                                   : storeTemplate.GetFileSize("", path).ToString(CultureInfo.InvariantCulture));
                    stream.StreamCopyTo(context.Response.OutputStream);
                }
            }
            catch (Exception ex)
            {
                Global.Logger.Error("Error for: " + context.Request.Url, ex);
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.Response.Write(ex.Message);
                return;
            }

            try
            {
                context.Response.Flush();
                context.Response.SuppressContent = true;
                context.ApplicationInstance.CompleteRequest();
            }
            catch (HttpException he)
            {
                Global.Logger.ErrorFormat("EmptyFile", he);
            }
        }
        private static void StreamFile(HttpContext context)
        {
            try
            {
                using (var fileDao = Global.DaoFactory.GetFileDao())
                {
                    var id = context.Request[FilesLinkUtility.FileId];
                    int version;
                    if (!int.TryParse(context.Request[FilesLinkUtility.Version] ?? "", out version))
                    {
                        version = 0;
                    }
                    var doc = context.Request[FilesLinkUtility.DocShareKey];

                    fileDao.InvalidateCache(id);

                    File file;
                    var  linkRight = FileShareLink.Check(doc, fileDao, out file);
                    if (linkRight == FileShare.Restrict && !SecurityContext.IsAuthenticated)
                    {
                        var auth           = context.Request[FilesLinkUtility.AuthKey];
                        var validateResult = EmailValidationKeyProvider.ValidateEmailKey(id + version, auth ?? "", Global.StreamUrlExpire);
                        if (validateResult != EmailValidationKeyProvider.ValidationResult.Ok)
                        {
                            var exc = new HttpException((int)HttpStatusCode.Forbidden, FilesCommonResource.ErrorMassage_SecurityException);

                            Global.Logger.Error(string.Format("{0} {1}: {2}", FilesLinkUtility.AuthKey, validateResult, context.Request.Url), exc);

                            context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                            context.Response.Write(FilesCommonResource.ErrorMassage_SecurityException);
                            return;
                        }

                        if (!string.IsNullOrEmpty(FileUtility.SignatureSecret))
                        {
                            try
                            {
                                var header = context.Request.Headers[FileUtility.SignatureHeader];
                                if (string.IsNullOrEmpty(header) || !header.StartsWith("Bearer "))
                                {
                                    throw new Exception("Invalid header " + header);
                                }
                                header = header.Substring("Bearer ".Length);

                                JsonWebToken.JsonSerializer = new DocumentService.JwtSerializer();

                                var stringPayload = JsonWebToken.Decode(header, FileUtility.SignatureSecret);

                                Global.Logger.Debug("DocService StreamFile payload: " + stringPayload);
                                //var data = JObject.Parse(stringPayload);
                                //if (data == null)
                                //{
                                //    throw new ArgumentException("DocService StreamFile header is incorrect");
                                //}

                                //var signedStringUrl = data["url"] ?? (data["payload"] != null ? data["payload"]["url"] : null);
                                //if (signedStringUrl == null)
                                //{
                                //    throw new ArgumentException("DocService StreamFile header url is incorrect");
                                //}
                                //var signedUrl = new Uri(signedStringUrl.ToString());

                                //var signedQuery = signedUrl.Query;
                                //if (!context.Request.Url.Query.Equals(signedQuery))
                                //{
                                //    throw new SecurityException(string.Format("DocService StreamFile header id not equals: {0} and {1}", context.Request.Url.Query, signedQuery));
                                //}
                            }
                            catch (Exception ex)
                            {
                                Global.Logger.Error("Download stream header " + context.Request.Url, ex);
                                context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                                context.Response.Write(FilesCommonResource.ErrorMassage_SecurityException);
                                return;
                            }
                        }
                    }

                    if (file == null ||
                        version > 0 && file.Version != version)
                    {
                        file = version > 0
                                   ? fileDao.GetFile(id, version)
                                   : fileDao.GetFile(id);
                    }

                    if (file == null)
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.NotFound;
                        return;
                    }

                    if (linkRight == FileShare.Restrict && SecurityContext.IsAuthenticated && !Global.GetFilesSecurity().CanRead(file))
                    {
                        context.Response.StatusCode = (int)HttpStatusCode.Forbidden;
                        return;
                    }

                    if (!string.IsNullOrEmpty(file.Error))
                    {
                        context.Response.StatusDescription = file.Error;
                        context.Response.StatusCode        = (int)HttpStatusCode.BadRequest;
                        return;
                    }

                    context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(file.Title));
                    context.Response.ContentType = MimeMapping.GetMimeMapping(file.Title);

                    using (var stream = fileDao.GetFileStream(file))
                    {
                        context.Response.AddHeader("Content-Length",
                                                   stream.CanSeek
                                                       ? stream.Length.ToString(CultureInfo.InvariantCulture)
                                                       : file.ContentLength.ToString(CultureInfo.InvariantCulture));
                        stream.StreamCopyTo(context.Response.OutputStream);
                    }
                }
            }
            catch (Exception ex)
            {
                Global.Logger.Error("Error for: " + context.Request.Url, ex);
                context.Response.StatusCode = (int)HttpStatusCode.InternalServerError;
                context.Response.Write(ex.Message);
                return;
            }

            try
            {
                context.Response.Flush();
                context.Response.SuppressContent = true;
                context.ApplicationInstance.CompleteRequest();
            }
            catch (HttpException he)
            {
                Global.Logger.ErrorFormat("StreamFile", he);
            }
        }
        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.CDNIvalidationAsync(_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));
        }