示例#1
0
        private static void DeleteFileSystemInfo(FileSystemInfoBase fileSystemInfo, bool ignoreErrors)
        {
            if (!fileSystemInfo.Exists)
            {
                return;
            }

            try
            {
                fileSystemInfo.Attributes = FileAttributes.Normal;
            }
            catch
            {
                if (!ignoreErrors) throw;
            }

            var directoryInfo = fileSystemInfo as DirectoryInfoBase;

            if (directoryInfo != null)
            {
                DeleteDirectoryContentsSafe(directoryInfo, ignoreErrors);
            }

            DoSafeAction(fileSystemInfo.Delete, ignoreErrors);
        }
示例#2
0
 public MarkdownNode(FileSystemInfoBase location, string relativePathFromRoot, XElement markdownContent)
 {
     this.OriginalLocation = location;
     this.OriginalLocationUrl = location.ToUri();
     this.RelativePathFromRoot = relativePathFromRoot;
     this.MarkdownContent = markdownContent;
 }
示例#3
0
 protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath)
 {
     // We don't support getting a file from the zip controller
     // Conceivably, it could be a zip file containing just the one file, but that's rarely interesting
     HttpResponseMessage notFoundResponse = Request.CreateResponse(HttpStatusCode.NotFound);
     return Task.FromResult(notFoundResponse);
 }
示例#4
0
        public INode Create(FileSystemInfoBase root, FileSystemInfoBase location)
        {
            string relativePathFromRoot = root == null ? @".\" : PathExtensions.MakeRelativePath(root, location, this.fileSystem);

            var directory = location as DirectoryInfoBase;
            if (directory != null)
            {
                return new FolderNode(directory, relativePathFromRoot);
            }

            var file = location as FileInfoBase;
            if (this.relevantFileDetector.IsFeatureFile(file))
            {
                Feature feature = this.featureParser.Parse(file.FullName);
                if (feature != null)
                {
                    return new FeatureNode(file, relativePathFromRoot, feature);
                }

                throw new InvalidOperationException("This feature file could not be read and will be excluded");
            }
            else if (this.relevantFileDetector.IsMarkdownFile(file))
            {
                XElement markdownContent = this.htmlMarkdownFormatter.Format(this.fileSystem.File.ReadAllText(file.FullName));
                return new MarkdownNode(file, relativePathFromRoot, markdownContent);
            }
            else if (this.relevantFileDetector.IsImageFile(file))
            {
                return new ImageNode(file, relativePathFromRoot);
            }

            throw new InvalidOperationException("Cannot create an IItemNode-derived object for " + file.FullName);
        }
示例#5
0
 public FeatureNode(FileSystemInfoBase location, string relativePathFromRoot, Feature feature)
 {
     this.OriginalLocation = location;
     this.OriginalLocationUrl = location.ToUri();
     this.RelativePathFromRoot = relativePathFromRoot;
     this.Feature = feature;
 }
示例#6
0
        public static string MakeRelativePath(FileSystemInfoBase from, FileSystemInfoBase to, IFileSystem fileSystem)
        {
            if (from == null) throw new ArgumentNullException("from");
            if (to == null) throw new ArgumentNullException("to");

            return MakeRelativePath(from.FullName, to.FullName, fileSystem);
        }
        /// <summary>
        /// Extracts a snippet.
        /// </summary>
        /// <param name="fileSystemInfo">The file system info.</param>
        /// <param name="pattern">The extraction pattern.</param>
        /// <returns>The extracted snippet.</returns>
        public Snippet Extract(FileSystemInfoBase fileSystemInfo, string pattern)
        {
            // Get the directory
            DirectoryInfoBase directoryInfo = this.ConvertToDirectory(fileSystemInfo);

            // Use * as pattern when none is set
            if (string.IsNullOrWhiteSpace(pattern))
            {
                pattern = "*";
            }

            try
            {
                // Search file system info from pattern
                FileSystemInfoBase[] fileSystemInfoBase = pattern
                    .Split(new char[] { '|', ';' }, StringSplitOptions.RemoveEmptyEntries)
                    .Select(x => x.Trim())
                    .Where(x => !string.IsNullOrWhiteSpace(x))
                    .SelectMany(x => directoryInfo.GetFileSystemInfos(x, SearchOption.AllDirectories))
                    .OrderByDescending(x => x is DirectoryInfoBase)
                    .ThenBy(x => x.FullName)
                    .ToArray();

                // Build snippet
                return this.BuildSnippet(directoryInfo, fileSystemInfoBase);
            }

            // Rethrow a snippet extraction exception if the directory is not found
            catch (DirectoryNotFoundException)
            {
                throw new SnippetExtractionException("Cannot find directory", pattern);
            }
        }
