public static File GetParams(object fileId, int version, string doc, bool editPossible, bool tryEdit, bool tryCoauth, out Configuration configuration) { File file; var lastVersion = true; FileShare linkRight; using (var fileDao = Global.DaoFactory.GetFileDao()) { linkRight = FileShareLink.Check(doc, fileDao, out file); if (file == null) { var curFile = fileDao.GetFile(fileId); if (curFile != null && 0 < version && version < curFile.Version) { file = fileDao.GetFile(fileId, version); lastVersion = false; } else { file = curFile; } } } return(GetParams(file, lastVersion, linkRight, true, true, editPossible, tryEdit, tryCoauth, out configuration)); }
protected override void OnPreInit(EventArgs e) { base.OnPreInit(e); _valideShareLink = !string.IsNullOrEmpty(FileShareLink.Parse(RequestShareLinkKey)); CheckAuth(); }
public override FileUploadResult ProcessUpload(HttpContext context) { if (!SecurityContext.IsAuthenticated) { throw new HttpException(403, "Access denied."); } var result = new FileUploadResult { Success = false }; try { if (FileToUpload.HasFilesToUpload(context)) { var file = new FileToUpload(context); var maxFileSize = MaxFileSizeInMegabytes * 1024 * 1024; if (string.IsNullOrEmpty(file.FileName)) { throw new ArgumentException("Empty file name"); } if (maxFileSize < file.ContentLength) { throw new Exception(CalendarJSResource.calendarEventAttachments_fileSizeError); } var fileName = System.IO.Path.GetFileName(file.FileName); var document = new File { Title = fileName, FolderID = AttachmentEngine.GetTmpFolderId(), ContentLength = file.ContentLength, ThumbnailStatus = Thumbnail.NotRequired }; document = AttachmentEngine.SaveFile(document, file.InputStream); result.Data = new { id = document.ID.ToString(), title = document.Title, size = document.ContentLength, contentType = file.FileContentType, fileUrl = FileShareLink.GetLink(document) + "&tmp=true" }; result.Success = true; } } catch (Exception ex) { result.Success = false; result.Message = ex.Message; } return(result); }
public File <T> GetParams <T>(T fileId, int version, string doc, bool editPossible, bool tryEdit, bool tryCoauth, out Configuration <T> configuration) { var lastVersion = true; FileShare linkRight; var fileDao = DaoFactory.GetFileDao <T>(); linkRight = FileShareLink.Check(doc, fileDao, out var file); if (file == null) { var curFile = fileDao.GetFile(fileId); if (curFile != null && 0 < version && version < curFile.Version) { file = fileDao.GetFile(fileId, version); lastVersion = false; } else { file = curFile; } } return(GetParams(file, lastVersion, linkRight, true, true, editPossible, tryEdit, tryCoauth, out configuration)); }
protected override void OnPreInit(EventArgs e) { base.OnPreInit(e); _valideShareLink = !string.IsNullOrEmpty(FileShareLink.Parse(RequestShareLinkKey)); CheckAuth(); if (!TenantExtra.GetTenantQuota().DocsEdition) { Response.Redirect(FilesLinkUtility.FileHandlerPath + "?" + Context.Request.QueryString + (string.IsNullOrEmpty(Context.Request[FilesLinkUtility.Action]) ? "&" + FilesLinkUtility.Action + "=view" : string.Empty)); } if (CoreContext.Configuration.PartnerHosted) { var hostedPartner = CoreContext.PaymentManager.GetApprovedPartner(); if (hostedPartner == null || string.IsNullOrEmpty(hostedPartner.AuthorizedKey)) { Response.Redirect(FilesLinkUtility.FileHandlerPath + "?" + Context.Request.QueryString + (string.IsNullOrEmpty(Context.Request[FilesLinkUtility.Action]) ? "&" + FilesLinkUtility.Action + "=view" : string.Empty)); } } if (ItsTry) { SetLanguage(false); } }
public DocumentServiceHelper( IDaoFactory daoFactory, FileShareLink fileShareLink, UserManager userManager, AuthContext authContext, FileSecurity fileSecurity, SetupInfo setupInfo, FileUtility fileUtility, MachinePseudoKeys machinePseudoKeys, Global global, DocumentServiceConnector documentServiceConnector, LockerManager lockerManager, IServiceProvider serviceProvider) { DaoFactory = daoFactory; FileShareLink = fileShareLink; UserManager = userManager; AuthContext = authContext; FileSecurity = fileSecurity; SetupInfo = setupInfo; FileUtility = fileUtility; MachinePseudoKeys = machinePseudoKeys; Global = global; DocumentServiceConnector = documentServiceConnector; LockerManager = lockerManager; ServiceProvider = serviceProvider; }
private void InitScript() { var fileId = Request[FilesLinkUtility.FileId]; File file; try { using (var fileDao = Global.DaoFactory.GetFileDao()) { file = fileDao.GetFile(fileId); } } catch (Exception ex) { Global.Logger.Error("ShareLink", ex); Response.StatusCode = (int)HttpStatusCode.BadRequest; return; } if (file == null) { Response.StatusCode = (int)HttpStatusCode.NotFound; return; } if (!FileSharing.CanSetAccess(file)) { Response.StatusCode = (int)HttpStatusCode.Forbidden; return; } var shareRecord = Global.GetFilesSecurity().GetShares(file).FirstOrDefault(r => r.Subject == FileConstant.ShareLinkId); if (shareRecord == null) { Response.StatusCode = (int)HttpStatusCode.Forbidden; return; } Link = FileShareLink.GetLink(file); if (BitlyLoginProvider.Enabled) { try { Link = BitlyLoginProvider.GetShortenLink(Link); } catch (Exception ex) { Global.Logger.Error("Get shorten link", ex); } } }
protected override void OnPreInit(EventArgs e) { base.OnPreInit(e); _valideShareLink = !string.IsNullOrEmpty(FileShareLink.Parse(RequestShareLinkKey)); CheckAuth(); if (!TenantExtra.GetTenantQuota().DocsEdition) { Response.Redirect(CommonLinkUtility.FileHandlerPath + "?" + Context.Request.QueryString + (string.IsNullOrEmpty(Context.Request[CommonLinkUtility.Action]) ? "&" + CommonLinkUtility.Action + "=view" : string.Empty)); } }
public static File GetParams(object fileId, int version, string shareLinkKey, bool itsNew, bool editPossible, bool tryEdit, out DocumentServiceParams docServiceParams) { File file; var lastVersion = true; var rightToEdit = true; var rightToReview = true; var checkLink = false; using (var fileDao = Global.DaoFactory.GetFileDao()) { var fileShare = FileShareLink.Check(shareLinkKey, fileDao, out file); switch (fileShare) { case FileShare.ReadWrite: checkLink = true; break; case FileShare.Review: rightToEdit = false; checkLink = true; break; case FileShare.Read: editPossible = false; rightToEdit = false; rightToReview = false; checkLink = true; break; } if (file == null) { var curFile = fileDao.GetFile(fileId); if (curFile != null && 0 < version && version < curFile.Version) { file = fileDao.GetFile(fileId, version); lastVersion = false; } else { file = curFile; } } } return(GetParams(file, lastVersion, checkLink, itsNew, editPossible, rightToEdit, rightToReview, tryEdit, out docServiceParams)); }
private static void ProcessEdit(string fileId, TrackerData fileData) { if (ThirdPartySelector.GetAppByFileId(fileId) != null) { return; } var users = FileTracker.GetEditingBy(fileId); var usersDrop = new List <Guid>(); foreach (var user in fileData.Users) { Guid userId; if (!Guid.TryParse(user, out userId)) { Global.Logger.Error("DocService userId is not Guid: " + user); continue; } users.Remove(userId); try { var doc = FileShareLink.CreateKey(fileId); EntryManager.TrackEditing(fileId, userId, userId, doc); } catch (Exception e) { Global.Logger.DebugFormat("Drop command: fileId '{0}' docKey '{1}' for user {2} : {3}", fileId, fileData.Key, user, e.Message); usersDrop.Add(userId); } } if (usersDrop.Any()) { if (!DocumentServiceHelper.DropUser(fileData.Key, usersDrop, fileId)) { Global.Logger.Error("DocService drop failed for users " + string.Join(",", usersDrop)); } } foreach (var removeUserId in users) { FileTracker.Remove(fileId, userId: removeUserId); } Global.SocketManager.FilesChangeEditors(fileId); }
public DocumentServiceTrackerHelper( SecurityContext securityContext, UserManager userManager, TenantManager tenantManager, FilesLinkUtility filesLinkUtility, EmailValidationKeyProvider emailValidationKeyProvider, BaseCommonLinkUtility baseCommonLinkUtility, SocketManager socketManager, GlobalStore globalStore, DisplayUserSettingsHelper displayUserSettingsHelper, IDaoFactory daoFactory, IOptionsMonitor <ILog> options, DocumentServiceHelper documentServiceHelper, EntryManager entryManager, FileShareLink fileShareLink, FilesMessageService filesMessageService, DocumentServiceConnector documentServiceConnector, NotifyClient notifyClient, MailMergeTaskRunner mailMergeTaskRunner, FileTrackerHelper fileTracker) { SecurityContext = securityContext; UserManager = userManager; TenantManager = tenantManager; FilesLinkUtility = filesLinkUtility; EmailValidationKeyProvider = emailValidationKeyProvider; BaseCommonLinkUtility = baseCommonLinkUtility; SocketManager = socketManager; GlobalStore = globalStore; DisplayUserSettingsHelper = displayUserSettingsHelper; DaoFactory = daoFactory; DocumentServiceHelper = documentServiceHelper; EntryManager = entryManager; FileShareLink = fileShareLink; FilesMessageService = filesMessageService; DocumentServiceConnector = documentServiceConnector; NotifyClient = notifyClient; MailMergeTaskRunner = mailMergeTaskRunner; FileTracker = fileTracker; Logger = options.CurrentValue; }
public MailAttachment AttachFileFromDocuments(int id_tenant, string id_user, int id_message, string id_file, string version, string share_link, string id_stream) { MailAttachment result; using (var file_dao = FilesIntegration.GetFileDao()) { Files.Core.File file; var check_link = FileShareLink.Check(share_link, true, file_dao, out file); if (!check_link && file == null) { file = String.IsNullOrEmpty(version) ? file_dao.GetFile(id_file) : file_dao.GetFile(id_file, Convert.ToInt32(version)); } if (file == null) { throw new AttachmentsException(AttachmentsException.Types.DOCUMENT_NOT_FOUND, "File not found."); } if (!check_link && !FilesIntegration.GetFileSecurity().CanRead(file)) { throw new AttachmentsException(AttachmentsException.Types.DOCUMENT_ACCESS_DENIED, "Access denied."); } if (!file_dao.IsExistOnStorage(file)) { throw new AttachmentsException(AttachmentsException.Types.DOCUMENT_NOT_FOUND, "File not exists on storage."); } var file_ext = FileUtility.GetFileExtension(file.Title); var cur_file_type = FileUtility.GetFileTypeByFileName(file.Title); if (file.ConvertedType != null) { if (cur_file_type == FileType.Image) { file_ext = file.ConvertedType == ".zip" ? ".pptt" : file.ConvertedType; } else if (cur_file_type == FileType.Spreadsheet) { file_ext = file.ConvertedType != ".xlsx" ? ".xlst" : file.ConvertedType; } else if (file.ConvertedType == ".doct" || file.ConvertedType == ".xlst" || file.ConvertedType == ".pptt") { file_ext = file.ConvertedType; } } var convert_to_ext = string.Empty; switch (cur_file_type) { case FileType.Document: if (file_ext == ".doct") { convert_to_ext = ".docx"; } break; case FileType.Spreadsheet: if (file_ext == ".xlst") { convert_to_ext = ".xlsx"; } break; case FileType.Presentation: if (file_ext == ".pptt") { convert_to_ext = ".pptx"; } break; } if (!string.IsNullOrEmpty(convert_to_ext) && file_ext != convert_to_ext) { var file_name = Path.ChangeExtension(file.Title, convert_to_ext); using (var read_stream = FileConverter.Exec(file, convert_to_ext)) { if (read_stream != null) { using (var mem_stream = new MemoryStream()) { read_stream.StreamCopyTo(mem_stream); result = AttachFile(id_tenant, id_user, id_message, file_name, mem_stream, id_stream); } } else { throw new AttachmentsException(AttachmentsException.Types.DOCUMENT_ACCESS_DENIED, "Access denied."); } } } else { using (var read_stream = file_dao.GetFileStream(file)) { if (read_stream != null) { result = AttachFile(id_tenant, id_user, id_message, file.Title, read_stream, id_stream); } else { throw new AttachmentsException(AttachmentsException.Types.DOCUMENT_ACCESS_DENIED, "Access denied."); } } } } return(result); }
public static void ProcessData(string fileId, bool isNew, string trackDataString) { if (string.IsNullOrEmpty(trackDataString)) { Global.Logger.Error("DocService return null"); throw new ArgumentException("DocService return null", "trackDataString"); } var data = JObject.Parse(trackDataString); if (data == null) { Global.Logger.Error("DocService response is incorrect"); throw new ArgumentException("DocService response is incorrect", "trackDataString"); } var fileData = data.ToObject <TrackerData>(); var userId = Guid.Empty; switch (fileData.Status) { case TrackerStatus.NotFound: case TrackerStatus.Closed: FileTracker.Remove(fileId); break; case TrackerStatus.Editing: var users = FileTracker.GetEditingBy(fileId); foreach (var user in fileData.Users) { if (!Guid.TryParse(user, out userId)) { Global.Logger.Error("DocService userId is not Guid: " + user); continue; } users.Remove(userId); try { var shareLinkKey = FileShareLink.CreateKey(fileId); EntryManager.TrackEditing(fileId, userId, userId, isNew, shareLinkKey); } catch (Exception e) { Global.Logger.DebugFormat("DocService drop fileId '{0}' docKey '{1}' for user {2} : {3}", fileId, fileData.Key, user, e.Message); if (!Drop(fileData.Key, user, fileId)) { Global.Logger.Error("DocService drop failed for user " + user); } } } foreach (var removeUserId in users) { FileTracker.Remove(fileId, userId: removeUserId); } break; case TrackerStatus.MustSave: case TrackerStatus.Corrupted: if (fileData.Users != null && fileData.Users.Count > 0) { Guid.TryParse(fileData.Users[0], out userId); } SecurityContext.AuthenticateMe(userId); try { var file = EntryManager.SaveEditing(fileId, -1, userId, fileData.Url, isNew, string.Empty, fileData.Status == TrackerStatus.Corrupted ? FilesCommonResource.ErrorMassage_SaveCorrupted : String.Empty, false); var user = CoreContext.UserManager.GetUsers(userId); if (file != null && user != null) { FilesMessageService.Send(file, MessageInitiator.DocsService, MessageAction.UserFileUpdated, user.DisplayUserName(false), file.Title); } } catch (Exception ex) { Global.Logger.Error(string.Format("DocService save error. File id: '{0}'. UserId: {1}. DocKey '{2}'. DownloadUri: {3}", fileId, userId, fileData.Key, fileData.Url), ex); StoringFileAfterError(fileId, userId.ToString(), fileData.Url); } FileTracker.Remove(fileId); break; } }
private static void ProcessEdit(string fileId, TrackerData fileData) { if (ThirdPartySelector.GetAppByFileId(fileId) != null) { return; } var users = FileTracker.GetEditingBy(fileId); var usersDrop = new List <string>(); string docKey; var app = ThirdPartySelector.GetAppByFileId(fileId); if (app == null) { File fileStable; using (var fileDao = Global.DaoFactory.GetFileDao()) { fileStable = fileDao.GetFileStable(fileId); } docKey = DocumentServiceHelper.GetDocKey(fileStable); } else { docKey = fileData.Key; } if (!fileData.Key.Equals(docKey)) { Global.Logger.InfoFormat("DocService editing file {0} ({1}) with key {2} for {3}", fileId, docKey, fileData.Key, string.Join(", ", fileData.Users)); usersDrop = fileData.Users; } else { foreach (var user in fileData.Users) { Guid userId; if (!Guid.TryParse(user, out userId)) { Global.Logger.Error("DocService userId is not Guid: " + user); continue; } users.Remove(userId); try { var doc = FileShareLink.CreateKey(fileId); EntryManager.TrackEditing(fileId, userId, userId, doc); } catch (Exception e) { Global.Logger.DebugFormat("Drop command: fileId '{0}' docKey '{1}' for user {2} : {3}", fileId, fileData.Key, user, e.Message); usersDrop.Add(userId.ToString()); } } } if (usersDrop.Any()) { if (!DocumentServiceHelper.DropUser(fileData.Key, usersDrop.ToArray(), fileId)) { Global.Logger.Error("DocService drop failed for users " + string.Join(",", usersDrop)); } } foreach (var removeUserId in users) { FileTracker.Remove(fileId, userId: removeUserId); } Global.SocketManager.FilesChangeEditors(fileId); }
private static void DownloadFile(HttpContext context, bool inline) { if (!string.IsNullOrEmpty(context.Request[CommonLinkUtility.TryParam])) { DownloadTry(context); return; } try { var id = context.Request[CommonLinkUtility.FileId]; var shareLinkKey = context.Request[CommonLinkUtility.DocShareKey] ?? ""; using (var fileDao = Global.DaoFactory.GetFileDao()) { File file; var checkLink = FileShareLink.Check(shareLinkKey, true, fileDao, out file); if (!checkLink && file == null) { int version; file = int.TryParse(context.Request[CommonLinkUtility.Version], out version) && version > 0 ? fileDao.GetFile(id, version) : fileDao.GetFile(id); } if (file == null) { context.Response.Redirect("~/404.htm"); return; } if (!checkLink && !Global.GetFilesSecurity().CanRead(file)) { context.Response.Redirect((context.Request.UrlReferrer != null ? context.Request.UrlReferrer.ToString() : PathProvider.StartURL) + "#" + UrlConstant.Error + "/" + HttpUtility.UrlEncode(FilesCommonResource.ErrorMassage_SecurityException_ReadFile)); return; } if (!fileDao.IsExistOnStorage(file)) { Global.Logger.ErrorFormat("Download file error. File is not exist on storage. File id: {0}.", file.ID); context.Response.Redirect("~/404.htm"); return; } FileMarker.RemoveMarkAsNew(file); context.Response.Clear(); context.Response.ContentType = MimeMapping.GetMimeMapping(file.Title); context.Response.Charset = "utf-8"; var browser = context.Request.Browser.Browser; var title = file.Title.Replace(',', '_'); var ext = FileUtility.GetFileExtension(file.Title); var outType = string.Empty; var curQuota = TenantExtra.GetTenantQuota(); if (curQuota.DocsEdition || FileUtility.InternalExtension.Values.Contains(ext)) { outType = context.Request[CommonLinkUtility.OutType]; } if (!string.IsNullOrEmpty(outType) && !inline) { outType = outType.Trim(); if (FileUtility.ExtsConvertible[ext].Contains(outType)) { ext = outType; title = FileUtility.ReplaceFileExtension(title, ext); } } context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(title, inline)); if (inline && string.Equals(context.Request.Headers["If-None-Match"], GetEtag(file))) { //Its cached. Reply 304 context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.Cache.SetETag(GetEtag(file)); } else { context.Response.CacheControl = "public"; context.Response.Cache.SetETag(GetEtag(file)); context.Response.Cache.SetCacheability(HttpCacheability.Public); Stream fileStream = null; try { if (file.ContentLength <= SetupInfo.AvailableFileSize) { if (file.ConvertedType == null && (string.IsNullOrEmpty(outType) || inline)) { context.Response.AddHeader("Content-Length", file.ContentLength.ToString(CultureInfo.InvariantCulture)); if (fileDao.IsSupportedPreSignedUri(file)) { context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true); return; } fileStream = fileDao.GetFileStream(file); } else { fileStream = FileConverter.Exec(file, ext); } fileStream.StreamCopyTo(context.Response.OutputStream); if (!context.Response.IsClientConnected) { Global.Logger.Error(String.Format("Download file error {0} {1} Connection is lost. Too long to buffer the file", file.Title, file.ID)); } context.Response.Flush(); } else { long offset = 0; if (context.Request.Headers["Range"] != null) { context.Response.StatusCode = 206; var range = context.Request.Headers["Range"].Split(new[] { '=', '-' }); offset = Convert.ToInt64(range[1]); } if (offset > 0) { Global.Logger.Info("Starting file download offset is " + offset); } context.Response.AddHeader("Connection", "Keep-Alive"); context.Response.AddHeader("Accept-Ranges", "bytes"); if (offset > 0) { context.Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", offset, file.ContentLength - 1, file.ContentLength)); } var dataToRead = file.ContentLength; const int bufferSize = 1024; var buffer = new Byte[bufferSize]; if (file.ConvertedType == null && (string.IsNullOrEmpty(outType) || inline)) { if (fileDao.IsSupportedPreSignedUri(file)) { context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true); return; } fileStream = fileDao.GetFileStream(file, offset); context.Response.AddHeader("Content-Length", (file.ContentLength - offset).ToString(CultureInfo.InvariantCulture)); } else { fileStream = FileConverter.Exec(file, ext); if (offset > 0) { var startBytes = offset; while (startBytes > 0) { long readCount; if (bufferSize >= startBytes) { readCount = startBytes; } else { readCount = bufferSize; } var length = fileStream.Read(buffer, 0, (int)readCount); startBytes -= length; } } } while (dataToRead > 0) { int length; try { length = fileStream.Read(buffer, 0, bufferSize); } catch (HttpException exception) { Global.Logger.Error( String.Format("Read from stream is error. Download file {0} {1}. Maybe Connection is lost.?? Error is {2} ", file.Title, file.ID, exception )); throw; } if (context.Response.IsClientConnected) { context.Response.OutputStream.Write(buffer, 0, length); dataToRead = dataToRead - length; } else { dataToRead = -1; Global.Logger.Error(String.Format("IsClientConnected is false. Why? Download file {0} {1} Connection is lost. ", file.Title, file.ID)); } } } } catch (HttpException e) { throw new HttpException((int)HttpStatusCode.BadRequest, e.Message); } finally { if (fileStream != null) { fileStream.Flush(); fileStream.Close(); fileStream.Dispose(); } } try { context.Response.End(); } catch (HttpException) { } } } } catch (Exception ex) { // Get stack trace for the exception with source file information var st = new StackTrace(ex, true); // Get the top stack frame var frame = st.GetFrame(0); // Get the line number from the stack frame var line = frame.GetFileLineNumber(); Global.Logger.ErrorFormat("Url: {0} {1} IsClientConnected:{2}, line number:{3} frame:{4}", context.Request.Url, ex, context.Response.IsClientConnected, line, frame); context.Response.StatusCode = 400; context.Response.Write(HttpUtility.HtmlEncode(ex.Message)); } }
private static void SaveFile(HttpContext context) { try { var shareLinkKey = context.Request[CommonLinkUtility.DocShareKey] ?? ""; var fileID = context.Request[CommonLinkUtility.FileId]; if (string.IsNullOrEmpty(fileID)) { throw new ArgumentNullException(fileID); } var downloadUri = context.Request[CommonLinkUtility.FileUri]; if (string.IsNullOrEmpty(downloadUri)) { throw new ArgumentNullException(downloadUri); } using (var fileDao = Global.DaoFactory.GetFileDao()) { File file; var checkLink = FileShareLink.Check(shareLinkKey, false, fileDao, out file); if (!checkLink && file == null) { file = fileDao.GetFile(fileID); } if (file == null) { throw new HttpException((int)HttpStatusCode.NotFound, FilesCommonResource.ErrorMassage_FileNotFound); } if (!checkLink && (!Global.GetFilesSecurity().CanEdit(file) || CoreContext.UserManager.GetUsers(SecurityContext.CurrentAccount.ID).IsVisitor())) { throw new SecurityException(FilesCommonResource.ErrorMassage_SecurityException_EditFile); } if (file.RootFolderType == FolderType.TRASH) { throw new HttpException((int)HttpStatusCode.Forbidden, FilesCommonResource.ErrorMassage_ViewTrashItem); } var versionEdit = context.Request[CommonLinkUtility.Version]; var currentType = file.ConvertedType ?? FileUtility.GetFileExtension(file.Title); var newType = FileUtility.GetFileExtension(downloadUri); var updateVersion = file.Version > 1 || file.ConvertedType == null || string.IsNullOrEmpty(context.Request[UrlConstant.New]); if ((string.IsNullOrEmpty(versionEdit) || file.Version <= Convert.ToInt32(versionEdit) || currentType != newType) && updateVersion && !FileLocker.LockVersion(file.ID)) { file.Version++; } file.ConvertedType = newType; if (file.ProviderEntry && !newType.Equals(currentType)) { var key = DocumentServiceConnector.GenerateRevisionId(downloadUri); DocumentServiceConnector.GetConvertedUri(downloadUri, newType, currentType, key, false, out downloadUri); } var req = (HttpWebRequest)WebRequest.Create(downloadUri); using (var editedFileStream = new ResponseStream(req.GetResponse())) { file.ContentLength = editedFileStream.Length; file = fileDao.SaveFile(file, editedFileStream); } bool checkRight; var tabId = new Guid(context.Request["tabId"]); FileLocker.ProlongLock(file.ID, tabId, true, out checkRight); if (checkRight) { FileLocker.ChangeRight(file.ID, SecurityContext.CurrentAccount.ID, false); } FileMarker.MarkAsNew(file); FileMarker.RemoveMarkAsNew(file); } } catch (Exception ex) { Global.Logger.Error(ex.Message, ex); context.Response.Write("{ \"error\": \"true\", \"message\": \"" + ex.Message + "\" }"); } }
public static void ProcessData(string fileId, bool isNew, string trackDataString) { if (string.IsNullOrEmpty(trackDataString)) { throw new ArgumentException("DocService return null"); } var data = JObject.Parse(trackDataString); if (data == null) { throw new ArgumentException("DocService response is incorrect"); } var fileData = data.ToObject <TrackerData>(); Guid userId; switch (fileData.Status) { case TrackerStatus.NotFound: case TrackerStatus.Closed: FileTracker.Remove(fileId); break; case TrackerStatus.Editing: if (ThirdPartySelector.GetAppByFileId(fileId) != null) { break; } var users = FileTracker.GetEditingBy(fileId); var usersDrop = new List <string>(); foreach (var user in fileData.Users) { if (!Guid.TryParse(user, out userId)) { Global.Logger.Error("DocService userId is not Guid: " + user); continue; } users.Remove(userId); try { var shareLinkKey = FileShareLink.CreateKey(fileId); EntryManager.TrackEditing(fileId, userId, userId, isNew, shareLinkKey); } catch (Exception e) { Global.Logger.DebugFormat("Drop command: fileId '{0}' docKey '{1}' for user {2} : {3}", fileId, fileData.Key, user, e.Message); usersDrop.Add(user); } } if (usersDrop.Any()) { var dropString = "[\"" + string.Join("\",\"", usersDrop) + "\"]"; if (!Drop(fileData.Key, dropString, fileId)) { Global.Logger.Error("DocService drop failed for users " + dropString); } } foreach (var removeUserId in users) { FileTracker.Remove(fileId, userId: removeUserId); } break; case TrackerStatus.MustSave: case TrackerStatus.Corrupted: var comments = new List <string>(); if (fileData.Status == TrackerStatus.Corrupted) { comments.Add(FilesCommonResource.ErrorMassage_SaveCorrupted); } if (fileData.Users == null || fileData.Users.Count == 0 || !Guid.TryParse(fileData.Users[0], out userId)) { userId = FileTracker.GetEditingBy(fileId).FirstOrDefault(); } try { SecurityContext.AuthenticateMe(userId); } catch (Exception ex) { Global.Logger.Warn("DocService save error: anonymous author - " + userId, ex); if (!userId.Equals(ASC.Core.Configuration.Constants.Guest.ID)) { comments.Add(FilesCommonResource.ErrorMassage_SaveAnonymous); } } File file = null; var saved = false; if (string.IsNullOrEmpty(fileData.Url)) { try { comments.Add(FilesCommonResource.ErrorMassage_SaveUrlLost); FileTracker.Remove(fileId); file = EntryManager.CompleteVersionFile(fileId, 0, false, false); using (var fileDao = Global.DaoFactory.GetFileDao()) { fileDao.UpdateComment(file.ID, file.Version, string.Join("; ", comments)); } } catch (Exception ex) { Global.Logger.Error(string.Format("DocService save error. Version update. File id: '{0}'. UserId: {1}. DocKey '{2}'", fileId, userId, fileData.Key), ex); } } else { try { file = EntryManager.SaveEditing(fileId, -1, userId, fileData.Url, isNew, string.Empty, string.Join("; ", comments), false); saved = fileData.Status == TrackerStatus.MustSave; } catch (Exception ex) { Global.Logger.Error(string.Format("DocService save error. File id: '{0}'. UserId: {1}. DocKey '{2}'. DownloadUri: {3}", fileId, userId, fileData.Key, fileData.Url), ex); StoringFileAfterError(fileId, userId.ToString(), fileData.Url); } } if (file != null) { var user = CoreContext.UserManager.GetUsers(userId); if (user != null) { FilesMessageService.Send(file, MessageInitiator.DocsService, MessageAction.UserFileUpdated, user.DisplayUserName(false), file.Title); } SaveHistory(file, fileData.ChangesHistory, fileData.ChangesUrl); } FileTracker.Remove(fileId); Command(TrackMethod.Saved, fileData.Key, fileId, null, userId.ToString(), saved ? "1" : "0"); break; } }
private static void DownloadFile(HttpContext context) { var flushed = false; try { var id = context.Request[FilesLinkUtility.FileId]; var doc = context.Request[FilesLinkUtility.DocShareKey] ?? ""; using (var fileDao = Global.DaoFactory.GetFileDao()) { File file; var readLink = FileShareLink.Check(doc, true, fileDao, out file); if (!readLink && file == null) { fileDao.InvalidateCache(id); int version; file = int.TryParse(context.Request[FilesLinkUtility.Version], out version) && version > 0 ? fileDao.GetFile(id, version) : fileDao.GetFile(id); } if (file == null) { context.Response.StatusCode = (int)HttpStatusCode.NotFound; return; } if (!readLink && !Global.GetFilesSecurity().CanRead(file)) { context.Response.StatusCode = (int)HttpStatusCode.Forbidden; return; } if (!string.IsNullOrEmpty(file.Error)) { throw new Exception(file.Error); } if (!fileDao.IsExistOnStorage(file)) { Global.Logger.ErrorFormat("Download file error. File is not exist on storage. File id: {0}.", file.ID); context.Response.StatusCode = (int)HttpStatusCode.NotFound; return; } FileMarker.RemoveMarkAsNew(file); context.Response.Clear(); context.Response.ClearHeaders(); context.Response.Charset = "utf-8"; var title = file.Title.Replace(',', '_'); var ext = FileUtility.GetFileExtension(file.Title); var outType = context.Request[FilesLinkUtility.OutType]; if (!string.IsNullOrEmpty(outType)) { outType = outType.Trim(); if (FileUtility.ExtsConvertible[ext].Contains(outType)) { ext = outType; title = FileUtility.ReplaceFileExtension(title, ext); } } context.Response.AddHeader("Content-Disposition", ContentDispositionUtil.GetHeaderValue(title)); context.Response.ContentType = MimeMapping.GetMimeMapping(title); //// Download file via nginx //if (CoreContext.Configuration.Standalone && // WorkContext.IsMono && // Global.GetStore() is DiscDataStore && // !file.ProviderEntry && // !FileConverter.EnableConvert(file, ext) // ) //{ // var diskDataStore = (DiscDataStore)Global.GetStore(); // var pathToFile = diskDataStore.GetPhysicalPath(String.Empty, FileDao.GetUniqFilePath(file)); // context.Response.Headers.Add("X-Accel-Redirect", "/filesData" + pathToFile); // FilesMessageService.Send(file, context.Request, MessageAction.FileDownloaded, file.Title); // return; //} if (string.Equals(context.Request.Headers["If-None-Match"], GetEtag(file))) { //Its cached. Reply 304 context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.Cache.SetETag(GetEtag(file)); } else { context.Response.CacheControl = "public"; context.Response.Cache.SetETag(GetEtag(file)); context.Response.Cache.SetCacheability(HttpCacheability.Public); Stream fileStream = null; try { if (file.ContentLength <= SetupInfo.AvailableFileSize) { if (!FileConverter.EnableConvert(file, ext)) { if (!readLink && fileDao.IsSupportedPreSignedUri(file)) { context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true); return; } fileStream = fileDao.GetFileStream(file); context.Response.AddHeader("Content-Length", file.ContentLength.ToString(CultureInfo.InvariantCulture)); } else { fileStream = FileConverter.Exec(file, ext); context.Response.AddHeader("Content-Length", fileStream.Length.ToString(CultureInfo.InvariantCulture)); } fileStream.StreamCopyTo(context.Response.OutputStream); if (!context.Response.IsClientConnected) { Global.Logger.Warn(String.Format("Download file error {0} {1} Connection is lost. Too long to buffer the file", file.Title, file.ID)); } FilesMessageService.Send(file, context.Request, MessageAction.FileDownloaded, file.Title); context.Response.Flush(); flushed = true; } else { context.Response.Buffer = false; context.Response.ContentType = "application/octet-stream"; long offset = 0; if (context.Request.Headers["Range"] != null) { context.Response.StatusCode = 206; var range = context.Request.Headers["Range"].Split(new[] { '=', '-' }); offset = Convert.ToInt64(range[1]); } if (offset > 0) { Global.Logger.Info("Starting file download offset is " + offset); } context.Response.AddHeader("Connection", "Keep-Alive"); context.Response.AddHeader("Accept-Ranges", "bytes"); if (offset > 0) { context.Response.AddHeader("Content-Range", String.Format(" bytes {0}-{1}/{2}", offset, file.ContentLength - 1, file.ContentLength)); } var dataToRead = file.ContentLength; const int bufferSize = 8 * 1024; // 8KB var buffer = new Byte[bufferSize]; if (!FileConverter.EnableConvert(file, ext)) { if (!readLink && fileDao.IsSupportedPreSignedUri(file)) { context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true); return; } fileStream = fileDao.GetFileStream(file, offset); context.Response.AddHeader("Content-Length", (file.ContentLength - offset).ToString(CultureInfo.InvariantCulture)); } else { fileStream = FileConverter.Exec(file, ext); if (offset > 0) { var startBytes = offset; while (startBytes > 0) { long readCount; if (bufferSize >= startBytes) { readCount = startBytes; } else { readCount = bufferSize; } var length = fileStream.Read(buffer, 0, (int)readCount); startBytes -= length; } } } while (dataToRead > 0) { int length; try { length = fileStream.Read(buffer, 0, bufferSize); } catch (HttpException exception) { Global.Logger.Error( String.Format("Read from stream is error. Download file {0} {1}. Maybe Connection is lost.?? Error is {2} ", file.Title, file.ID, exception )); throw; } if (context.Response.IsClientConnected) { context.Response.OutputStream.Write(buffer, 0, length); context.Response.Flush(); flushed = true; dataToRead = dataToRead - length; } else { dataToRead = -1; Global.Logger.Warn(String.Format("IsClientConnected is false. Why? Download file {0} {1} Connection is lost. ", file.Title, file.ID)); } } } } catch (ThreadAbortException) { } catch (HttpException e) { throw new HttpException((int)HttpStatusCode.BadRequest, e.Message); } finally { if (fileStream != null) { fileStream.Close(); fileStream.Dispose(); } } try { context.Response.End(); flushed = true; } catch (HttpException) { } } } } catch (ThreadAbortException) { } catch (Exception ex) { // Get stack trace for the exception with source file information var st = new StackTrace(ex, true); // Get the top stack frame var frame = st.GetFrame(0); // Get the line number from the stack frame var line = frame.GetFileLineNumber(); Global.Logger.ErrorFormat("Url: {0} {1} IsClientConnected:{2}, line number:{3} frame:{4}", context.Request.Url, ex, context.Response.IsClientConnected, line, frame); if (!flushed && context.Response.IsClientConnected) { context.Response.StatusCode = 400; context.Response.Write(HttpUtility.HtmlEncode(ex.Message)); } } }
public MailAttachment AttachFileFromDocuments(int tenant, string user, int messageId, string fileId, string version, string shareLink) { MailAttachment result; using (var fileDao = FilesIntegration.GetFileDao()) { File file; var checkLink = FileShareLink.Check(shareLink, true, fileDao, out file); if (!checkLink && file == null) { file = string.IsNullOrEmpty(version) ? fileDao.GetFile(fileId) : fileDao.GetFile(fileId, Convert.ToInt32(version)); } if (file == null) { throw new AttachmentsException(AttachmentsException.Types.DocumentNotFound, "File not found."); } if (!checkLink && !FilesIntegration.GetFileSecurity().CanRead(file)) { throw new AttachmentsException(AttachmentsException.Types.DocumentAccessDenied, "Access denied."); } if (!fileDao.IsExistOnStorage(file)) { throw new AttachmentsException(AttachmentsException.Types.DocumentNotFound, "File not exists on storage."); } _log.Info("Original file id: {0}", file.ID); _log.Info("Original file name: {0}", file.Title); var fileExt = FileUtility.GetFileExtension(file.Title); var curFileType = FileUtility.GetFileTypeByFileName(file.Title); _log.Info("File converted type: {0}", file.ConvertedType); if (file.ConvertedType != null) { switch (curFileType) { case FileType.Image: fileExt = file.ConvertedType == ".zip" ? ".pptt" : file.ConvertedType; break; case FileType.Spreadsheet: fileExt = file.ConvertedType != ".xlsx" ? ".xlst" : file.ConvertedType; break; default: if (file.ConvertedType == ".doct" || file.ConvertedType == ".xlst" || file.ConvertedType == ".pptt") { fileExt = file.ConvertedType; } break; } } var convertToExt = string.Empty; switch (curFileType) { case FileType.Document: if (fileExt == ".doct") { convertToExt = ".docx"; } break; case FileType.Spreadsheet: if (fileExt == ".xlst") { convertToExt = ".xlsx"; } break; case FileType.Presentation: if (fileExt == ".pptt") { convertToExt = ".pptx"; } break; } if (!string.IsNullOrEmpty(convertToExt) && fileExt != convertToExt) { var fileName = Path.ChangeExtension(file.Title, convertToExt); _log.Info("Changed file name - {0} for file {1}:", fileName, file.ID); using (var readStream = FileConverter.Exec(file, convertToExt)) { if (readStream == null) { throw new AttachmentsException(AttachmentsException.Types.DocumentAccessDenied, "Access denied."); } using (var memStream = new MemoryStream()) { readStream.StreamCopyTo(memStream); result = AttachFile(tenant, user, messageId, fileName, memStream); _log.Info("Attached attachment: ID - {0}, Name - {1}, StoredUrl - {2}", result.fileName, result.fileName, result.storedFileUrl); } } } else { using (var readStream = fileDao.GetFileStream(file)) { if (readStream == null) { throw new AttachmentsException(AttachmentsException.Types.DocumentAccessDenied, "Access denied."); } result = AttachFile(tenant, user, messageId, file.Title, readStream); _log.Info("Attached attachment: ID - {0}, Name - {1}, StoredUrl - {2}", result.fileName, result.fileName, result.storedFileUrl); } } } return(result); }
public override FileUploadResult ProcessUpload(HttpContext context) { var log = LogManager.GetLogger("ASC.Mail.FilesUploader"); string message; var fileName = string.Empty; MailAttachmentData mailAttachmentData = null; try { if (!FileToUpload.HasFilesToUpload(context)) { throw new Exception(MailScriptResource.AttachmentsBadInputParamsError); } if (!SecurityContext.IsAuthenticated) { throw new HttpException(403, "Access denied."); } Thread.CurrentThread.CurrentCulture = CurrentCulture; Thread.CurrentThread.CurrentUICulture = CurrentCulture; var mailId = Convert.ToInt32(context.Request["messageId"]); var copyToMy = Convert.ToInt32(context.Request["copyToMy"]); var needSaveToTemp = Convert.ToBoolean(context.Request["needSaveToTemp"]); if (mailId < 1) { throw new AttachmentsException(AttachmentsException.Types.MessageNotFound, "Message not yet saved!"); } var engine = new EngineFactory(TenantId, Username); var item = engine.MessageEngine.GetMessage(mailId, new MailMessageData.Options()); if (item == null) { throw new AttachmentsException(AttachmentsException.Types.MessageNotFound, "Message not found."); } if (string.IsNullOrEmpty(item.StreamId)) { throw new AttachmentsException(AttachmentsException.Types.BadParams, "Have no stream"); } var postedFile = new FileToUpload(context); fileName = context.Request["name"]; if (string.IsNullOrEmpty(fileName)) { throw new AttachmentsException(AttachmentsException.Types.BadParams, "Empty name param"); } if (copyToMy == 1) { var uploadedFile = FileUploader.Exec(Global.FolderMy.ToString(), fileName, postedFile.ContentLength, postedFile.InputStream, true); return(new FileUploadResult { Success = true, FileName = uploadedFile.Title, FileURL = FileShareLink.GetLink(uploadedFile, false), Data = new MailAttachmentData { fileId = Convert.ToInt32(uploadedFile.ID), fileName = uploadedFile.Title, size = uploadedFile.ContentLength, contentType = uploadedFile.ConvertedType, attachedAsLink = true, tenant = TenantId, user = Username } }); } mailAttachmentData = engine.AttachmentEngine .AttachFileToDraft(TenantId, Username, mailId, fileName, postedFile.InputStream, postedFile.ContentLength, null, postedFile.NeedSaveToTemp); return(new FileUploadResult { Success = true, FileName = mailAttachmentData.fileName, FileURL = mailAttachmentData.storedFileUrl, Data = mailAttachmentData }); } catch (HttpException he) { log.Error("FileUpload handler failed", he); context.Response.StatusCode = he.GetHttpCode(); message = he.Message != null ? HttpUtility.HtmlEncode(he.Message) : MailApiErrorsResource.ErrorInternalServer; } catch (AttachmentsException ex) { log.Error("FileUpload handler failed", ex); switch (ex.ErrorType) { case AttachmentsException.Types.BadParams: message = MailScriptResource.AttachmentsBadInputParamsError; break; case AttachmentsException.Types.EmptyFile: message = MailScriptResource.AttachmentsEmptyFileNotSupportedError; break; case AttachmentsException.Types.MessageNotFound: message = MailScriptResource.AttachmentsMessageNotFoundError; break; case AttachmentsException.Types.TotalSizeExceeded: message = MailScriptResource.AttachmentsTotalLimitError; break; case AttachmentsException.Types.DocumentNotFound: message = MailScriptResource.AttachmentsDocumentNotFoundError; break; case AttachmentsException.Types.DocumentAccessDenied: message = MailScriptResource.AttachmentsDocumentAccessDeniedError; break; default: message = MailScriptResource.AttachmentsUnknownError; break; } } catch (TenantQuotaException ex) { log.Error("FileUpload handler failed", ex); message = ex.Message; } catch (Exception ex) { log.Error("FileUpload handler failed", ex); message = MailScriptResource.AttachmentsUnknownError; } return(new FileUploadResult { Success = false, FileName = fileName, Data = mailAttachmentData, Message = string.IsNullOrEmpty(message) ? MailApiErrorsResource.ErrorInternalServer : message }); }
public static string GetUriString(File file) { return(FileShareLink.GetLink(file)); }
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 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); } }
private static void DownloadFile(HttpContext context) { var flushed = false; try { var id = context.Request[FilesLinkUtility.FileId]; var doc = context.Request[FilesLinkUtility.DocShareKey] ?? ""; using (var fileDao = Global.DaoFactory.GetFileDao()) { File file; var readLink = FileShareLink.Check(doc, true, fileDao, out file); if (!readLink && file == null) { fileDao.InvalidateCache(id); int version; file = int.TryParse(context.Request[FilesLinkUtility.Version], out version) && version > 0 ? fileDao.GetFile(id, version) : fileDao.GetFile(id); } if (file == null) { context.Response.StatusCode = (int)HttpStatusCode.NotFound; return; } if (!readLink && !Global.GetFilesSecurity().CanRead(file)) { context.Response.StatusCode = (int)HttpStatusCode.Forbidden; return; } if (!string.IsNullOrEmpty(file.Error)) { throw new Exception(file.Error); } if (!fileDao.IsExistOnStorage(file)) { Global.Logger.ErrorFormat("Download file error. File is not exist on storage. File id: {0}.", file.ID); context.Response.StatusCode = (int)HttpStatusCode.NotFound; return; } FileMarker.RemoveMarkAsNew(file); context.Response.Clear(); context.Response.ClearHeaders(); context.Response.Charset = "utf-8"; FilesMessageService.Send(file, context.Request, MessageAction.FileDownloaded, file.Title); if (string.Equals(context.Request.Headers["If-None-Match"], GetEtag(file))) { //Its cached. Reply 304 context.Response.StatusCode = (int)HttpStatusCode.NotModified; context.Response.Cache.SetETag(GetEtag(file)); } else { context.Response.CacheControl = "public"; context.Response.Cache.SetETag(GetEtag(file)); context.Response.Cache.SetCacheability(HttpCacheability.Public); Stream fileStream = null; try { var title = file.Title; if (file.ContentLength <= SetupInfo.AvailableFileSize) { var ext = FileUtility.GetFileExtension(file.Title); var outType = (context.Request[FilesLinkUtility.OutType] ?? "").Trim(); if (!string.IsNullOrEmpty(outType) && FileUtility.ExtsConvertible.Keys.Contains(ext) && FileUtility.ExtsConvertible[ext].Contains(outType)) { ext = outType; } long offset = 0; long length; if (!file.ProviderEntry && string.Equals(context.Request["convpreview"], "true", StringComparison.InvariantCultureIgnoreCase) && FFmpegService.IsConvertable(ext)) { const string mp4Name = "content.mp4"; var mp4Path = FileDao.GetUniqFilePath(file, mp4Name); var store = Global.GetStore(); if (!store.IsFile(mp4Path)) { fileStream = fileDao.GetFileStream(file); Global.Logger.InfoFormat("Converting {0} (fileId: {1}) to mp4", file.Title, file.ID); var stream = FFmpegService.Convert(fileStream, ext); store.Save(string.Empty, mp4Path, stream, mp4Name); } var fullLength = store.GetFileSize(string.Empty, mp4Path); length = ProcessRangeHeader(context, fullLength, ref offset); fileStream = store.GetReadStream(string.Empty, mp4Path, (int)offset); title = FileUtility.ReplaceFileExtension(title, ".mp4"); } else { if (!FileConverter.EnableConvert(file, ext)) { if (!readLink && fileDao.IsSupportedPreSignedUri(file)) { context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true); return; } fileStream = fileDao.GetFileStream(file); // getStream to fix file.ContentLength if (fileStream.CanSeek) { var fullLength = file.ContentLength; length = ProcessRangeHeader(context, fullLength, ref offset); fileStream.Seek(offset, SeekOrigin.Begin); } else { length = file.ContentLength; } } else { title = FileUtility.ReplaceFileExtension(title, ext); fileStream = FileConverter.Exec(file, ext); length = fileStream.Length; } } SendStreamByChunks(context, length, title, fileStream, ref flushed); } else { if (!readLink && fileDao.IsSupportedPreSignedUri(file)) { context.Response.Redirect(fileDao.GetPreSignedUri(file, TimeSpan.FromHours(1)).ToString(), true); return; } fileStream = fileDao.GetFileStream(file); // getStream to fix file.ContentLength long offset = 0; var length = file.ContentLength; if (fileStream.CanSeek) { length = ProcessRangeHeader(context, file.ContentLength, ref offset); fileStream.Seek(offset, SeekOrigin.Begin); } SendStreamByChunks(context, length, title, fileStream, ref flushed); } } catch (ThreadAbortException tae) { Global.Logger.Error("DownloadFile", tae); } catch (HttpException e) { Global.Logger.Error("DownloadFile", e); throw new HttpException((int)HttpStatusCode.BadRequest, e.Message); } finally { if (fileStream != null) { fileStream.Close(); fileStream.Dispose(); } } try { context.Response.Flush(); context.Response.SuppressContent = true; context.ApplicationInstance.CompleteRequest(); flushed = true; } catch (HttpException ex) { Global.Logger.Error("DownloadFile", ex); } } } } catch (ThreadAbortException tae) { Global.Logger.Error("DownloadFile", tae); } catch (Exception ex) { // Get stack trace for the exception with source file information var st = new StackTrace(ex, true); // Get the top stack frame var frame = st.GetFrame(0); // Get the line number from the stack frame var line = frame.GetFileLineNumber(); Global.Logger.ErrorFormat("Url: {0} {1} IsClientConnected:{2}, line number:{3} frame:{4}", context.Request.Url, ex, context.Response.IsClientConnected, line, frame); if (!flushed && context.Response.IsClientConnected) { context.Response.StatusCode = 400; context.Response.Write(HttpUtility.HtmlEncode(ex.Message)); } } }