예제 #1
0
    static int Main(string[] args)
    {
        MimeTable mt     = new MimeTable();
        Widget    widget = new Widget();

        widget.Add(mt);
        widget.Add((IEnumerable <Mime>)mt);
        return(0);
    }
예제 #2
0
 /// <summary>
 /// 将自身作为multipart/form-data的一个文件项
 /// </summary>
 /// <param name="stream">数据流</param>
 /// <param name="fileName">文件友好名称</param>
 /// <exception cref="ArgumentNullException"></exception>
 public MulitpartFile(Stream stream, string fileName)
 {
     if (stream == null)
     {
         throw new ArgumentNullException(nameof(stream));
     }
     this.stream      = stream;
     this.FileName    = fileName;
     this.ContentType = MimeTable.GetContentType(fileName);
 }
예제 #3
0
        public void ProcessRequest(HttpContext context)
        {
            var request  = context.Request;
            var response = context.Response;

            VirtualFile vf       = null;
            var         filePath = request.FilePath;

            // Cross-Origin Resource Sharing (CORS)
            if (!HttpHeaderTools.IsOriginHeaderAllowed())
            {
                AuthenticationHelper.ThrowForbidden(filePath);
            }

            if (HostingEnvironment.VirtualPathProvider.FileExists(filePath))
            {
                vf = HostingEnvironment.VirtualPathProvider.GetFile(filePath);
            }

            if (vf == null)
            {
                throw new HttpException(404, "File does not exist");
            }

            response.ClearContent();

            // Set content type only if this is not a RepositoryFile, because the
            // Open method of RepositoryFile will set the content type itself.
            if (!(vf is RepositoryFile))
            {
                var extension = System.IO.Path.GetExtension(filePath);
                context.Response.ContentType = MimeTable.GetMimeType(extension);

                // add the necessary header for the css font-face rule
                if (MimeTable.IsFontType(extension))
                {
                    HttpHeaderTools.SetAccessControlHeaders();
                }
            }

            // The bytes we write into the output stream will NOT be buffered and will be sent
            // to the client immediately. This makes sure that the whole (potentially large)
            // file is not loaded into the memory on the server.
            response.BufferOutput = false;

            using (var stream = vf.Open())
            {
                response.AppendHeader("Content-Length", stream.Length.ToString());
                response.Clear();

                // Let ASP.NET handle sending bytes to the client (avoid Flush).
                stream.CopyTo(response.OutputStream);
            }
        }
예제 #4
0
        public void ProcessRequest(HttpContext context)
        {
            var request  = context.Request;
            var response = context.Response;

            VirtualFile vf       = null;
            var         filePath = request.FilePath;

            if (HostingEnvironment.VirtualPathProvider.FileExists(filePath))
            {
                vf = HostingEnvironment.VirtualPathProvider.GetFile(filePath);
            }

            if (vf == null)
            {
                throw new HttpException(404, "File does not exist");
            }

            response.ClearContent();

            //Set content type only if this is not a RepositoryFile, because the
            //Open method of RepositoryFile will set the content type itself.
            if (!(vf is RepositoryFile))
            {
                var extension = System.IO.Path.GetExtension(filePath);
                context.Response.ContentType = MimeTable.GetMimeType(extension);

                //add the necessary header for the css font-face rule
                if (MimeTable.IsFontType(extension))
                {
                    HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));
                }
            }

            using (var stream = vf.Open())
            {
                response.AppendHeader("Content-Length", stream.Length.ToString());

                //We need to Flush the headers before
                //we start to stream the actual binary.
                response.Flush();

                var buffer = new byte[Math.Min(stream.Length, RepositoryConfiguration.BinaryChunkSize)];
                int readed;

                while ((readed = stream.Read(buffer, 0, buffer.Length)) > 0)
                {
                    response.OutputStream.Write(buffer, 0, readed);
                    response.Flush();
                }
            }
        }
        private static void ProcessRequestUsingVirtualFile(HttpContext context, string repositoryPath)
        {
            byte[] buffer = ReadVirtualFile(repositoryPath);

            context.Response.ClearContent();

            context.Response.OutputStream.Write(buffer, 0, buffer.Length);

            context.Response.ContentType =
                MimeTable.GetMimeType(System.IO.Path.GetExtension(repositoryPath));

            context.Response.End();
        }