示例#8
0
        internal static string GetDestinationPath(string sourceRootPath, string destinationRootPath, FileSystemInfoBase info)
        {
            string sourcePath = info.FullName;
            sourcePath = sourcePath.Substring(sourceRootPath.Length)
                                   .Trim(Path.DirectorySeparatorChar);

            return Path.Combine(destinationRootPath, sourcePath);
        }
        public static ItemType GetItemType(FileSystemInfoBase itemInfo) {
            if(itemInfo is FileInfoBase) {
                return ItemType.File;
            }

            if (itemInfo is DirectoryInfoBase) {
                return ItemType.Directory;
            }

            throw new NotImplementedException();
        }
        /// <summary>
        /// Converts a FileSystemInfo to DirectoryInfo.
        /// </summary>
        /// <param name="fileSystemInfo">The file system info.</param>
        /// <returns>The directory info.</returns>
        protected DirectoryInfoBase ConvertToDirectory(FileSystemInfoBase fileSystemInfo)
        {
            // Data validation
            Ensure.That(() => fileSystemInfo).IsNotNull();

            // Cast to DirectoryInfo
            DirectoryInfoBase directoryInfo = fileSystemInfo as DirectoryInfoBase;
            Ensure.That(() => directoryInfo).IsNotNull();

            // Return as directory
            return directoryInfo;
        }
        /// <summary>
        /// Extracts a snippet.
        /// </summary>
        /// <param name="fileSystemInfo">The file system info.</param>
        /// <param name="pattern">The extraction pattern, never used for this implementation.</param>
        /// <returns>The extracted snippet.</returns>
        public virtual Model.Snippet Extract(FileSystemInfoBase fileSystemInfo, string pattern)
        {
            // Data validation
            if (null == fileSystemInfo)
                throw new ArgumentNullException("fileSystemInfo");

            // Extract file content
            string sourceCode = this.LoadFile(this.ConvertToFile(fileSystemInfo));

            // Return the entire code
            return new Model.PlainTextSnippet(sourceCode);
        }
        public FileSystemCabinetItemInfo(FileSystemInfoBase itemInfo, string baseDirectory) {
            if (itemInfo == null) throw new ArgumentNullException(nameof(itemInfo));
            if (String.IsNullOrWhiteSpace(baseDirectory)) throw new ArgumentNullException(nameof(baseDirectory));

            this.Type = GetItemType(itemInfo);
            this.Key = GetItemKey(itemInfo, baseDirectory);
            this.Exists = itemInfo.Exists;

            bool isExistingFile = itemInfo.Exists && this.Type == ItemType.File;
            var fileInfo = itemInfo as FileInfoBase;
            
            this.Size = isExistingFile ? fileInfo?.Length : null;
            this.LastModifiedUtc =  isExistingFile ? fileInfo?.LastWriteTimeUtc : null;
        }
        /// <summary>
        /// Converts a FileSystemInfo to FileInfo.
        /// </summary>
        /// <param name="fileSystemInfo">The file system info.</param>
        /// <returns>The file info.</returns>
        protected FileInfoBase ConvertToFile(FileSystemInfoBase fileSystemInfo)
        {
            // Data validation
            if (null == fileSystemInfo)
                throw new ArgumentNullException("fileSystemInfo");

            // Cast to FileInfo
            FileInfoBase fileInfo = fileSystemInfo as FileInfoBase;
            if (null == fileInfo)
                throw new ArgumentException("fileInfo");

            // Return as file
            return fileInfo;
        }
        /// <summary>
        /// Extracts a snippet from a given rule pattern.
        /// </summary>
        /// <param name="fileSystemInfo">The file system info.</param>
        /// <param name="memberPattern">The member pattern to extract.</param>
        /// <returns>The extracted snippet.</returns>
        public override Model.Snippet Extract(FileSystemInfoBase fileSystemInfo, string memberPattern)
        {
            // Return the entire code if no member is specified
            if (string.IsNullOrWhiteSpace(memberPattern))
            {
                return base.Extract(fileSystemInfo, memberPattern);
            }

            // Parse the matching rule from the pattern
            CSharpMatchingRule rule = CSharpMatchingRule.Parse(memberPattern);

            // Load the trie for pattern matching
            if (null == this.syntaxTrie)
            {
                // Load file content
                string sourceCode = base.LoadFile(this.ConvertToFile(fileSystemInfo));

                // Build a syntax tree from the source code
                SyntaxTree tree = CSharpSyntaxTree.ParseText(sourceCode);
                SyntaxNode root = tree.GetRoot();

                // Visit the syntax tree for generating a Trie for pattern matching
                CSharpSyntaxWalkerMatchingBuilder syntaxMatchingBuilder = new CSharpSyntaxWalkerMatchingBuilder();
                syntaxMatchingBuilder.Visit(root);

                // Retrieve the Trie root
                this.syntaxTrie = syntaxMatchingBuilder.Root;
            }

            // Match the rule from the syntax matching Trie
            CSharpSyntaxMatchingNode matchingTrie = syntaxTrie.Match(rule.MatchingChunks);
            if (null == matchingTrie)
            {
                throw new SnippetExtractionException("Cannot find member", memberPattern);
            }

            // Build a snippet for extracted syntax nodes
            return this.BuildSnippet(matchingTrie.MatchingSyntaxNodes, rule.ExtractionMode);
        }
