internal RequestCacheEntry(_WinInetCache.Entry entry, bool isPrivateEntry) { this.m_IsPrivateEntry = isPrivateEntry; this.m_StreamSize = (entry.Info.SizeHigh << 0x20) | entry.Info.SizeLow; this.m_ExpiresUtc = entry.Info.ExpireTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong()); this.m_HitCount = entry.Info.HitRate; this.m_LastAccessedUtc = entry.Info.LastAccessTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.LastAccessTime.ToLong()); this.m_LastModifiedUtc = entry.Info.LastModifiedTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong()); this.m_LastSynchronizedUtc = entry.Info.LastSyncTime.IsNull ? DateTime.MinValue : DateTime.FromFileTimeUtc(entry.Info.LastSyncTime.ToLong()); this.m_MaxStale = TimeSpan.FromSeconds((double)entry.Info.U.ExemptDelta); if (this.m_MaxStale == WinInetCache.s_MaxTimeSpanForInt32) { this.m_MaxStale = TimeSpan.MaxValue; } this.m_UsageCount = entry.Info.UseCount; this.m_IsPartialEntry = (entry.Info.EntryType & _WinInetCache.EntryType.Sparse) != 0; }
// This ctor is for IERequestCache class only that relies on WinInet cache API. internal RequestCacheEntry(_WinInetCache.Entry entry, bool isPrivateEntry) { m_IsPrivateEntry = isPrivateEntry; m_StreamSize = ((long)entry.Info.SizeHigh << 32) | (long)((ulong)entry.Info.SizeLow); m_ExpiresUtc = (entry.Info.ExpireTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong())); m_HitCount = entry.Info.HitRate; m_LastAccessedUtc = (entry.Info.LastAccessTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.LastAccessTime.ToLong())); m_LastModifiedUtc = (entry.Info.LastModifiedTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong())); m_LastSynchronizedUtc = (entry.Info.LastSyncTime.IsNull? DateTime.MinValue: DateTime.FromFileTimeUtc(entry.Info.LastSyncTime.ToLong())); m_MaxStale = TimeSpan.FromSeconds(entry.Info.U.ExemptDelta); if (m_MaxStale == Microsoft.Win32.WinInetCache.s_MaxTimeSpanForInt32) { m_MaxStale = TimeSpan.MaxValue; } m_UsageCount = entry.Info.UseCount; m_IsPartialEntry = (entry.Info.EntryType & _WinInetCache.EntryType.Sparse) != 0; }
protected override void Dispose(bool disposing) { if ((Interlocked.Exchange(ref this.m_Disposed, 1) == 0) && (this.m_Entry != null)) { System.Net.TriState unspecified; lock (this.m_Entry) { if (this.m_CallNesting == 0) { base.Dispose(disposing); } else { this.m_Event = new ManualResetEvent(false); } } if (disposing && (this.m_Event != null)) { using (this.m_Event) { this.m_Event.WaitOne(); lock (this.m_Entry) { } } base.Dispose(disposing); } if (this.m_StreamSize < 0L) { if (this.m_Aborted) { if (this.m_OneWriteSucceeded) { unspecified = System.Net.TriState.Unspecified; } else { unspecified = System.Net.TriState.False; } } else { unspecified = System.Net.TriState.True; } } else if (!this.m_OneWriteSucceeded) { unspecified = System.Net.TriState.False; } else if (this.m_StreamSize > 0L) { unspecified = System.Net.TriState.Unspecified; } else { unspecified = System.Net.TriState.True; } if (unspecified == System.Net.TriState.False) { try { if (Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_no_commit", new object[] { "WinInetWriteStream.Close()" })); } System.IO.File.Delete(this.m_Entry.Filename); } catch (Exception exception) { if (((exception is ThreadAbortException) || (exception is StackOverflowException)) || (exception is OutOfMemoryException)) { throw; } if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_error_deleting_filename", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Filename })); } } finally { _WinInetCache.Status status = _WinInetCache.Remove(this.m_Entry); if (((status != _WinInetCache.Status.Success) && (status != _WinInetCache.Status.FileNotFound)) && Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_delete_failed", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Key, new Win32Exception((int) this.m_Entry.Error).Message })); } this.m_Entry = null; } } else { this.m_Entry.OriginalUrl = null; if (unspecified == System.Net.TriState.Unspecified) { if (((this.m_Entry.MetaInfo == null) || (this.m_Entry.MetaInfo.Length == 0)) || ((this.m_Entry.MetaInfo != "\r\n") && (this.m_Entry.MetaInfo.IndexOf("\r\n\r\n", StringComparison.Ordinal) == -1))) { this.m_Entry.MetaInfo = "\r\n~SPARSE_ENTRY:\r\n"; } else { this.m_Entry.MetaInfo = this.m_Entry.MetaInfo + "~SPARSE_ENTRY:\r\n"; } } if (_WinInetCache.Commit(this.m_Entry) != _WinInetCache.Status.Success) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_commit_failed", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Key, new Win32Exception((int) this.m_Entry.Error).Message })); } try { System.IO.File.Delete(this.m_Entry.Filename); } catch (Exception exception2) { if (((exception2 is ThreadAbortException) || (exception2 is StackOverflowException)) || (exception2 is OutOfMemoryException)) { throw; } if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_error_deleting_filename", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Filename })); } } if (this.m_IsThrow) { Win32Exception innerException = new Win32Exception((int) this.m_Entry.Error); throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException); } } else { if (Logging.On) { if ((this.m_StreamSize > 0L) || ((this.m_StreamSize < 0L) && this.m_Aborted)) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_committed_as_partial", new object[] { "WinInetWriteStream.Close()", this.m_Entry.Key, (this.m_StreamSize > 0L) ? this.m_StreamSize.ToString(CultureInfo.CurrentCulture) : SR.GetString("net_log_unknown") })); } Logging.PrintInfo(Logging.RequestCache, "WinInetWriteStream.Close(), Key = " + this.m_Entry.Key + ", Commit Status = " + this.m_Entry.Error.ToString()); } if ((this.m_Entry.Info.EntryType & _WinInetCache.EntryType.StickyEntry) == _WinInetCache.EntryType.StickyEntry) { if (_WinInetCache.Update(this.m_Entry, _WinInetCache.Entry_FC.ExemptDelta) != _WinInetCache.Status.Success) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_update_failed", new object[] { "WinInetWriteStream.Close(), Key = " + this.m_Entry.Key, new Win32Exception((int) this.m_Entry.Error).Message })); } if (this.m_IsThrow) { Win32Exception exception4 = new Win32Exception((int) this.m_Entry.Error); throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { exception4.Message }), exception4); } return; } if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_max_stale_and_update_status", new object[] { "WinInetWriteFile.Close()", this.m_Entry.Info.U.ExemptDelta, this.m_Entry.Error.ToString() })); } } base.Dispose(disposing); } } } }
internal WriteStream(_WinInetCache.Entry entry, bool isThrow, long streamSize, bool async) : base(entry.Filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 0x1000, async) { this.m_Entry = entry; this.m_IsThrow = isThrow; this.m_StreamSize = streamSize; this.m_OneWriteSucceeded = streamSize == 0L; this.m_ReadTimeout = this.m_WriteTimeout = -1; }
private Stream GetWriteStream(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow) { if (Logging.On) { Logging.Enter(Logging.RequestCache, "WinInetCache.Store()", "Key = " + key); } if (key == null) { throw new ArgumentNullException("key"); } if (!base.CanWrite) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.Store()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) })); } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Store"); } if (isThrow) { throw new InvalidOperationException(SR.GetString("net_cache_access_denied", new object[] { "Write" })); } return null; } _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength) { Key = key, OptionalLength = (contentLength < 0L) ? 0 : ((contentLength > 0x7fffffffL) ? 0x7fffffff : ((int) contentLength)) }; entry.Info.ExpireTime = _WinInetCache.FILETIME.Zero; if ((expiresUtc != DateTime.MinValue) && (expiresUtc > s_MinDateTimeUtcForFileTimeUtc)) { entry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc()); } entry.Info.LastModifiedTime = _WinInetCache.FILETIME.Zero; if ((lastModifiedUtc != DateTime.MinValue) && (lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc)) { entry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc()); } entry.Info.EntryType = _WinInetCache.EntryType.NormalEntry; if (maxStale > TimeSpan.Zero) { if (maxStale >= s_MaxTimeSpanForInt32) { maxStale = s_MaxTimeSpanForInt32; } entry.Info.U.ExemptDelta = (int) maxStale.TotalSeconds; entry.Info.EntryType = _WinInetCache.EntryType.StickyEntry; } entry.MetaInfo = this.CombineMetaInfo(entryMetadata, systemMetadata); entry.FileExt = "cache"; if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_expected_length", new object[] { entry.OptionalLength })); Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_last_modified", new object[] { entry.Info.LastModifiedTime.IsNull ? "0" : DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong()).ToString("r") })); Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_expires", new object[] { entry.Info.ExpireTime.IsNull ? "0" : DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong()).ToString("r") })); Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_max_stale", new object[] { (maxStale > TimeSpan.Zero) ? ((int) maxStale.TotalSeconds).ToString() : "n/a" })); if (Logging.IsVerbose(Logging.RequestCache)) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_dumping_metadata")); if (entry.MetaInfo.Length == 0) { Logging.PrintInfo(Logging.RequestCache, "<null>"); } else { if (entryMetadata != null) { foreach (string str in entryMetadata) { Logging.PrintInfo(Logging.RequestCache, str.TrimEnd(RequestCache.LineSplits)); } } Logging.PrintInfo(Logging.RequestCache, "------"); if (systemMetadata != null) { foreach (string str2 in systemMetadata) { Logging.PrintInfo(Logging.RequestCache, str2.TrimEnd(RequestCache.LineSplits)); } } } } } _WinInetCache.CreateFileName(entry); Stream @null = Stream.Null; if (entry.Error != _WinInetCache.Status.Success) { if (Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_create_failed", new object[] { new Win32Exception((int) entry.Error).Message })); Logging.Exit(Logging.RequestCache, "WinInetCache.Store"); } if (isThrow) { Win32Exception innerException = new Win32Exception((int) entry.Error); throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException); } return null; } try { @null = new WriteStream(entry, isThrow, contentLength, this.async); } catch (Exception exception2) { if (((exception2 is ThreadAbortException) || (exception2 is StackOverflowException)) || (exception2 is OutOfMemoryException)) { throw; } if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_exception", new object[] { "WinInetCache.Store()", exception2 })); Logging.Exit(Logging.RequestCache, "WinInetCache.Store"); } if (isThrow) { throw; } return null; } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Store", "Filename = " + entry.Filename); } return @null; }
private bool UpdateInfo(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow) { if (key == null) { throw new ArgumentNullException("key"); } if (Logging.On) { Logging.Enter(Logging.RequestCache, "WinInetCache.Update", "Key = " + key); } if (!base.CanWrite) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.Update()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) })); } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Update()"); } if (isThrow) { throw new InvalidOperationException(SR.GetString("net_cache_access_denied", new object[] { "Write" })); } return false; } _WinInetCache.Entry newEntry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); _WinInetCache.Entry_FC none = _WinInetCache.Entry_FC.None; if ((expiresUtc != DateTime.MinValue) && (expiresUtc > s_MinDateTimeUtcForFileTimeUtc)) { none |= _WinInetCache.Entry_FC.Exptime; newEntry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc()); if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_set_expires", new object[] { expiresUtc.ToString("r") })); } } if ((lastModifiedUtc != DateTime.MinValue) && (lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc)) { none |= _WinInetCache.Entry_FC.Modtime; newEntry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc()); if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_set_last_modified", new object[] { lastModifiedUtc.ToString("r") })); } } if ((lastSynchronizedUtc != DateTime.MinValue) && (lastSynchronizedUtc > s_MinDateTimeUtcForFileTimeUtc)) { none |= _WinInetCache.Entry_FC.Synctime; newEntry.Info.LastSyncTime = new _WinInetCache.FILETIME(lastSynchronizedUtc.ToFileTimeUtc()); if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_set_last_synchronized", new object[] { lastSynchronizedUtc.ToString("r") })); } } if (maxStale != TimeSpan.MinValue) { none |= _WinInetCache.Entry_FC.ExemptDelta | _WinInetCache.Entry_FC.Attribute; newEntry.Info.EntryType = _WinInetCache.EntryType.NormalEntry; if (maxStale >= TimeSpan.Zero) { if (maxStale >= s_MaxTimeSpanForInt32) { maxStale = s_MaxTimeSpanForInt32; } newEntry.Info.EntryType = _WinInetCache.EntryType.StickyEntry; newEntry.Info.U.ExemptDelta = (int) maxStale.TotalSeconds; if (Logging.On) { object[] args = new object[] { ((int) maxStale.TotalSeconds).ToString() }; Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_enable_max_stale", args)); } } else { newEntry.Info.U.ExemptDelta = 0; if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_disable_max_stale")); } } } newEntry.MetaInfo = this.CombineMetaInfo(entryMetadata, systemMetadata); if (newEntry.MetaInfo.Length != 0) { none |= _WinInetCache.Entry_FC.Headerinfo; if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_dumping")); if (Logging.IsVerbose(Logging.RequestCache)) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_dumping")); if (entryMetadata != null) { foreach (string str in entryMetadata) { Logging.PrintInfo(Logging.RequestCache, str.TrimEnd(RequestCache.LineSplits)); } } Logging.PrintInfo(Logging.RequestCache, "------"); if (systemMetadata != null) { foreach (string str2 in systemMetadata) { Logging.PrintInfo(Logging.RequestCache, str2.TrimEnd(RequestCache.LineSplits)); } } } } } _WinInetCache.Update(newEntry, none); if (newEntry.Error != _WinInetCache.Status.Success) { if (Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_update_failed", new object[] { "WinInetCache.Update()", newEntry.Key, new Win32Exception((int) newEntry.Error).Message })); Logging.Exit(Logging.RequestCache, "WinInetCache.Update()"); } if (isThrow) { Win32Exception innerException = new Win32Exception((int) newEntry.Error); throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException); } return false; } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Update()", "Status = " + newEntry.Error.ToString()); } return true; }
internal bool TryRemove(string key, bool forceRemove) { if (key == null) { throw new ArgumentNullException("key"); } if (!base.CanWrite) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.TryRemove()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) })); } return false; } _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); if ((_WinInetCache.Remove(entry) == _WinInetCache.Status.Success) || (entry.Error == _WinInetCache.Status.FileNotFound)) { if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() })); } return true; } if (!forceRemove) { if (Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString("net_log_cache_key_remove_failed_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() })); } return false; } if (_WinInetCache.LookupInfo(entry) == _WinInetCache.Status.Success) { while (entry.Info.UseCount != 0) { if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() })); } if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_usecount_file", new object[] { "WinInetCache.TryRemove()", entry.Info.UseCount, entry.Filename })); } if (!UnsafeNclNativeMethods.UnsafeWinInetCache.UnlockUrlCacheEntryFileW(key, 0)) { break; } _WinInetCache.Status info = _WinInetCache.LookupInfo(entry); } } _WinInetCache.Remove(entry); if ((entry.Error != _WinInetCache.Status.Success) && (_WinInetCache.LookupInfo(entry) == _WinInetCache.Status.FileNotFound)) { entry.Error = _WinInetCache.Status.Success; } if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.TryRemove()", key, entry.Error.ToString() })); } return (entry.Error == _WinInetCache.Status.Success); }
internal override void Remove(string key) { if (key == null) { throw new ArgumentNullException("key"); } if (!base.CanWrite) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_operation_failed_with_error", new object[] { "WinInetCache.Remove()", SR.GetString("net_cache_access_denied", new object[] { "Write" }) })); } } else { _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); if ((_WinInetCache.Remove(entry) != _WinInetCache.Status.Success) && (entry.Error != _WinInetCache.Status.FileNotFound)) { Win32Exception innerException = new Win32Exception((int) entry.Error); if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_cannot_remove", new object[] { "WinInetCache.Remove()", key, innerException.Message })); } throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException); } if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_key_status", new object[] { "WinInetCache.Remove(), ", key, entry.Error.ToString() })); } } }
private unsafe Stream Lookup(string key, out RequestCacheEntry cacheEntry, bool isThrow) { if (Logging.On) { Logging.Enter(Logging.RequestCache, "WinInetCache.Retrieve", "key = " + key); } if (key == null) { throw new ArgumentNullException("key"); } Stream @null = Stream.Null; SafeUnlockUrlCacheEntryFile handle = null; _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); try { handle = _WinInetCache.LookupFile(entry); if (entry.Error == _WinInetCache.Status.Success) { if (Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString("net_log_cache_filename", new object[] { "WinInetCache.Retrieve()", entry.Filename, entry.Error })); } cacheEntry = new RequestCacheEntry(entry, base.IsPrivateCache); if ((entry.MetaInfo != null) && (entry.MetaInfo.Length != 0)) { int startIndex = 0; int length = entry.MetaInfo.Length; StringCollection strings = new StringCollection(); fixed (char* str2 = ((char*) entry.MetaInfo)) { char* chPtr = str2; for (int i = 0; i < length; i++) { if ((((i == startIndex) && ((i + 2) < length)) && (chPtr[i] == '~')) && (((chPtr[i + 1] == 'U') || (chPtr[i + 1] == 'u')) && (chPtr[i + 2] == ':'))) { while ((i < length) && (chPtr[++i] != '\n')) { } startIndex = i + 1; } else if (((i + 1) == length) || (chPtr[i] == '\n')) { string str = entry.MetaInfo.Substring(startIndex, ((chPtr[i - 1] == '\r') ? (i - 1) : (i + 1)) - startIndex); if ((str.Length == 0) && (cacheEntry.EntryMetadata == null)) { cacheEntry.EntryMetadata = strings; strings = new StringCollection(); } else if ((cacheEntry.EntryMetadata != null) && str.StartsWith("~SPARSE_ENTRY:", StringComparison.Ordinal)) { cacheEntry.IsPartialEntry = true; } else { strings.Add(str); } startIndex = i + 1; } } } if (cacheEntry.EntryMetadata == null) { cacheEntry.EntryMetadata = strings; } else { cacheEntry.SystemMetadata = strings; } } @null = new ReadStream(entry, handle, this.async); } else { if (handle != null) { handle.Close(); } cacheEntry = new RequestCacheEntry(); cacheEntry.IsPrivateEntry = base.IsPrivateCache; if (entry.Error != _WinInetCache.Status.FileNotFound) { if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_lookup_failed", new object[] { "WinInetCache.Retrieve()", new Win32Exception((int) entry.Error).Message })); } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()"); } if (isThrow) { Win32Exception innerException = new Win32Exception((int) entry.Error); throw new IOException(SR.GetString("net_cache_retrieve_failure", new object[] { innerException.Message }), innerException); } return null; } } } catch (Exception exception2) { if (((exception2 is ThreadAbortException) || (exception2 is StackOverflowException)) || (exception2 is OutOfMemoryException)) { throw; } if (Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString("net_log_cache_exception", new object[] { "WinInetCache.Retrieve()", exception2.ToString() })); } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()"); } if (handle != null) { handle.Close(); } @null.Close(); @null = Stream.Null; cacheEntry = new RequestCacheEntry(); cacheEntry.IsPrivateEntry = base.IsPrivateCache; if (isThrow) { throw; } return null; } if (Logging.On) { Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()", "Status = " + entry.Error.ToString()); } return @null; }
protected override void Dispose(bool disposing) { //if m_Entry is null, it means that the base constructor failed if (Interlocked.Exchange(ref m_Disposed, 1) == 0 && m_Entry != null) { lock (m_Entry) { if (m_CallNesting == 0) base.Dispose(disposing); else m_Event = new ManualResetEvent(false); } // // This assumes the FileStream will never hang on write // if (disposing && m_Event != null) { using (m_Event) { m_Event.WaitOne(); lock (m_Entry) { Debug.Assert(m_CallNesting == 0); } } base.Dispose(disposing); } // We use TriState to indicate: // False: Delete // Unknown: Partial // True: Full TriState cacheCommitAction; if (m_StreamSize < 0) { if (m_Aborted) { if (m_OneWriteSucceeded) cacheCommitAction = TriState.Unspecified; // Partial else cacheCommitAction = TriState.False; // Delete } else { cacheCommitAction = TriState.True; // Full } } else { if (!m_OneWriteSucceeded) { cacheCommitAction = TriState.False; // Delete } else { if (m_StreamSize > 0) cacheCommitAction = TriState.Unspecified; // Partial else cacheCommitAction = TriState.True; // Full } } if (cacheCommitAction == TriState.False) { try { if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_no_commit, "WinInetWriteStream.Close()")); // Delete temp cache file File.Delete(m_Entry.Filename); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_error_deleting_filename, "WinInetWriteStream.Close()", m_Entry.Filename)); } finally { //Delete an old entry if there was one _WinInetCache.Status errorStatus = _WinInetCache.Remove(m_Entry); if (errorStatus != _WinInetCache.Status.Success && errorStatus != _WinInetCache.Status.FileNotFound) { if(Logging.On)Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_delete_failed, "WinInetWriteStream.Close()", m_Entry.Key, new Win32Exception((int)m_Entry.Error).Message)); } m_Entry = null; } return; } m_Entry.OriginalUrl = null; // // ATTN: WinIent currently does NOT support _WinInetCache.EntryType.Sparse // USING a workaround // if (cacheCommitAction == TriState.Unspecified) { // WinInet will not report this entry back we set this flag // m_Entry.Info.EntryType |= _WinInetCache.EntryType.Sparse; // does not work for now // HACK: WinInet does not support SPARSE_ENTRY bit // We want to add c_SPARSE_ENTRY_HACK into the systemmetadata i.e. to the second block of strings separated by an empty line (\r\n). if (m_Entry.MetaInfo == null || m_Entry.MetaInfo.Length == 0 || (m_Entry.MetaInfo != "\r\n" && m_Entry.MetaInfo.IndexOf("\r\n\r\n", StringComparison.Ordinal) == -1)) { m_Entry.MetaInfo = "\r\n"+ WinInetCache.c_SPARSE_ENTRY_HACK+"\r\n"; } else { m_Entry.MetaInfo += WinInetCache.c_SPARSE_ENTRY_HACK+"\r\n"; } } if (_WinInetCache.Commit(m_Entry) != _WinInetCache.Status.Success) { if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_commit_failed, "WinInetWriteStream.Close()", m_Entry.Key, new Win32Exception((int)m_Entry.Error).Message)); try { // Delete temp cache file File.Delete(m_Entry.Filename); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_error_deleting_filename, "WinInetWriteStream.Close()", m_Entry.Filename)); } if (m_IsThrow) { Win32Exception win32Exception = new Win32Exception((int)m_Entry.Error); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception); } return; } if(Logging.On) { if (m_StreamSize > 0 || (m_StreamSize < 0 && m_Aborted)) Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_committed_as_partial, "WinInetWriteStream.Close()", m_Entry.Key, (m_StreamSize > 0 ? m_StreamSize.ToString(CultureInfo.CurrentCulture) : SR.GetString(SR.net_log_unknown)))); Logging.PrintInfo(Logging.RequestCache, "WinInetWriteStream.Close(), Key = " + m_Entry.Key + ", Commit Status = " + m_Entry.Error.ToString()); } if ((m_Entry.Info.EntryType & _WinInetCache.EntryType.StickyEntry) == _WinInetCache.EntryType.StickyEntry) { if (_WinInetCache.Update(m_Entry, _WinInetCache.Entry_FC.ExemptDelta) != _WinInetCache.Status.Success) { if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_update_failed, "WinInetWriteStream.Close(), Key = " + m_Entry.Key, new Win32Exception((int)m_Entry.Error).Message)); if (m_IsThrow) { Win32Exception win32Exception = new Win32Exception((int)m_Entry.Error); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception); } return; } if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_max_stale_and_update_status, "WinInetWriteFile.Close()", m_Entry.Info.U.ExemptDelta, m_Entry.Error.ToString())); } base.Dispose(disposing); } }
internal WriteStream(_WinInetCache.Entry entry, bool isThrow, long streamSize, bool async): base(entry.Filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, async) { m_Entry = entry; m_IsThrow = isThrow; m_StreamSize = streamSize; m_OneWriteSucceeded = streamSize == 0; //if 0 is expected or the lenght is unknonw we will commit even an emtpy stream. m_ReadTimeout = m_WriteTimeout = System.Threading.Timeout.Infinite; }
// // private bool UpdateInfo(string key, DateTime expiresUtc, DateTime lastModifiedUtc, DateTime lastSynchronizedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow) { if (key == null) { throw new ArgumentNullException("key"); } if(Logging.On) Logging.Enter(Logging.RequestCache, "WinInetCache.Update", "Key = "+ key); if (!CanWrite) { if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_operation_failed_with_error, "WinInetCache.Update()", SR.GetString(SR.net_cache_access_denied, "Write"))); if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Update()"); if(isThrow) { throw new InvalidOperationException(SR.GetString(SR.net_cache_access_denied, "Write")); } return false; } _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); _WinInetCache.Entry_FC attributes = _WinInetCache.Entry_FC.None; if (expiresUtc != DateTime.MinValue && expiresUtc > s_MinDateTimeUtcForFileTimeUtc) { attributes |= _WinInetCache.Entry_FC.Exptime; entry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc()); if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_set_expires, expiresUtc.ToString("r"))); } if (lastModifiedUtc != DateTime.MinValue && lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc) { attributes |= _WinInetCache.Entry_FC.Modtime; entry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc()); if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_set_last_modified, lastModifiedUtc.ToString("r"))); } if (lastSynchronizedUtc != DateTime.MinValue && lastSynchronizedUtc > s_MinDateTimeUtcForFileTimeUtc) { attributes |= _WinInetCache.Entry_FC.Synctime; entry.Info.LastSyncTime = new _WinInetCache.FILETIME(lastSynchronizedUtc.ToFileTimeUtc()); if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_set_last_synchronized, lastSynchronizedUtc.ToString("r"))); } if (maxStale != TimeSpan.MinValue) { attributes |= _WinInetCache.Entry_FC.ExemptDelta|_WinInetCache.Entry_FC.Attribute; entry.Info.EntryType = _WinInetCache.EntryType.NormalEntry; if (maxStale >= TimeSpan.Zero) { if (maxStale >= s_MaxTimeSpanForInt32) { maxStale = s_MaxTimeSpanForInt32; } entry.Info.EntryType = _WinInetCache.EntryType.StickyEntry; entry.Info.U.ExemptDelta = (int)maxStale.TotalSeconds; if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_enable_max_stale, ((int)maxStale.TotalSeconds).ToString())); } else { entry.Info.U.ExemptDelta = 0; if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_disable_max_stale)); } } entry.MetaInfo = CombineMetaInfo(entryMetadata, systemMetadata); if (entry.MetaInfo.Length != 0) { attributes |= _WinInetCache.Entry_FC.Headerinfo; if(Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_dumping)); if (Logging.IsVerbose(Logging.RequestCache)) { Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_dumping)); if (entryMetadata != null) { foreach (string s in entryMetadata) { Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits)); } } Logging.PrintInfo(Logging.RequestCache, "------"); if (systemMetadata != null) { foreach (string s in systemMetadata) { Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits)); } } } } } _WinInetCache.Update(entry, attributes) ; if (entry.Error != _WinInetCache.Status.Success) { if(Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_update_failed, "WinInetCache.Update()", entry.Key, new Win32Exception((int)entry.Error).Message)); Logging.Exit(Logging.RequestCache, "WinInetCache.Update()"); } if (isThrow) { Win32Exception win32Exception = new Win32Exception((int)entry.Error); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception); } return false; } if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Update()", "Status = " + entry.Error.ToString()); return true; }
// // private Stream GetWriteStream(string key, long contentLength, DateTime expiresUtc, DateTime lastModifiedUtc, TimeSpan maxStale, StringCollection entryMetadata, StringCollection systemMetadata, bool isThrow) { if(Logging.On) Logging.Enter(Logging.RequestCache, "WinInetCache.Store()", "Key = " + key); if (key == null) { throw new ArgumentNullException("key"); } if (!CanWrite) { if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_operation_failed_with_error, "WinInetCache.Store()", SR.GetString(SR.net_cache_access_denied, "Write"))); if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Store"); if(isThrow) { throw new InvalidOperationException(SR.GetString(SR.net_cache_access_denied, "Write")); } return null; } _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); entry.Key = key; entry.OptionalLength = (contentLength < 0L)? 0: contentLength > Int32.MaxValue? Int32.MaxValue: (int)(contentLength); entry.Info.ExpireTime = _WinInetCache.FILETIME.Zero; if (expiresUtc != DateTime.MinValue && expiresUtc > s_MinDateTimeUtcForFileTimeUtc) { entry.Info.ExpireTime = new _WinInetCache.FILETIME(expiresUtc.ToFileTimeUtc()); } entry.Info.LastModifiedTime = _WinInetCache.FILETIME.Zero; if (lastModifiedUtc != DateTime.MinValue && lastModifiedUtc > s_MinDateTimeUtcForFileTimeUtc) { entry.Info.LastModifiedTime = new _WinInetCache.FILETIME(lastModifiedUtc.ToFileTimeUtc()); } entry.Info.EntryType = _WinInetCache.EntryType.NormalEntry; if (maxStale > TimeSpan.Zero) { if (maxStale >= s_MaxTimeSpanForInt32) { maxStale = s_MaxTimeSpanForInt32; } entry.Info.U.ExemptDelta = (int)maxStale.TotalSeconds; entry.Info.EntryType = _WinInetCache.EntryType.StickyEntry; } entry.MetaInfo = CombineMetaInfo(entryMetadata, systemMetadata); entry.FileExt = "cache"; if(Logging.On) { Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_expected_length, entry.OptionalLength)); Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_last_modified, (entry.Info.LastModifiedTime.IsNull? "0": DateTime.FromFileTimeUtc(entry.Info.LastModifiedTime.ToLong()).ToString("r")))); Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_expires, (entry.Info.ExpireTime.IsNull? "0": DateTime.FromFileTimeUtc(entry.Info.ExpireTime.ToLong()).ToString("r")))); Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_max_stale, (maxStale > TimeSpan.Zero? ((int)maxStale.TotalSeconds).ToString():"n/a"))); if (Logging.IsVerbose(Logging.RequestCache)) { Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_dumping_metadata)); if (entry.MetaInfo.Length == 0) { Logging.PrintInfo(Logging.RequestCache, "<null>"); } else { if (entryMetadata != null) { foreach (string s in entryMetadata) { Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits)); } } Logging.PrintInfo(Logging.RequestCache, "------"); if (systemMetadata != null) { foreach (string s in systemMetadata) { Logging.PrintInfo(Logging.RequestCache, s.TrimEnd(LineSplits)); } } } } } _WinInetCache.CreateFileName(entry); Stream result = Stream.Null; if (entry.Error != _WinInetCache.Status.Success) { if(Logging.On) { Logging.PrintWarning(Logging.RequestCache, SR.GetString(SR.net_log_cache_create_failed, new Win32Exception((int)entry.Error).Message)); Logging.Exit(Logging.RequestCache, "WinInetCache.Store"); } if (isThrow) { Win32Exception win32Exception = new Win32Exception((int)entry.Error); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception); } return null; } try { result = new WriteStream(entry, isThrow, contentLength, async); } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } if(Logging.On) { Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_exception, "WinInetCache.Store()", exception)); Logging.Exit(Logging.RequestCache, "WinInetCache.Store"); } if (isThrow) { throw; } return null; } if(Logging.On) Logging.Exit(Logging.RequestCache, "WinInetCache.Store", "Filename = " + entry.Filename); return result; }
// // // private Stream Lookup(string key, out RequestCacheEntry cacheEntry, bool isThrow) { if(Logging.On) Logging.Enter(Logging.RequestCache, "WinInetCache.Retrieve", "key = " + key); if (key == null) { throw new ArgumentNullException("key"); } Stream result = Stream.Null; SafeUnlockUrlCacheEntryFile handle = null; _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); try { handle = _WinInetCache.LookupFile(entry); if (entry.Error == _WinInetCache.Status.Success) { if(Logging.On) Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_filename, "WinInetCache.Retrieve()", entry.Filename, entry.Error)); cacheEntry = new RequestCacheEntry(entry, IsPrivateCache); if (entry.MetaInfo != null && entry.MetaInfo.Length != 0) { // convert metadata to upto two string collections unsafe { int start = 0; int length = entry.MetaInfo.Length; StringCollection sc = new StringCollection(); fixed (char * ch = entry.MetaInfo) { int i; for (i = 0; i < length; ++i) { // WinInet specific block!! // The point here is that wininet scans for ~U: throughly with no regard to \r\n so we mimic the same behavior if (i == start && i+2 < length) { if (ch[i] == '~' && (ch[i+1] == 'U' || ch[i+1] == 'u') && ch[i+2] == ':') { //Security: don't report what the username is while(i < length && ch[++i] != '\n') {;} start = i+1; continue; } } // note a metadata entry must terminate with \r\n if ((i+1 == length) || (ch[i] == '\n')) { string value = entry.MetaInfo.Substring(start, (ch[i-1] == '\r'? (i-1):(i+1)) - start); if (value.Length == 0 && cacheEntry.EntryMetadata == null) { // done with headers, prepare for system metadata cacheEntry.EntryMetadata = sc; sc = new StringCollection(); } else { //WinInet specific block!! // HACK: if we are parsing system metadata and have found our hack, // then convert it to a sparse entry type (entry.Info.EntryType & _WinInetCache.EntryType.Sparse) if (cacheEntry.EntryMetadata != null && value.StartsWith(c_SPARSE_ENTRY_HACK, StringComparison.Ordinal)) cacheEntry.IsPartialEntry = true; else sc.Add(value); } start = i+1; } } } if (cacheEntry.EntryMetadata == null ) {cacheEntry.EntryMetadata = sc;} else {cacheEntry.SystemMetadata = sc;} } } result = new ReadStream(entry, handle, async); } else { if (handle != null) { handle.Close(); } cacheEntry = new RequestCacheEntry(); cacheEntry.IsPrivateEntry = IsPrivateCache; if (entry.Error != _WinInetCache.Status.FileNotFound) { if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_lookup_failed, "WinInetCache.Retrieve()", new Win32Exception((int)entry.Error).Message)); if(Logging.On)Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()"); if(isThrow) { Win32Exception win32Exception = new Win32Exception((int)entry.Error); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception); } return null; } } } catch (Exception exception) { if (exception is ThreadAbortException || exception is StackOverflowException || exception is OutOfMemoryException) { throw; } if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_exception, "WinInetCache.Retrieve()", exception.ToString())); if(Logging.On)Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()"); if (handle != null) { handle.Close(); } result.Close(); result = Stream.Null; cacheEntry = new RequestCacheEntry(); cacheEntry.IsPrivateEntry = IsPrivateCache; if (isThrow) { throw; } return null; } if(Logging.On)Logging.Exit(Logging.RequestCache, "WinInetCache.Retrieve()", "Status = " + entry.Error.ToString()); return result; }
/// <summary> /// <para> /// Removes an item from the IE cache. Throws Win32Excpetion if failed /// </para> /// </summary> internal override void Remove(string key) { if (key == null) { throw new ArgumentNullException("key"); } if (!CanWrite) { if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_operation_failed_with_error, "WinInetCache.Remove()", SR.GetString(SR.net_cache_access_denied, "Write"))); return ; } _WinInetCache.Entry entry = new _WinInetCache.Entry(key, _MaximumResponseHeadersLength); if (_WinInetCache.Remove(entry) != _WinInetCache.Status.Success && entry.Error != _WinInetCache.Status.FileNotFound) { Win32Exception win32Exception = new Win32Exception((int)entry.Error); if(Logging.On)Logging.PrintError(Logging.RequestCache, SR.GetString(SR.net_log_cache_cannot_remove, "WinInetCache.Remove()", key, win32Exception.Message)); throw new IOException(SR.GetString(SR.net_cache_retrieve_failure, win32Exception.Message), win32Exception); } if(Logging.On)Logging.PrintInfo(Logging.RequestCache, SR.GetString(SR.net_log_cache_key_status, "WinInetCache.Remove(), ", key, entry.Error.ToString())); }