예제 #6
0
 public CustomHttpServer()
 {
     _SessionList           = new DefaultSessionList();
     _MimeTable             = new MimeTable(true);
     DefaultPort            = TcpPorts.Http;
     MaximumHeaderLineCount = Http.HttpServer_MaximumHeaderLineCount;
     AutoStartSession       = Http.HttpServer_AutoStartSession;
     KeepAlive           = Http.HttpServer_KeepAlive;
     ParseParams         = Http.HttpServer_ParseParams;
     ServerSoftware      = Http.HttpServer_ServerSoftware;
     SessionState        = Http.HttpServer_SessionState;
     SessionTimeOut      = Http.HttpServer_SessionTimeOut;
     _OkToProcessCommand = false;
 }
예제 #7
0
        public void BinaryData_CreateImageByBinary()
        {
            var testFileName        = "test.jpg";
            var expectedContentType = MimeTable.GetMimeType(System.IO.Path.GetExtension(testFileName).ToLower());
            var testBinaryData      = new BinaryData();

            testBinaryData.FileName = testFileName;

            var image = Image.CreateByBinary(this.TestRoot as IFolder, testBinaryData);

            Assert.AreEqual(testFileName, image.Name);
            Assert.AreEqual(testFileName, image.Binary.FileName.ToString());
            Assert.AreEqual(expectedContentType, image.Binary.ContentType);
        }
예제 #8
0
        /// <summary>
        /// multipart/form-data的一个文件项
        /// </summary>
        /// <param name="localFilePath">本地文件路径</param>
        /// <exception cref="ArgumentNullException"></exception>
        /// <exception cref="FileNotFoundException"></exception>
        public MulitpartFile(string localFilePath)
        {
            if (string.IsNullOrEmpty(localFilePath))
            {
                throw new ArgumentNullException(nameof(localFilePath));
            }

            if (File.Exists(localFilePath) == false)
            {
                throw new FileNotFoundException(localFilePath);
            }

            this.filePath    = localFilePath;
            this.FileName    = Path.GetFileName(localFilePath);
            this.ContentType = MimeTable.GetContentType(localFilePath);
        }