示例#15
0
 protected abstract Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath);
示例#16
0
 protected override Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
 {
     // We don't support putting an individual file using the zip controller
     HttpResponseMessage notFoundResponse = Request.CreateResponse(HttpStatusCode.NotFound);
     return Task.FromResult(notFoundResponse);
 }
示例#17
0
        private static void DeleteFileSystemInfo(FileSystemInfoBase fileSystemInfo)
        {
            try
            {
                if (fileSystemInfo.Exists)
                {
                    fileSystemInfo.Attributes = FileAttributes.Normal;
                }
            }
            catch
            {
            }

            var directoryInfo = fileSystemInfo as DirectoryInfoBase;

            if (directoryInfo != null)
            {
                DeleteDirectoryContentsSafe(directoryInfo);
            }

            DoSafeAction(fileSystemInfo.Delete);
        }
        protected override async Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
        {
            // If repository is empty then there is no commit id and no master branch so we don't create any branch; we just init the repo.
            if (_currentEtag != null)
            {
                HttpResponseMessage errorResponse;
                if (!PrepareBranch(itemExists, out errorResponse))
                {
                    return errorResponse;
                }
            }
            else
            {
                // Initialize or re-initialize repository
                _repository.Initialize();
            }

            // Save file
            try
            {
                // Get the query parameters
                QueryParameters parameters = new QueryParameters(this.Request);

                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Content.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        HttpResponseMessage conflictResponse = Request.CreateErrorResponse(
                            HttpStatusCode.Conflict, RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message),
                            ex);
                        return conflictResponse;
                    }
                }

                // Use to track whether our rebase applied updates from master.
                bool updateBranchIsUpToDate = true;

                // Commit to local branch
                bool commitResult = _repository.Commit(parameters.Message, authorName: null, emailAddress: null);
                if (!commitResult)
                {
                    HttpResponseMessage noChangeResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    noChangeResponse.Headers.ETag = CreateEtag(_repository.CurrentId);
                    return noChangeResponse;
                }

                bool rebasing = false;
                if (_currentEtag != null)
                {
                    try
                    {
                        // Only rebase if VFS branch isn't up-to-date already
                        if (!_repository.DoesBranchContainCommit(VfsUpdateBranch, MasterBranch))
                        {
                            // Rebase to get updates from master while checking whether we get a conflict
                            rebasing = true;
                            updateBranchIsUpToDate = _repository.Rebase(MasterBranch);
                        }

                        // Switch content back to master
                        _repository.UpdateRef(VfsUpdateBranch);
                    }
                    catch (CommandLineException commandLineException)
                    {
                        Tracer.TraceError(commandLineException);

                        if (rebasing)
                        {
                            // The rebase resulted in a conflict. We send the conflicted version to the client so that the user
                            // can see the conflicts and resubmit.
                            _cleanupRebaseConflict = true;
                            HttpResponseMessage conflictResponse = Request.CreateResponse(HttpStatusCode.Conflict);
                            _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                            conflictResponse.Content = new StreamContent(_readStream, BufferSize);
                            conflictResponse.Content.Headers.ContentType = _conflictMediaType;
                            return conflictResponse;
                        }
                        else
                        {
                            HttpResponseMessage updateErrorResponse =
                               Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmUpdate_Error, commandLineException.Message));
                            return updateErrorResponse;
                        }
                    }
                }

                // If item does not already exist then we return 201 Created. Otherwise, as a successful commit could result 
                // in a non-conflicting merge we send back the committed version so that a client
                // can get the latest bits. This means we use a 200 OK response instead of a 204 response.
                HttpResponseMessage successFileResponse = null;
                if (itemExists)
                {
                    if (updateBranchIsUpToDate)
                    {
                        successFileResponse = Request.CreateResponse(HttpStatusCode.NoContent);
                    }
                    else
                    {
                        successFileResponse = Request.CreateResponse(HttpStatusCode.OK);
                        _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                        successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                        successFileResponse.Content.Headers.ContentType = MediaTypeMap.GetMediaType(info.Extension);
                    }
                }
                else
                {
                    successFileResponse = Request.CreateResponse(HttpStatusCode.Created);
                }

                // Get current commit ID
                string currentId = _repository.CurrentId;

                // Deploy changes unless request indicated to not deploy
                if (!parameters.NoDeploy)
                {
                    DeployResult result = await DeployChangesAsync(currentId);
                    if (result != null && result.Status != DeployStatus.Success)
                    {
                        HttpResponseMessage deploymentErrorResponse =
                            Request.CreateErrorResponse(HttpStatusCode.InternalServerError, RS.Format(Resources.VfsScmController_DeploymentError, result.StatusText));
                        return deploymentErrorResponse;
                    }
                }

                // Set updated etag for the file
                successFileResponse.Headers.ETag = CreateEtag(currentId);
                return successFileResponse;
            }
            catch (Exception ex)
            {
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.Conflict,
                    RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex);
                return errorResponse;
            }
        }
