Esempio n. 1
0
        /// <summary>
        /// 获取文件缓存,失败时创建缓存对象
        /// </summary>
        /// <param name="path"></param>
        /// <param name="fileCache"></param>
        /// <param name="isCopyPath">是否复制请求路径</param>
        /// <returns>是否新的文件缓存数据</returns>
        private byte get(ref FileCacheKey path, out FileCache fileCache, bool isCopyPath)
        {
            byte isNewFileCache = 0;

            Monitor.Enter(fileLock);
            if ((fileCache = files.Get(ref path, null)) == null)
            {
                byte isLock = 0;
                try
                {
                    fileCache = new FileCache();
                    isLock    = 1;
                    if (isCopyPath)
                    {
                        path.CopyPath();
                    }
                    files.UnsafeAdd(ref path, fileCache);
                    return(isNewFileCache = 1);
                }
                finally
                {
                    Monitor.Exit(fileLock);
                    if (isNewFileCache == 0 && isLock != 0)
                    {
                        fileCache.PulseAll();
                    }
                }
            }
            else
            {
                Monitor.Exit(fileLock);
            }
            return(0);
        }
Esempio n. 2
0
        private void removeOnly(ref FileCacheKey path)
        {
            FileCache fileCache;

            Monitor.Enter(fileLock);
            files.Remove(ref path, out fileCache);
            Monitor.Exit(fileLock);
        }
Esempio n. 3
0
        private FileCache get(ref FileCacheKey path)
        {
            Monitor.Enter(fileLock);
            FileCache file = files.Get(ref path, null);

            Monitor.Exit(fileLock);
            return(file);
        }
Esempio n. 4
0
        private FileCache get(ref FileCacheKey path)
        {
            fileLock.Enter();
            FileCache file = files.Get(ref path, null);

            fileLock.Exit();
            return(file);
        }
Esempio n. 5
0
        private void removeOnly(ref FileCacheKey path)
        {
            FileCache fileCache;

            fileLock.Enter();
            files.Remove(ref path, out fileCache);
            fileLock.Exit();
        }
Esempio n. 6
0
        /// <summary>
        /// 删除文件缓存
        /// </summary>
        /// <param name="path"></param>
        private void remove(ref FileCacheKey path)
        {
            FileCache file;

            Monitor.Enter(fileLock);
            if (files.Remove(ref path, out file))
            {
                freeCacheSize += file.Size;
            }
            Monitor.Exit(fileLock);
        }
Esempio n. 7
0
        /// <summary>
        /// 文件更新事件
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private unsafe void fileChanged(object sender, FileSystemEventArgs e)
        {
            try
            {
                string fullPath = e.FullPath;
                if (fullPath.Length - path.Length <= fileWatcherBuffer.Length)
                {
                    char directorySeparatorChar = Path.DirectorySeparatorChar;
                    Monitor.Enter(fileWatcherLock);
                    try
                    {
                        fixed(byte *bufferFixed = fileWatcherBuffer)
                        fixed(char *pathFixed = fullPath)
                        {
                            byte *write = bufferFixed;
                            char *start = pathFixed + path.Length, end = pathFixed + fullPath.Length;

                            while (start != end)
                            {
                                char value = *start++;
                                if ((uint)(value - 'A') < 26)
                                {
                                    *write++ = (byte)(value | 0x20);
                                }
                                else
                                {
                                    *write++ = value == directorySeparatorChar ? (byte)'/' : (byte)value;
                                }
                            }
                            FileCacheKey key = new FileCacheKey(identity, fileWatcherBuffer, 0, (int)(write - bufferFixed));

                            FileCacheQueue.Remove(ref key);
                        }
                    }
                    finally { Monitor.Exit(fileWatcherLock); }
                }
            }
            catch (Exception error)
            {
                AutoCSer.LogHelper.Exception(error, null, LogLevel.Exception | LogLevel.AutoCSer);
            }
        }