예제 #9
0
        void IHttpHandler.ProcessRequest(HttpContext context)
        {
            Stream     imageStream;
            BinaryData binaryData;
            var        propNameParam = context.Request.QueryString["NodeProperty"];
            var        propertyName  = string.Empty;
            var        widthParam    = context.Request.QueryString["width"];
            var        heightParam   = context.Request.QueryString["height"];

            if (!string.IsNullOrEmpty(propNameParam))
            {
                propertyName = propNameParam.Replace("$", "#");
                binaryData   = this.GetBinary(propertyName);
            }
            else
            {
                binaryData = this.Binary;
            }

            if (DocumentPreviewProvider.Current != null && DocumentPreviewProvider.Current.IsPreviewOrThumbnailImage(NodeHead.Get(this.Id)))
            {
                // get preview image with watermark or redaction if necessary
                imageStream = string.IsNullOrEmpty(propertyName)
                    ? DocumentPreviewProvider.Current.GetRestrictedImage(this)
                    : DocumentPreviewProvider.Current.GetRestrictedImage(this, propertyName);
            }
            else
            {
                imageStream = binaryData.GetStream();
            }

            //set compressed encoding if necessary
            if (MimeTable.IsCompressedType(this.Extension))
            {
                context.Response.Headers.Add("Content-Encoding", "gzip");
            }

            context.Response.ContentType = binaryData.ContentType;

            imageStream.Position = 0;

            if (!string.IsNullOrEmpty(widthParam) && !string.IsNullOrEmpty(heightParam))
            {
                int width;
                int height;
                if (!int.TryParse(widthParam, out width))
                {
                    width = 200;
                }
                if (!int.TryParse(heightParam, out height))
                {
                    height = 200;
                }

                // compute a new, resized stream on-the-fly
                using (var resizedStream = ImageResizer.CreateResizedImageFile(imageStream, width, height, 80, getImageFormat(binaryData.ContentType)))
                {
                    resizedStream.CopyTo(context.Response.OutputStream);
                }
            }
            else
            {
                imageStream.CopyTo(context.Response.OutputStream);
            }

            imageStream.Close();
        }
        private static void ProcessRequestUsingFilesystemCache(HttpContext context, string repositoryPath, string fullyQualyfiedPath)
        {
            // Check the filesystem cache, create the file if not exists
            if (!System.IO.File.Exists(fullyQualyfiedPath))
            {
                byte[] buffer = ReadVirtualFile(repositoryPath);

                string directoryName = Path.GetDirectoryName(fullyQualyfiedPath);
                if (!Directory.Exists(directoryName))
                {
                    System.IO.Directory.CreateDirectory(directoryName);
                }

                using (var cachedFile = System.IO.File.Create(fullyQualyfiedPath))
                {
                    cachedFile.Write(buffer, 0, buffer.Length);
                }
            }
            else
            {
                var servedFromFileSystem = true;

                // check the date
                DateTime lastWriteTime   = System.IO.File.GetLastWriteTime(fullyQualyfiedPath);
                DateTime now             = DateTime.UtcNow;
                var      nodeDescription = NodeHead.Get(repositoryPath);

                if (lastWriteTime.AddMinutes(CacheTimeframeInMinutes) < now)
                {
                    // update if needed
                    CreateLockFile(fullyQualyfiedPath);

                    int         maxTryNum = 20;
                    IOException lastError = null;
                    while (--maxTryNum >= 0)
                    {
                        try
                        {
                            System.IO.File.SetLastWriteTime(fullyQualyfiedPath, now);
                            break;
                        }
                        catch (IOException ioex) //TODO: catch block
                        {
                            lastError = ioex;
                            System.Threading.Thread.Sleep(200);
                        }
                    }
                    if (lastError != null)
                    {
                        throw new IOException("Cannot write the file: " + fullyQualyfiedPath, lastError);
                    }

                    if (nodeDescription.ModificationDate > lastWriteTime)
                    {
                        // refresh file
                        byte[] buffer = ReadVirtualFile(repositoryPath);
                        servedFromFileSystem = false;

                        using (var cachedFile = System.IO.File.Open(fullyQualyfiedPath, FileMode.Truncate, FileAccess.Write))
                        {
                            cachedFile.Write(buffer, 0, buffer.Length);
                        }
                    }

                    DeleteLockFile(fullyQualyfiedPath);
                }

                // only log file download if it was not logged before by the virtual file provider
                if (servedFromFileSystem)
                {
                    // let the client code log file downloads
                    if (nodeDescription != null &&
                        Providers.Instance.StorageSchema.NodeTypes[nodeDescription.NodeTypeId].IsInstaceOfOrDerivedFrom("File"))
                    {
                        ContentRepository.File.Downloaded(nodeDescription.Id);
                    }
                }
            }

            string extension = System.IO.Path.GetExtension(repositoryPath);

            context.Response.ContentType = MimeTable.GetMimeType(extension);

            context.Response.TransmitFile(fullyQualyfiedPath);
        }