示例#19
0
 public static string GetUriForTargetRelativeToMe(this Uri me, FileSystemInfoBase target, string newExtension)
 {
     return target.FullName != me.LocalPath
                ? me.MakeRelativeUri(target.ToUri()).ToString().Replace(target.Extension, newExtension)
                : "#";
 }
示例#20
0
        private string ShorthandAttributes(FileSystemInfoBase sourceFile)
        {
            var sb = new StringBuilder("[");
            var sfa = sourceFile.Attributes;

            if ((sfa & FileAttributes.Archive) == FileAttributes.Archive)
            {
                sb.Append("A");
            }

            if ((sfa & FileAttributes.Hidden) == FileAttributes.Hidden)
            {
                sb.Append("H");
            }

            if ((sfa & FileAttributes.System) == FileAttributes.System)
            {
                sb.Append("S");
            }

            if ((sfa & FileAttributes.ReadOnly) == FileAttributes.ReadOnly)
            {
                sb.Append("R");
            }

            if ((sfa & FileAttributes.Compressed) == FileAttributes.Compressed)
            {
                sb.Append("C");
            }

            if ((sfa & FileAttributes.Encrypted) == FileAttributes.Encrypted)
            {
                sb.Append("E");
            }

            if (sb.Length == 1)
            {
                return String.Empty;
            }

            sb.Append("]");
            return sb.ToString();
        }
示例#21
0
        void CopyFileToLocation(FileSystemInfoBase target, IPackageFile x)
        {
            var targetPath = Path.Combine(target.FullName, x.EffectivePath);

            var fi = fileSystem.GetFileInfo(targetPath);
            if (fi.Exists) fi.Delete();

            var dir = fileSystem.GetDirectoryInfo(Path.GetDirectoryName(targetPath));
            if (!dir.Exists) dir.Create();

            using (var inf = x.GetStream())
            using (var of = fi.Open(FileMode.CreateNew, FileAccess.Write)) {
                log.Debug("Writing {0} to app directory", targetPath);
                inf.CopyTo(of);
            }
        }
示例#22
0
 public ImageNode(FileSystemInfoBase location, string relativePathFromRoot)
 {
     this.OriginalLocation = location;
     this.OriginalLocationUrl = location.ToUri();
     this.RelativePathFromRoot = relativePathFromRoot;
 }
示例#23
0
 protected abstract Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists);
