Exemple #1
0
        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));
        }
        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));
        }
Exemple #3
0
        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));
        }
Exemple #4
0
        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);
        }
Exemple #6
0
        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);
        }
        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));
                }
            }
        }
Exemple #10
0
        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 + "\" }");
            }
        }
Exemple #11
0
        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));
            }
        }