Esempio n. 8
0
 /// <summary>
 /// 设置文件缓存
 /// </summary>
 /// <param name="path"></param>
 /// <param name="fileCache"></param>
 /// <param name="fileSize"></param>
 private void set(ref FileCacheKey path, FileCache fileCache, int fileSize)
 {
     Monitor.Enter(fileLock);
     try
     {
         fileCache.Size = fileSize;
         FileCache oldFileCache = files.Set(ref path, fileCache);
         freeCacheSize -= fileSize;
         if (oldFileCache == null)
         {
             while (freeCacheSize < 0 && files.Count > 1)
             {
                 freeCacheSize += files.UnsafePopValue().Size;
             }
         }
         else if (oldFileCache != fileCache)
         {
             freeCacheSize += oldFileCache.Size;
         }
     }
     finally { Monitor.Exit(fileLock); }
 }
Esempio n. 9
0
 internal static void Set(ref FileCacheKey path, FileCache fileCache, int fileSize)
 {
     queues[path.HashCode & 0xff].set(ref path, fileCache, fileSize);
 }
Esempio n. 10
0
 internal static void RemoveOnly(ref FileCacheKey path)
 {
     queues[path.HashCode & 0xff].removeOnly(ref path);
 }
Esempio n. 11
0
 internal static byte Get(ref FileCacheKey path, out FileCache fileCache, bool isCopyPath)
 {
     return(queues[path.HashCode & 0xff].get(ref path, out fileCache, isCopyPath));
 }
Esempio n. 12
0
 internal static FileCache Get(ref FileCacheKey path)
 {
     return(queues[path.HashCode & 0xff].get(ref path));
 }
