Code:
/ DotNET / DotNET / 8.0 / untmp / whidbey / REDBITS / ndp / fx / src / xsp / System / Web / HttpInputStream.cs / 2 / HttpInputStream.cs
//------------------------------------------------------------------------------ //// Copyright (c) Microsoft Corporation. All rights reserved. // //----------------------------------------------------------------------------- /* * Input stream used in response and uploaded file objects * * Copyright (c) 1998 Microsoft Corporation */ namespace System.Web { using System.IO; using System.CodeDom.Compiler; // needed for TempFilesCollection using System.Security; using System.Security.Permissions; using System.Web.Hosting; /* * Wrapper around temporary file or byte[] for input stream * * Pattern of use: * ctor * AddBytes * ... * DoneAddingBytes * access bytes: [] / CopyBytes / WriteBytes / GetAsByteArray * Dispose */ internal class HttpRawUploadedContent : IDisposable { private int _fileThreshold; // for sizes over this use file private int _expectedLength;// content-length private bool _completed; // true when all data's in private int _length; // length of the data private byte[] _data; // contains data (either all of it or part read from file) private TempFile _file; // temporary file with content (null when using byte[]) private int _chunkOffset; // which part of file is cached in data - offset private int _chunkLength; // which part of file is cached in data - length internal HttpRawUploadedContent(int fileThreshold, int expectedLength) { _fileThreshold = fileThreshold; _expectedLength = expectedLength; if (_expectedLength >= 0 && _expectedLength < _fileThreshold) _data = new byte[_expectedLength]; else _data = new byte[_fileThreshold]; } public void Dispose() { if (_file != null) _file.Dispose(); } internal void AddBytes(byte[] data, int offset, int length) { if (_completed) throw new InvalidOperationException(); if (length <= 0) return; if (_file == null) { // fits in the existing _data if (_length + length <= _data.Length) { Array.Copy(data, offset, _data, _length, length); _length += length; return; } // doesn't fit in _data but still under threshold // possible if content-length is -1, or when filtering if (_length + length <= _fileThreshold) { byte[] newData = new byte[_fileThreshold]; if (_length > 0) Array.Copy(_data, 0, newData, 0, _length); Array.Copy(data, offset, newData, _length, length); _data = newData; _length += length; return; } // need to convert to file _file = new TempFile(); _file.AddBytes(_data, 0, _length); } // using file _file.AddBytes(data, offset, length); _length += length; } internal void DoneAddingBytes() { if (_data == null) _data = new byte[0]; if (_file != null) _file.DoneAddingBytes(); _completed = true; } internal int Length { get { return _length; } } internal byte this[int index] { get { if (!_completed) throw new InvalidOperationException(); // all data in memory if (_file == null) return _data[index]; // index in the chunk already read if (index >= _chunkOffset && index < _chunkOffset + _chunkLength) return _data[index - _chunkOffset]; // check bounds if (index < 0 || index >= _length) throw new ArgumentOutOfRangeException("index"); // read from file _chunkLength = _file.GetBytes(index, _data.Length, _data, 0); _chunkOffset = index; return _data[0]; } } internal void CopyBytes(int offset, byte[] buffer, int bufferOffset, int length) { if (!_completed) throw new InvalidOperationException(); if (_file != null) { if (offset >= _chunkOffset && offset+length < _chunkOffset + _chunkLength) { // preloaded Array.Copy(_data, offset - _chunkOffset, buffer, bufferOffset, length); } else { if (length <= _data.Length) { // read from file and remember the chunk _chunkLength = _file.GetBytes(offset, _data.Length, _data, 0); _chunkOffset = offset; Array.Copy(_data, offset - _chunkOffset, buffer, bufferOffset, length); } else { // read from file _file.GetBytes(offset, length, buffer, bufferOffset); } } } else { Array.Copy(_data, offset, buffer, bufferOffset, length); } } internal void WriteBytes(int offset, int length, Stream stream) { if (!_completed) throw new InvalidOperationException(); if (_file != null) { int readPosition = offset; int bytesRemaining = length; byte[] buf = new byte[bytesRemaining > _fileThreshold ? _fileThreshold : bytesRemaining]; while (bytesRemaining > 0) { int bytesToRead = bytesRemaining > _fileThreshold ? _fileThreshold : bytesRemaining; int bytesRead = _file.GetBytes(readPosition, bytesToRead, buf, 0); if (bytesRead == 0) break; stream.Write(buf, 0, bytesRead); readPosition += bytesRead; bytesRemaining -= bytesRead; } } else { stream.Write(_data, offset, length); } } internal byte[] GetAsByteArray() { // If the request is chunked, _data can be much larger than // the actual number of bytes read, and FillInFormCollection // will call FillFromEncodedBytes and incorrectly append a // bunch of zeros to the last form value. Therefore, we copy // the data into a smaller array if _length < _data.Length if (_file == null && _length == _data.Length) { return _data; } return GetAsByteArray(0, _length); } internal byte[] GetAsByteArray(int offset, int length) { if (!_completed) throw new InvalidOperationException(); if (length == 0) return new byte[0]; byte[] result = new byte[length]; CopyBytes(offset, result, 0, length); return result; } // helper class for a temp file for large posted data class TempFile : IDisposable { TempFileCollection _tempFiles; String _filename; Stream _filestream; internal TempFile() { // suspend the impersonation for the file creation using (new ApplicationImpersonationContext()) { String tempDir = Path.Combine(HttpRuntime.CodegenDirInternal, "uploads"); // Assert IO access to the temporary directory new FileIOPermission(FileIOPermissionAccess.AllAccess, tempDir).Assert(); if (!Directory.Exists(tempDir)) { try { Directory.CreateDirectory(tempDir); } catch { } } _tempFiles = new TempFileCollection(tempDir, false /*keepFiles*/); _filename = _tempFiles.AddExtension("post", false /*keepFiles*/); //using 4096 as the buffer size, same as the BCL _filestream = new FileStream(_filename, FileMode.Create, FileAccess.ReadWrite, FileShare.None, 4096, FileOptions.DeleteOnClose); } } public void Dispose() { // suspend the impersonation for the file creation using (new ApplicationImpersonationContext()) { try { // force filestream handle to close // since we're using FILE_FLAG_DELETE_ON_CLOSE // this will delete it from disk as well if (_filestream != null) { _filestream.Close(); } _tempFiles.Delete(); ((IDisposable)_tempFiles).Dispose(); } catch { } } } internal void AddBytes(byte[] data, int offset, int length) { if (_filestream == null) throw new InvalidOperationException(); _filestream.Write(data, offset, length); } internal void DoneAddingBytes() { if (_filestream == null) throw new InvalidOperationException(); _filestream.Flush(); _filestream.Seek(0, SeekOrigin.Begin); } internal int GetBytes(int offset, int length, byte[] buffer, int bufferOffset) { if (_filestream == null) throw new InvalidOperationException(); _filestream.Seek(offset, SeekOrigin.Begin); return _filestream.Read(buffer, bufferOffset, length); } } } /* * Stream object over HttpRawUploadedContent * Not a publc class - used internally, returned as Stream */ internal class HttpInputStream : Stream { private HttpRawUploadedContent _data; // the buffer with the content private int _offset; // offset to the start of this stream private int _length; // length of this stream private int _pos; // current reader posision // // Internal access (from this package) // internal HttpInputStream(HttpRawUploadedContent data, int offset, int length) { Init(data, offset, length); } protected void Init(HttpRawUploadedContent data, int offset, int length) { _data = data; _offset = offset; _length = length; _pos = 0; } protected void Uninit() { _data = null; _offset = 0; _length = 0; _pos = 0; } internal byte[] GetAsByteArray() { if (_length == 0) return null; return _data.GetAsByteArray(_offset, _length); } internal void WriteTo(Stream s) { if (_data != null && _length > 0) _data.WriteBytes(_offset, _length, s); } // // BufferedStream implementation // public override bool CanRead { get {return true;} } public override bool CanSeek { get {return true;} } public override bool CanWrite { get {return false;} } public override long Length { get {return _length;} } public override long Position { get {return _pos;} set { Seek(value, SeekOrigin.Begin); } } protected override void Dispose(bool disposing) { try { if (disposing) Uninit(); } finally { base.Dispose(disposing); } } public override void Flush() { } public override long Seek(long offset, SeekOrigin origin) { int newpos = _pos; int offs = (int)offset; switch (origin) { case SeekOrigin.Begin: newpos = offs; break; case SeekOrigin.Current: newpos = _pos + offs; break; case SeekOrigin.End: newpos = _length + offs; break; default: throw new ArgumentOutOfRangeException("origin"); } if (newpos < 0 || newpos > _length) throw new ArgumentOutOfRangeException("offset"); _pos = newpos; return _pos; } public override void SetLength(long length) { throw new NotSupportedException(); } public override int Read(byte[] buffer, int offset, int count) { // find the number of bytes to copy int numBytes = _length - _pos; if (count < numBytes) numBytes = count; // copy the bytes if (numBytes > 0) _data.CopyBytes(_offset + _pos, buffer, offset, numBytes); // adjust the position _pos += numBytes; return numBytes; } public override void Write(byte[] buffer, int offset, int count) { throw new NotSupportedException(); } } /* * Stream used as the source for input filtering */ internal class HttpInputStreamFilterSource : HttpInputStream { internal HttpInputStreamFilterSource() : base(null, 0, 0) { } internal void SetContent(HttpRawUploadedContent data) { if (data != null) base.Init(data, 0, data.Length); else base.Uninit(); } } }
Link Menu

