Пример #1
0
        //--- Methods ---
        public StreamInfo GetFile(ResourceBE attachment, SizeType size, bool allowFileLink)
        {
            MimeType mime;

            switch (size)
            {
            case SizeType.THUMB:
            case SizeType.WEBVIEW:
                mime = AttachmentPreviewBL.ResolvePreviewMime(attachment.MimeType);
                break;

            default:
                mime = attachment.MimeType;
                break;
            }

            return(GetFileInternal(FilePath(attachment, size), mime));
        }
Пример #2
0
        internal Yield PutSiteLogo(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            //Confirm image type
            if (!new MimeType("image/*").Match(request.ContentType))
            {
                throw new SiteImageMimetypeInvalidArgumentException();
            }
            try {
                //Save file to storage provider
                DekiContext.Current.Instance.Storage.PutSiteFile(LOGO_LABEL, new StreamInfo(request.AsStream(), request.ContentLength, request.ContentType));
                ConfigBL.SetInstanceSettingsValue(ConfigBL.UI_LOGO_UPLOADED, "true");
            } catch (Exception x) {
                DekiContext.Current.Instance.Log.Warn("Failed to save logo to storage provider", x);
                ConfigBL.DeleteInstanceSettingsValue(ConfigBL.UI_LOGO_UPLOADED);
                throw;
            }

            StreamInfo file = DekiContext.Current.Instance.Storage.GetSiteFile(LOGO_LABEL, false);

            if (file != null)
            {
                StreamInfo thumb = AttachmentPreviewBL.BuildThumb(file, FormatType.PNG, RatioType.UNDEFINED, DekiContext.Current.Instance.LogoWidth, DekiContext.Current.Instance.LogoHeight);
                if (thumb != null)
                {
                    DekiContext.Current.Instance.Storage.PutSiteFile(LOGO_LABEL, thumb);
                }
                else
                {
                    DekiContext.Current.Instance.Log.WarnMethodCall("PUT:site/logo", "Unable to process logo through imagemagick");
                    DekiContext.Current.ApiPlug.At("site", "logo").Delete();
                    throw new SiteUnableToProcessLogoInvalidOperationException();
                }
            }
            else
            {
                DekiContext.Current.Instance.Log.WarnMethodCall("PUT:site/logo", "Unable to retrieve saved logo");
            }
            response.Return(DreamMessage.Ok());
            yield break;
        }
