internal static void SaveCache(string cachePath, WebCache webCache) { if (cachePath == null || webCache == null) { return; } using (var stream = BlobStore.OpenWrite(cachePath)) { using (var gz = new GZipStream2(stream, CompressionMode.Compress)) using (var bw = new BinaryWriter(gz, Encoding.UTF8)) { Sanity.AssertFastWriteByte(gz.BaseStream); bw.Write((byte)52); bw.WriteNullableString(webCache.ContentType); bw.Write(webCache.DateRetrieved.Ticks); bw.Write(webCache.ErrorCode); bw.WriteNullableString(webCache.ExceptionMessage); bw.WriteNullableString(webCache.ExceptionType); bw.Write(webCache.Headers != null ? webCache.Headers.Count : 0); if (webCache.Headers != null) { foreach (var item in webCache.Headers) { bw.Write(item.Key); bw.Write(item.Value); } } bw.Write(webCache.Cookies != null ? webCache.Cookies.Count : 0); if (webCache.Cookies != null) { foreach (var item in webCache.Cookies) { bw.Write(item.Key); bw.Write(item.Value); } } bw.Write((byte)webCache.DataType); bw.WriteNullableString(webCache.RedirectUrl != null ? webCache.RedirectUrl.AbsoluteUri : null); bw.WriteNullableString(webCache.Url != null ? webCache.Url.AbsoluteUri : null); bw.WriteNullableString(webCache.Result); bw.WriteNullableString(webCache.JsExecutionResults); bw.WriteNullableString(webCache.PageUrl?.AbsoluteUri); } } if (lastFlush == null) { lastFlush = Stopwatch.StartNew(); } else if (lastFlush.ElapsedMilliseconds > Configuration_FlushIntervalMs) { BlobStore.FlushDirectory(Path.GetDirectoryName(cachePath)); #if NET35 lastFlush.Stop(); lastFlush.Start(); #else lastFlush.Restart(); #endif } }
internal static WebCache TryReadCacheFile(string path, bool onlyIfFailed = false, bool fromFileSystem = false) { #if STANDALONE HttpUtils.EnsureInitialized(); #else Utils.EnsureInitialized(); #endif Stream stream; if (fromFileSystem) { if (!File.Exists(path)) { return(null); } try { stream = File.Open(path, FileMode.Open, FileAccess.Read, FileShare.Delete | FileShare.Read); } catch (FileNotFoundException) { return(null); } } else { if (!BlobStore.Exists(path)) { return(null); } try { stream = BlobStore.OpenRead(path); } catch (FileNotFoundException) { return(null); } } Sanity.AssertFastReadByte(stream); using (stream) { var q = stream.ReadByte(); if (q == 0xEF) { stream.ReadByte(); stream.ReadByte(); using (var sr = new StreamReader(stream, Encoding.UTF8)) { var qq = JsonConvert.DeserializeObject <WebCache>(sr.ReadToEnd()); stream.Dispose(); SaveCache(path, qq); return(qq); } } if (q != 0x1F) { throw new ArgumentException("Invalid cache file."); } stream.Seek(0, SeekOrigin.Begin); var gz = new GZipStream2(stream, CompressionMode.Decompress); q = gz.ReadByte(); if (q < 50 || q > 80) { throw new ArgumentException("Invalid cache file."); } using (var br = new BinaryReader(gz, Encoding.UTF8)) { Sanity.AssertFastReadByte(br.BaseStream); var cache = new WebCache(); cache.ContentType = br.ReadNullableString(); cache.DateRetrieved = new DateTime(br.ReadInt64(), DateTimeKind.Utc); cache.ErrorCode = br.ReadInt32(); cache.ExceptionMessage = br.ReadNullableString(); cache.ExceptionType = br.ReadNullableString(); if (onlyIfFailed && cache.ExceptionType == null) { return(null); } var headerCount = br.ReadInt32(); cache.Headers = new Dictionary <string, string>(headerCount); for (int i = 0; i < headerCount; i++) { var name = br.ReadString(); var value = br.ReadString(); cache.Headers[name] = value; } var cookieCount = br.ReadInt32(); cache.Cookies = new Dictionary <string, string>(cookieCount); for (int i = 0; i < cookieCount; i++) { var name = br.ReadString(); var value = br.ReadString(); cache.Cookies[name] = value; } cache.DataType = (WebCacheDataType)br.ReadByte(); cache.RedirectUrl = br.ReadNullableString()?.AsLazyUri(); var p = br.ReadNullableString(); cache.Url = p != null ? new LazyUri(p) : null; cache.Result = br.ReadNullableString(); if (q >= 51) { cache.JsExecutionResults = br.ReadNullableString(); if (q >= 52) { var pp = br.ReadNullableString(); cache.PageUrl = pp != null ? new LazyUri(pp) : null; } } return(cache); } } }