Esempio n. 13
0
        /// <summary>
        /// HTTP文件请求处理
        /// </summary>
        /// <param name="path">请求路径</param>
        /// <param name="ifModifiedSince">文件修改时间</param>
        /// <param name="response">HTTP响应输出</param>
        /// <param name="isCopyPath">是否复制请求路径</param>
        /// <returns>文件缓存</returns>
        protected unsafe FileCache file(byte[] path, SubArray <byte> ifModifiedSince, ref Http.Response response, bool isCopyPath)
        {
            string cacheFileName = null;

            try
            {
                if (path.Length != 0 && WorkPath.Length + path.Length <= AutoCSer.IO.File.MaxFullNameLength)
                {
                    byte[] contentType = null;
                    bool   isCompress  = true;
                    fixed(byte *pathFixed = path)
                    {
                        byte *pathStart = pathFixed, pathEnd = pathStart + path.Length;

                        if (isFile(pathEnd, ref contentType, ref isCompress) == 0)
                        {
                            if (*pathStart == '/')
                            {
                                ++pathStart;
                            }
                            for (byte *formatStart = pathStart; formatStart != pathEnd; ++formatStart)
                            {
                                if (*formatStart == ':')
                                {
                                    response = Http.Response.Blank;
                                    return(null);
                                }
                            }
                            int          cachePathLength = (int)(pathEnd - pathStart);
                            FileCacheKey cacheKey        = new FileCacheKey(pathIdentity, path, (int)(pathStart - pathFixed), cachePathLength);
                            FileCache    fileCache       = FileCacheQueue.Get(ref cacheKey);
                            if (fileCache == null)
                            {
                                cacheFileName = StringExtension.FastAllocateString(WorkPath.Length + cachePathLength);
                                fixed(char *nameFixed = cacheFileName)
                                {
                                    char *write = nameFixed + WorkPath.Length;
                                    char  directorySeparatorChar = Path.DirectorySeparatorChar;

                                    StringExtension.CopyNotNull(WorkPath, nameFixed);
                                    for (byte *start = pathStart; start != pathEnd; ++start)
                                    {
                                        *write++ = *start == '/' ? directorySeparatorChar : (char)*start;
                                    }
                                }
                                FileInfo file = new FileInfo(cacheFileName);
                                if (file.Exists)
                                {
                                    string fileName = file.FullName;
                                    if (fileName.Length > WorkPath.Length && WorkPath.equalCaseNotNull(fileName, WorkPath.Length))
                                    {
                                        if (fileName.Length <= AutoCSer.IO.File.MaxFullNameLength && file.Length <= FileCacheQueue.MaxFileSize)
                                        {
                                            if (FileCacheQueue.Get(ref cacheKey, out fileCache, isCopyPath) != 0)
                                            {
                                                try
                                                {
                                                    fileCache.LastModified = file.LastWriteTimeUtc.UniversalNewBytes();
                                                    int             extensionNameLength = (int)(pathEnd - getExtensionNameStart(pathEnd));
                                                    SubArray <byte> fileData            = readCacheFile(new SubString {
                                                        String = fileName, Start = fileName.Length - extensionNameLength, Length = extensionNameLength
                                                    });
                                                    FileCacheQueue.Set(ref cacheKey, fileCache, fileCache.Set(ref fileData, contentType, cacheControl, isCompress));
                                                    if (ifModifiedSince.Length == fileCache.LastModified.Length)
                                                    {
                                                        fixed(byte *ifModifiedSinceFixed = ifModifiedSince.Array)
                                                        {
                                                            if (Memory.EqualNotNull(fileCache.LastModified, ifModifiedSinceFixed + ifModifiedSince.Start, ifModifiedSince.Length))
                                                            {
                                                                response = Http.Response.NotChanged304;
                                                                return(null);
                                                            }
                                                        }
                                                    }
                                                }
                                                finally
                                                {
                                                    if (fileCache.IsData == 0)
                                                    {
                                                        fileCache.PulseAll();
                                                        fileCache = null;
                                                        FileCacheQueue.RemoveOnly(ref cacheKey);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if (ifModifiedSince.Length == Date.ToByteLength && Date.UniversalByteEquals(file.LastWriteTimeUtc, ifModifiedSince) == 0)
                                            {
                                                response = Http.Response.NotChanged304;
                                                return(null);
                                            }
                                            response = Http.Response.Get();
                                            //response.State = Http.ResponseState.Ok200;
                                            response.SetBodyFile(file);
                                            response.CacheControl = cacheControl;
                                            response.ContentType  = contentType;
                                            response.SetLastModified(file.LastWriteTimeUtc.UniversalNewBytes());
                                            return(null);
                                        }
                                    }
                                }
                            }
                            return(fileCache);
                        }
                    }
                }
            }
            catch (Exception error)
            {
                RegisterServer.TcpServer.Log.Add(AutoCSer.Log.LogType.Error, error, cacheFileName);
            }
            return(null);
        }
Esempio n. 14
0
        /// <summary>
        /// HTTP文件请求处理
        /// </summary>
        /// <param name="header">请求头部</param>
        /// <param name="response">HTTP响应输出</param>
        /// <returns>文件缓存</returns>
        protected unsafe FileCache file(Http.Header header, ref Http.Response response)
        {
            SubArray <byte> path          = header.Path;
            string          cacheFileName = null;

            try
            {
                if (path.Length != 0 && WorkPath.Length + path.Length <= AutoCSer.IO.File.MaxFullNameLength)
                {
                    byte[] contentType = null;
                    bool   isCompress  = true;
                    fixed(byte *pathFixed = path.GetFixedBuffer())
                    {
                        byte *pathStart = pathFixed + path.Start, pathEnd = pathStart + path.Length;

                        if (isFile(pathEnd, ref contentType, ref isCompress) == 0)
                        {
                            if (*pathStart == '/')
                            {
                                ++pathStart;
                            }
                            for (byte *formatStart = pathStart; formatStart != pathEnd; ++formatStart)
                            {
                                if (*formatStart == ':')
                                {
                                    response = Http.Response.Blank;
                                    return(null);
                                }
#if !MONO
                                if ((uint)(*formatStart - 'A') < 26)
                                {
                                    *formatStart |= 0x20;
                                }
#endif
                            }
                            int          cachePathLength = (int)(pathEnd - pathStart);
                            FileCacheKey cacheKey        = new FileCacheKey(pathIdentity, path.Array, (int)(pathStart - pathFixed), cachePathLength);
                            FileCache    fileCache       = FileCacheQueue.Get(ref cacheKey);
                            if (fileCache == null)
                            {
                                cacheFileName = StringExtension.FastAllocateString(WorkPath.Length + cachePathLength);
                                fixed(char *nameFixed = cacheFileName)
                                {
                                    char *write = nameFixed + WorkPath.Length;
                                    char  directorySeparatorChar = Path.DirectorySeparatorChar;

                                    StringExtension.CopyNotNull(WorkPath, nameFixed);
                                    for (byte *start = pathStart; start != pathEnd; ++start)
                                    {
                                        *write++ = *start == '/' ? directorySeparatorChar : (char)*start;
                                    }
                                }
                                FileInfo file = new FileInfo(cacheFileName);
                                bool     isFileExists = file.Exists, isCopyPath = true;
                                if (!isFileExists && cacheFileName.IndexOf('%') >= WorkPath.Length)
                                {
                                    cacheKey.CopyPath();
                                    isCopyPath = false;
                                    string newPath = AutoCSer.Net.Http.Header.UnescapeUtf8(pathStart, cachePathLength, path.Array, (int)(pathStart - pathFixed));
                                    if (Path.DirectorySeparatorChar != '/')
                                    {
                                        newPath.replaceNotNull('/', Path.DirectorySeparatorChar);
                                    }
                                    FileInfo newFile = new FileInfo(WorkPath + newPath);
                                    if (newFile.Exists)
                                    {
                                        file         = newFile;
                                        isFileExists = true;
                                    }
                                }
                                if (isFileExists)
                                {
                                    string fileName = file.FullName;
                                    if (fileName.Length > WorkPath.Length && WorkPath.equalCaseNotNull(fileName, WorkPath.Length))
                                    {
                                        if (fileName.Length <= AutoCSer.IO.File.MaxFullNameLength && file.Length <= FileCacheQueue.MaxFileSize)
                                        {
                                            if (FileCacheQueue.Get(ref cacheKey, out fileCache, isCopyPath) != 0)
                                            {
                                                try
                                                {
                                                    fileCache.LastModified = file.LastWriteTimeUtc.UniversalNewBytes();
                                                    int             extensionNameLength = (int)(pathEnd - getExtensionNameStart(pathEnd));
                                                    SubArray <byte> fileData            = readCacheFile(new SubString {
                                                        String = fileName, Start = fileName.Length - extensionNameLength, Length = extensionNameLength
                                                    });
                                                    FileCacheQueue.Set(ref cacheKey, fileCache, fileCache.Set(ref fileData, contentType, cacheControl, isCompress));
                                                    if ((header.Flag & Http.HeaderFlag.IsSetIfModifiedSince) != 0 && header.IfModifiedSinceIndex.Length == fileCache.LastModified.Length)
                                                    {
                                                        if (AutoCSer.Memory.Common.EqualNotNull(fileCache.LastModified, pathFixed + header.Buffer.StartIndex + header.IfModifiedSinceIndex.StartIndex, header.IfModifiedSinceIndex.Length))
                                                        {
                                                            response = Http.Response.NotChanged304;
                                                            return(null);
                                                        }
                                                    }
                                                }
                                                finally
                                                {
                                                    if (fileCache.IsData == 0)
                                                    {
                                                        fileCache.PulseAll();
                                                        fileCache = null;
                                                        FileCacheQueue.RemoveOnly(ref cacheKey);
                                                    }
                                                }
                                            }
                                        }
                                        else
                                        {
                                            if ((header.Flag & Http.HeaderFlag.IsSetIfModifiedSince) != 0 && header.IfModifiedSinceIndex.Length == Date.ToByteLength && Date.UniversalByteEquals(file.LastWriteTimeUtc, header.IfModifiedSince) == 0)
                                            {
                                                response = Http.Response.NotChanged304;
                                                return(null);
                                            }
                                            response = Http.Response.Get();
                                            //response.State = Http.ResponseState.Ok200;
                                            response.SetBodyFile(file);
                                            response.CacheControl = cacheControl;
                                            response.ContentType  = contentType;
                                            response.SetLastModified(file.LastWriteTimeUtc.UniversalNewBytes());
                                            return(null);
                                        }
                                    }
                                }
                            }
                            return(fileCache);
                        }
                    }
                }
            }
            catch (Exception error)
            {
                RegisterServer.TcpServer.Log.Exception(error, cacheFileName, LogLevel.Exception | LogLevel.AutoCSer);
            }
            return(null);
        }