Пример #3
0
        public Yield GetFile(DreamContext context, DreamMessage request, Result <DreamMessage> response)
        {
            PageBE       parentPage   = null;
            DreamMessage responseMsg  = null;
            ResourceBE   fileRevision = GetAttachment(context, request, Permissions.READ, true, false, out parentPage);

            if (fileRevision.IsHidden)
            {
                PermissionsBL.CheckUserAllowed(DekiContext.Current.User, Permissions.ADMIN);
            }

            // check if only file information is requested
            if (context.Verb == Verb.HEAD)
            {
                response.Return(new DreamMessage(DreamStatus.Ok, null, fileRevision.MimeType, (long)fileRevision.Size, Stream.Null));
                yield break;
            }
            try {
                if (request.CheckCacheRevalidation(fileRevision.Timestamp))
                {
                    responseMsg = DreamMessage.NotModified();
                }
                if (responseMsg == null)
                {
                    #region Preview related parameter parsing
                    string sFormat    = context.GetParam("format", string.Empty);
                    string sRatio     = context.GetParam("ratio", string.Empty);
                    uint   height     = context.GetParam <uint>("height", 0);
                    uint   width      = context.GetParam <uint>("width", 0);
                    string cachedSize = context.GetParam("size", string.Empty);

                    // check 'ratio' parameter
                    RatioType ratio = RatioType.UNDEFINED;
                    if (!string.IsNullOrEmpty(sRatio))
                    {
                        switch (sRatio.ToLowerInvariant().Trim())
                        {
                        case "var":
                        case "variable":
                            ratio = RatioType.VARIABLE;
                            break;

                        case "fixed":
                            ratio = RatioType.FIXED;
                            break;

                        default:
                            throw new AttachmentFileRatioInvalidArgumentException();
                        }
                    }

                    // check 'size' parameter
                    SizeType size = SizeType.UNDEFINED;
                    if (!string.IsNullOrEmpty(cachedSize) && !SysUtil.TryParseEnum(cachedSize.Trim(), out size))
                    {
                        throw new AttachmentFilesizeInvalidArgumentException();
                    }

                    // check 'format' parameter
                    FormatType format = FormatType.UNDEFINED;
                    if (!string.IsNullOrEmpty(sFormat) && !SysUtil.TryParseEnum(sFormat.Trim(), out format))
                    {
                        throw new AttachmentFileFormatInvalidArgumentException();
                    }
                    #endregion

                    //if any preview related parameters are set, do preview logic. Otherwise return the file
                    StreamInfo file = null;
                    if ((size != SizeType.UNDEFINED && size != SizeType.ORIGINAL) ||
                        ratio != RatioType.UNDEFINED ||
                        format != FormatType.UNDEFINED ||
                        height != 0 ||
                        width != 0
                        )
                    {
                        file = AttachmentPreviewBL.RetrievePreview(fileRevision, height, width, ratio, size, format);
                    }
                    else
                    {
                        var isMSWebDAV = MSWEBDAV_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty);
                        file = DekiContext.Current.Instance.Storage.GetFile(fileRevision, SizeType.ORIGINAL, !isMSWebDAV);
                    }

                    // prepare response
                    if (file == null)
                    {
                        throw new AttachmentDoesNotExistFatalException(fileRevision.ResourceId, fileRevision.Revision);
                    }

                    if (file.Uri != null)
                    {
                        responseMsg = DreamMessage.Redirect(file.Uri);
                    }
                    else
                    {
                        bool inline = fileRevision.MetaXml.ImageHeight.HasValue;

                        // see if we can use the MimeType map for allowing inlining
                        if (!inline)
                        {
                            // if IE inline security is not disabled
                            bool isIE = false;
                            if (!DekiContext.Current.Instance.EnableUnsafeIEContentInlining)
                            {
                                // check the user agent to see if we're dealing with IE
                                isIE = MSIE_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty);
                            }

                            // see if the mime-type could allow inlining
                            inline = DekiContext.Current.Instance.MimeTypeCanBeInlined(fileRevision.MimeType);
                            if (inline && isIE)
                            {
                                // check whether the creator of the file had unsafecontent permission, to override IE security
                                IList <ResourceBE> revisions         = ResourceBL.Instance.GetResourceRevisions(fileRevision.ResourceId, ResourceBE.ChangeOperations.CONTENT, SortDirection.DESC, 1);
                                UserBE             lastContentEditor = UserBL.GetUserById(revisions[0].UserId);
                                inline = PermissionsBL.IsUserAllowed(lastContentEditor, parentPage, Permissions.UNSAFECONTENT);
                            }
                        }
                        responseMsg = DreamMessage.Ok(fileRevision.MimeType, file.Length, file.Stream);
                        responseMsg.Headers["X-Content-Type-Options"] = "nosniff";
                        responseMsg.Headers.ContentDisposition        = new ContentDisposition(inline, fileRevision.Timestamp, null, null, fileRevision.Name, file.Length, request.Headers.UserAgent);

                        // MSIE6 will delete a downloaded file before the helper app trying to use it can get to it so we
                        //have to do custom cache control headers for MSIE6 so that the file can actually be opened
                        if (MSIE6_USER_AGENT_REGEX.IsMatch(request.Headers.UserAgent ?? string.Empty))
                        {
                            responseMsg.Headers["Expires"]   = "0";
                            responseMsg.Headers.Pragma       = "cache";
                            responseMsg.Headers.CacheControl = "private";
                        }
                        else
                        {
                            responseMsg.SetCacheMustRevalidate(fileRevision.Timestamp);
                        }
                    }
                }
            } catch {
                if (responseMsg != null)
                {
                    responseMsg.Close();
                }
                throw;
            }
            response.Return(responseMsg);
            yield break;
        }