示例#24
0
        protected override async Task<HttpResponseMessage> CreateItemPutResponse(FileSystemInfoBase info, string localFilePath, bool itemExists)
        {
            // Check that we have a matching conditional If-Match request for existing resources
            if (itemExists)
            {
                // Get current etag
                EntityTagHeaderValue currentEtag = CreateEntityTag(info);

                // Existing resources require an etag to be updated.
                if (Request.Headers.IfMatch == null)
                {
                    HttpResponseMessage missingIfMatchResponse = Request.CreateErrorResponse(
                        HttpStatusCode.PreconditionFailed, Resources.VfsController_MissingIfMatch);
                    return missingIfMatchResponse;
                }

                bool isMatch = false;
                foreach (EntityTagHeaderValue etag in Request.Headers.IfMatch)
                {
                    if (currentEtag.Equals(etag) || etag == EntityTagHeaderValue.Any)
                    {
                        isMatch = true;
                        break;
                    }
                }

                if (!isMatch)
                {
                    HttpResponseMessage conflictFileResponse = Request.CreateErrorResponse(
                        HttpStatusCode.PreconditionFailed, Resources.VfsController_EtagMismatch);
                    conflictFileResponse.Headers.ETag = currentEtag;
                    return conflictFileResponse;
                }
            }

            // Save file
            try
            {
                using (Stream fileStream = GetFileWriteStream(localFilePath, fileExists: itemExists))
                {
                    try
                    {
                        await Request.Content.CopyToAsync(fileStream);
                    }
                    catch (Exception ex)
                    {
                        Tracer.TraceError(ex);
                        HttpResponseMessage conflictResponse = Request.CreateErrorResponse(
                            HttpStatusCode.Conflict,
                            RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message),
                            ex);

                        return conflictResponse;
                    }
                }

                // Return either 204 No Content or 201 Created response
                HttpResponseMessage successFileResponse =
                    Request.CreateResponse(itemExists ? HttpStatusCode.NoContent : HttpStatusCode.Created);

                // Set updated etag for the file
                info.Refresh();
                successFileResponse.SetEntityTagHeader(CreateEntityTag(info), info.LastWriteTimeUtc);
                return successFileResponse;

            }
            catch (Exception ex)
            {
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse =
                    Request.CreateErrorResponse(HttpStatusCode.Conflict,
                    RS.Format(Resources.VfsController_WriteConflict, localFilePath, ex.Message), ex);

                return errorResponse;
            }
        }
示例#25
0
        private IEnumerable<VfsStatEntry> GetDirectoryResponse(FileSystemInfoBase[] infos)
        {
            string baseAddress = Request.RequestUri.AbsoluteUri;
            foreach (FileSystemInfoBase fileSysInfo in infos)
            {
                bool isDirectory = (fileSysInfo.Attributes & FileAttributes.Directory) != 0;
                string mime = isDirectory ? _directoryMediaType.ToString() : MediaTypeMap.GetMediaType(fileSysInfo.Extension).ToString();
                string unescapedHref = isDirectory ? fileSysInfo.Name + UriSegmentSeparator : fileSysInfo.Name;
                long size = isDirectory ? 0 : ((FileInfoBase)fileSysInfo).Length;

                yield return new VfsStatEntry
                {
                    Name = fileSysInfo.Name,
                    MTime = fileSysInfo.LastWriteTimeUtc,
                    Mime = mime,
                    Size = size,
                    Href = baseAddress + Uri.EscapeUriString(unescapedHref),
                    Path = fileSysInfo.FullName
                };
            }

            // add special folders when requesting Root url
            IHttpRouteData routeData = Request.GetRouteData();
            if (routeData != null && String.IsNullOrEmpty(routeData.Values["path"] as string))
            {
                foreach (var entry in VfsSpecialFolders.GetEntries(baseAddress))
                {
                    yield return entry;
                }
            }
        }