예제 #11
0
        public override Stream Open()
        {
            if (_node == null)
            {
                try
                {
                    var allowCompiledContent = AllowCompiledContent(_repositoryPath);

                    // http://localhost/TestDoc.docx?action=RestoreVersion&version=2.0A
                    // When there are 'action' and 'version' parameters in the requested URL the portal is trying to load the desired version of the node of the requested action.
                    // This leads to an exception when the action doesn't have that version.
                    // _repositoryPath will point to the node of action and ContextNode will be the document
                    // if paths are not equal then we will return the last version of the requested action
                    if (PortalContext.Current == null || string.IsNullOrEmpty(PortalContext.Current.VersionRequest) || _repositoryPath != PortalContext.Current.ContextNodePath)
                    {
                        if (allowCompiledContent)
                        {
                            // elevated mode: pages, ascx files, etc.
                            using (new SystemAccount())
                            {
                                _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                            }
                        }
                        else
                        {
                            _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                        }
                    }
                    else
                    {
                        VersionNumber version;
                        if (VersionNumber.TryParse(PortalContext.Current.VersionRequest, out version))
                        {
                            Node node;

                            if (allowCompiledContent)
                            {
                                // elevated mode: pages, ascx files, etc.
                                using (new SystemAccount())
                                {
                                    node = Node.LoadNode(_repositoryPath, version);
                                }
                            }
                            else
                            {
                                node = Node.LoadNode(_repositoryPath, version);
                            }

                            if (node != null && node.SavingState == ContentSavingState.Finalized)
                            {
                                _node = node;
                            }
                        }
                    }

                    // we cannot serve the binary if the user has only See or Preview permissions for the content
                    if (_node != null && (_node.IsHeadOnly || _node.IsPreviewOnly) && HttpContext.Current != null)
                    {
                        AuthenticationHelper.ThrowForbidden(_node.Name);
                    }
                }
                catch (SenseNetSecurityException ex) //logged
                {
                    Logger.WriteException(ex);

                    if (HttpContext.Current == null || (_repositoryPath != null && _repositoryPath.ToLower().EndsWith(".ascx")))
                    {
                        throw;
                    }

                    AuthenticationHelper.DenyAccess(HttpContext.Current.ApplicationInstance);
                }
            }

            if (_node == null)
            {
                throw new ApplicationException(string.Format("{0} not found. RepositoryFile cannot be served.", _repositoryPath));
            }

            string propertyName = string.Empty;

            if (PortalContext.Current != null)
            {
                propertyName = PortalContext.Current.QueryStringNodePropertyName;
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                propertyName = PortalContext.DefaultNodePropertyName;
            }

            var propType = _node.PropertyTypes[propertyName];

            if (propType == null)
            {
                throw new ApplicationException("Property not found: " + propertyName);
            }
            ////<only_for_test>
            //if(propType == null)
            //{
            //    StringBuilder sb = new StringBuilder();
            //    sb.AppendFormat("Property {0} not found.", propertyName);
            //    sb.AppendLine();
            //    foreach (var pt in _node.PropertyTypes)
            //    {
            //        sb.AppendFormat("PropertyName='{0}' - DataType='{1}'", pt.Name, pt.DataType);
            //        sb.AppendLine();
            //    }
            //    return new MemoryStream(System.Text.Encoding.UTF8.GetBytes(sb.ToString()));
            //}
            ////</only_for_test>

            var    propertyDataType = propType.DataType;
            Stream stream;

            switch (propertyDataType)
            {
            case DataType.Binary:
                string         contentType;
                BinaryFileName fileName;
                stream = DocumentBinaryProvider.Current.GetStream(_node, propertyName, out contentType, out fileName);

                if (stream == null)
                {
                    throw new ApplicationException(string.Format("BinaryProperty.Value.GetStream() returned null. RepositoryPath={0}, OriginalUri={1}, AppDomainFriendlyName={2} ", this._repositoryPath, ((PortalContext.Current != null) ? PortalContext.Current.OriginalUri.ToString() : "PortalContext.Current is null"), AppDomain.CurrentDomain.FriendlyName));
                }

                //Set MIME type only if this is the main content (skip asp controls and pages,
                //page templates and other repository files opened during the request).
                //We need this in case of special images, fonts, etc, and handle the variable
                //at the end of the request (PortalContextModule.EndRequest method).
                if (HttpContext.Current != null &&
                    PortalContext.Current != null &&
                    PortalContext.Current.RepositoryPath == _repositoryPath &&
                    (string.IsNullOrEmpty(PortalContext.Current.ActionName) || PortalContext.Current.ActionName == "Browse") &&
                    !string.IsNullOrEmpty(contentType) &&
                    contentType != "text/asp")
                {
                    if (!HttpContext.Current.Items.Contains(RESPONSECONTENTTYPEKEY))
                    {
                        HttpContext.Current.Items.Add(RESPONSECONTENTTYPEKEY, contentType);
                    }

                    //set the value anyway as it may be useful in case of our custom file handler (SenseNetStaticFileHandler)
                    HttpContext.Current.Response.ContentType = contentType;

                    //add the necessary header for the css font-face rule
                    if (MimeTable.IsFontType(fileName.Extension))
                    {
                        HttpContext.Current.Response.AppendHeader("Access-Control-Allow-Origin", HttpContext.Current.Request.Url.GetComponents(UriComponents.SchemeAndServer, UriFormat.SafeUnescaped));
                    }
                }

                //set compressed encoding if necessary
                if (HttpContext.Current != null && MimeTable.IsCompressedType(fileName.Extension))
                {
                    HttpContext.Current.Response.Headers.Add("Content-Encoding", "gzip");
                }

                //let the client code log file downloads
                var file = _node as ContentRepository.File;
                if (file != null)
                {
                    ContentRepository.File.Downloaded(file.Id);
                }
                break;

            case DataType.String:
            case DataType.Text:
            case DataType.Int:
            case DataType.DateTime:
                stream = new MemoryStream(Encoding.UTF8.GetBytes(_node[propertyName].ToString()));
                break;

            default:
                throw new NotSupportedException(string.Format("The {0} property cannot be served because that's datatype is {1}.", propertyName, propertyDataType));
            }

            return(stream);
        }