This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- UInt32.cs
- DataGridToolTip.cs
- Flattener.cs
- SecurityPolicySection.cs
- RegistryDataKey.cs
- WebPartEditVerb.cs
- SharedDp.cs
- PointLightBase.cs
- Point4D.cs
- DocumentXmlWriter.cs
- EditBehavior.cs
- BindingsCollection.cs
- DbQueryCommandTree.cs
- ComponentCollection.cs
- DictionaryBase.cs
- GroupJoinQueryOperator.cs
- ProxyManager.cs
- SQLSingleStorage.cs
- CodeGen.cs
- PropertiesTab.cs
- XmlEncodedRawTextWriter.cs
- SiteMapSection.cs
- SmtpFailedRecipientException.cs
- Literal.cs
- GridViewCancelEditEventArgs.cs
- DataGridViewSelectedColumnCollection.cs
- SymbolDocumentGenerator.cs
- XmlArrayAttribute.cs
- ListViewSortEventArgs.cs
- WebHeaderCollection.cs
- DataRowView.cs
- BaseParagraph.cs
- ServicePointManager.cs
- FileDialogPermission.cs
- MenuBindingsEditor.cs
- UniqueConstraint.cs
- securitymgrsite.cs
- SqlProfileProvider.cs
- HtmlToClrEventProxy.cs
- UIElementIsland.cs
- FindCriteriaElement.cs
- PolyQuadraticBezierSegment.cs
- RetrieveVirtualItemEventArgs.cs
- DataKeyCollection.cs
- WebPartEditorCancelVerb.cs
- FolderNameEditor.cs
- CachedPathData.cs
- AssertFilter.cs
- TagMapInfo.cs
- NativeMethods.cs
- CrossSiteScriptingValidation.cs
- RenderData.cs
- ProcessHostServerConfig.cs
- DockEditor.cs
- SelectionManager.cs
- InternalConfigRoot.cs
- ErrorFormatter.cs
- TemplateControlParser.cs
- StringPropertyBuilder.cs
- SynchronizedPool.cs
- InternalsVisibleToAttribute.cs
- FormsAuthenticationUser.cs
- DesignTimeXamlWriter.cs
- CodeGroup.cs
- ConnectionPointCookie.cs
- ValidationError.cs
- Drawing.cs
- WCFServiceClientProxyGenerator.cs
- Vector3DKeyFrameCollection.cs
- CustomUserNameSecurityTokenAuthenticator.cs
- _ListenerRequestStream.cs
- XmlSchemaRedefine.cs
- XmlNodeComparer.cs
- ViewManager.cs
- TCEAdapterGenerator.cs
- DataGridViewLayoutData.cs
- DesignerSerializationOptionsAttribute.cs
- IPPacketInformation.cs
- RewritingValidator.cs
- LocationReferenceValue.cs
- Viewport3DVisual.cs
- ActivityDefaults.cs
- HttpCapabilitiesSectionHandler.cs
- Splitter.cs
- XmlCompatibilityReader.cs
- SqlError.cs
- XmlSchemaInferenceException.cs
- FixedDocument.cs
- altserialization.cs
- RelationshipConverter.cs
- RulePatternOps.cs
- Flattener.cs
- VerticalAlignConverter.cs
- UIPermission.cs
- InputMethod.cs
- ToolStripDropDownClosedEventArgs.cs
- XmlSecureResolver.cs
- WorkflowQueueInfo.cs
- AppDomainAttributes.cs
- SystemParameters.cs