示例#26
0
        /// <summary>
        /// Create unique etag based on the last modified UTC time
        /// </summary>
        private static EntityTagHeaderValue CreateEntityTag(FileSystemInfoBase sysInfo)
        {
            Contract.Assert(sysInfo != null);
            byte[] etag = BitConverter.GetBytes(sysInfo.LastWriteTimeUtc.Ticks);

            var result = new StringBuilder(2 + etag.Length * 2);
            result.Append("\"");
            foreach (byte b in etag)
            {
                result.AppendFormat("{0:x2}", b);
            }
            result.Append("\"");
            return new EntityTagHeaderValue(result.ToString());
        }
        protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath)
        {
            // Check whether we have a conditional If-None-Match request
            if (IsIfNoneMatchRequest(_currentEtag))
            {
                HttpResponseMessage notModifiedResponse = Request.CreateResponse(HttpStatusCode.NotModified);
                notModifiedResponse.Headers.ETag = _currentEtag;
                return Task.FromResult(notModifiedResponse);
            }

            // Check whether we have a conditional range request containing both a Range and If-Range header field
            bool isRangeRequest = IsRangeRequest(_currentEtag);

            // Generate file response
            try
            {
                _readStream = new RepositoryItemStream(this, GetFileReadStream(localFilePath));
                MediaTypeHeaderValue mediaType = MediaTypeMap.GetMediaType(info.Extension);
                HttpResponseMessage successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK);

                if (isRangeRequest)
                {
                    successFileResponse.Content = new ByteRangeStreamContent(_readStream, Request.Headers.Range, mediaType, BufferSize);
                }
                else
                {
                    successFileResponse.Content = new StreamContent(_readStream, BufferSize);
                    successFileResponse.Content.Headers.ContentType = mediaType;
                }

                // Set etag for the file
                successFileResponse.Headers.ETag = _currentEtag;
                return Task.FromResult(successFileResponse);
            }
            catch (InvalidByteRangeException invalidByteRangeException)
            {
                // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable)
                // including a Content-Range header with the current size.
                Tracer.TraceError(invalidByteRangeException);
                HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException);
                CloseReadStream();
                return Task.FromResult(invalidByteRangeResponse);
            }
            catch (Exception ex)
            {
                // Could not read the file
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
                CloseReadStream();
                return Task.FromResult(errorResponse);
            }
        }
示例#28
0
        protected override Task<HttpResponseMessage> CreateItemGetResponse(FileSystemInfoBase info, string localFilePath)
        {

            // Get current etag
            EntityTagHeaderValue currentEtag = CreateEntityTag(info);
            DateTime lastModified = info.LastWriteTimeUtc;

            // Check whether we have a range request (taking If-Range condition into account)
            bool isRangeRequest = IsRangeRequest(currentEtag);

            // Check whether we have a conditional If-None-Match request
            // Unless it is a range request (see RFC2616 sec 14.35.2 Range Retrieval Requests)
            if (!isRangeRequest && IsIfNoneMatchRequest(currentEtag))
            {
                HttpResponseMessage notModifiedResponse = Request.CreateResponse(HttpStatusCode.NotModified);
                notModifiedResponse.SetEntityTagHeader(currentEtag, lastModified);
                return Task.FromResult(notModifiedResponse);
            }

            // Generate file response
            Stream fileStream = null;
            try
            {
                fileStream = GetFileReadStream(localFilePath);
                MediaTypeHeaderValue mediaType = MediaTypeMap.GetMediaType(info.Extension);
                HttpResponseMessage successFileResponse = Request.CreateResponse(isRangeRequest ? HttpStatusCode.PartialContent : HttpStatusCode.OK);

                if (isRangeRequest)
                {
                    successFileResponse.Content = new ByteRangeStreamContent(fileStream, Request.Headers.Range, mediaType, BufferSize);
                }
                else
                {
                    successFileResponse.Content = new StreamContent(fileStream, BufferSize);
                    successFileResponse.Content.Headers.ContentType = mediaType;
                }

                // Set etag for the file
                successFileResponse.SetEntityTagHeader(currentEtag, lastModified);
                return Task.FromResult(successFileResponse);
            }
            catch (InvalidByteRangeException invalidByteRangeException)
            {
                // The range request had no overlap with the current extend of the resource so generate a 416 (Requested Range Not Satisfiable)
                // including a Content-Range header with the current size.
                Tracer.TraceError(invalidByteRangeException);
                HttpResponseMessage invalidByteRangeResponse = Request.CreateErrorResponse(invalidByteRangeException);
                if (fileStream != null)
                {
                    fileStream.Close();
                }
                return Task.FromResult(invalidByteRangeResponse);
            }
            catch (Exception ex)
            {
                // Could not read the file
                Tracer.TraceError(ex);
                HttpResponseMessage errorResponse = Request.CreateErrorResponse(HttpStatusCode.NotFound, ex);
                if (fileStream != null)
                {
                    fileStream.Close();
                }
                return Task.FromResult(errorResponse);
            }
        }
示例#29
0
 private bool IgnorePath(FileSystemInfoBase fileSystemInfoBase)
 {
     return (_ignoreList.Contains(fileSystemInfoBase.Name)
         || _wildcardIgnoreList.Any((name) => fileSystemInfoBase.Name.EndsWith(name, StringComparison.OrdinalIgnoreCase)));
 }
示例#30
0
 private bool IgnorePath(FileSystemInfoBase fileName)
 {
     return _ignoreList.Contains(fileName.Name);
 }