예제 #12
0
        public override Stream Open()
        {
            if (_node == null)
            {
                try
                {
                    var allowCompiledContent = AllowCompiledContent(_repositoryPath);

                    // http://localhost/TestDoc.docx?action=RestoreVersion&version=2.0A
                    // When there are 'action' and 'version' parameters in the requested URL the portal is trying to load the desired version of the node of the requested action.
                    // This leads to an exception when the action doesn't have that version.
                    // _repositoryPath will point to the node of action and ContextNode will be the document
                    // if paths are not equal then we will return the last version of the requested action.
                    // We also have to ignore the version request parameter in case of binary handler, because that
                    // ashx must not have multiple versions.
                    if (PortalContext.Current == null || PortalContext.Current.BinaryHandlerRequestedNodeHead != null || string.IsNullOrEmpty(PortalContext.Current.VersionRequest) || _repositoryPath != PortalContext.Current.ContextNodePath)
                    {
                        if (allowCompiledContent)
                        {
                            // elevated mode: pages, ascx files, etc.
                            using (new SystemAccount())
                            {
                                _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                            }
                        }
                        else
                        {
                            _node = Node.LoadNode(_repositoryPath, VersionNumber.LastFinalized);
                        }
                    }
                    else
                    {
                        VersionNumber version;
                        if (VersionNumber.TryParse(PortalContext.Current.VersionRequest, out version))
                        {
                            Node node;

                            if (allowCompiledContent)
                            {
                                // elevated mode: pages, ascx files, etc.
                                using (new SystemAccount())
                                {
                                    node = Node.LoadNode(_repositoryPath, version);
                                }
                            }
                            else
                            {
                                node = Node.LoadNode(_repositoryPath, version);
                            }

                            if (node != null && node.SavingState == ContentSavingState.Finalized)
                            {
                                _node = node;
                            }
                        }
                    }

                    // we cannot serve the binary if the user has only See or Preview permissions for the content
                    if (_node != null && (_node.IsHeadOnly || _node.IsPreviewOnly) && HttpContext.Current != null)
                    {
                        AuthenticationHelper.ThrowForbidden(_node.Name);
                    }
                }
                catch (SenseNetSecurityException ex) // logged
                {
                    SnLog.WriteException(ex);

                    if (HttpContext.Current == null || (_repositoryPath != null && _repositoryPath.ToLower().EndsWith(".ascx")))
                    {
                        throw;
                    }

                    AuthenticationHelper.DenyAccess(HttpContext.Current.ApplicationInstance);
                }
            }

            if (_node == null)
            {
                throw new ApplicationException(string.Format("{0} not found. RepositoryFile cannot be served.", _repositoryPath));
            }

            string propertyName = string.Empty;

            if (PortalContext.Current != null)
            {
                propertyName = PortalContext.Current.QueryStringNodePropertyName;
            }

            if (string.IsNullOrEmpty(propertyName))
            {
                propertyName = PortalContext.DefaultNodePropertyName;
            }

            var propType = _node.PropertyTypes[propertyName];

            if (propType == null)
            {
                throw new ApplicationException("Property not found: " + propertyName);
            }

            var    propertyDataType = propType.DataType;
            Stream stream;

            switch (propertyDataType)
            {
            case DataType.Binary:
                string         contentType;
                BinaryFileName fileName;

                // Images need to be handled differently, because of these reasons:
                // - dimensions may be changed dynamically, based on request parameters
                // - preview images may be restricted (redacted) based on permissions
                if (_node is Image img)
                {
                    var parameters = HttpContext.Current?.Request.QueryString;

                    stream = img.GetImageStream(propertyName,
                                                parameters?.AllKeys.ToDictionary(k => k ?? string.Empty, k => (object)parameters[k]),
                                                out contentType,
                                                out fileName);
                }
                else
                {
                    stream = DocumentBinaryProvider.Current.GetStream(_node, propertyName, out contentType, out fileName);
                }

                if (stream == null)
                {
                    throw new ApplicationException(string.Format("BinaryProperty.Value.GetStream() returned null. RepositoryPath={0}, OriginalUri={1}, AppDomainFriendlyName={2} ", this._repositoryPath, ((PortalContext.Current != null) ? PortalContext.Current.RequestedUri.ToString() : "PortalContext.Current is null"), AppDomain.CurrentDomain.FriendlyName));
                }

                // Set MIME type only if this is the main content (skip asp controls and pages,
                // page templates and other repository files opened during the request).
                // We need this in case of special images, fonts, etc, and handle the variable
                // at the end of the request (PortalContextModule.EndRequest method).
                if (HttpContext.Current != null &&
                    PortalContext.Current != null &&
                    string.Equals(PortalContext.Current.RepositoryPath, _repositoryPath, StringComparison.InvariantCultureIgnoreCase) &&
                    (string.IsNullOrEmpty(PortalContext.Current.ActionName) || string.Equals(PortalContext.Current.ActionName, "Browse", StringComparison.InvariantCultureIgnoreCase)) &&
                    !string.IsNullOrEmpty(contentType) &&
                    contentType != "text/asp")
                {
                    if (!HttpContext.Current.Items.Contains(RESPONSECONTENTTYPEKEY))
                    {
                        HttpContext.Current.Items.Add(RESPONSECONTENTTYPEKEY, contentType);
                    }

                    // set the value anyway as it may be useful in case of our custom file handler (SenseNetStaticFileHandler)
                    HttpContext.Current.Response.ContentType = contentType;

                    // add the necessary header for the css font-face rule
                    if (MimeTable.IsFontType(fileName.Extension))
                    {
                        HttpHeaderTools.SetAccessControlHeaders();
                    }
                }

                // set compressed encoding if necessary
                if (HttpContext.Current != null && MimeTable.IsCompressedType(fileName.Extension))
                {
                    HttpContext.Current.Response.Headers.Add("Content-Encoding", "gzip");
                }

                // let the client code log file downloads
                var file = _node as ContentRepository.File;
                if (file != null)
                {
                    ContentRepository.File.Downloaded(file.Id);
                }
                break;

            case DataType.String:
            case DataType.Text:
            case DataType.Int:
            case DataType.DateTime:
                stream = new MemoryStream(Encoding.UTF8.GetBytes(_node[propertyName].ToString()));
                break;

            default:
                throw new NotSupportedException(string.Format("The {0} property cannot be served because that's datatype is {1}.", propertyName, propertyDataType));
            }

            return(stream);
        }