Code:
/ FXUpdate3074 / FXUpdate3074 / 1.1 / untmp / whidbey / QFE / 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]; // 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(); } } } // File provided for Reference Use Only by Microsoft Corporation (c) 2007. // Copyright (c) Microsoft Corporation. All rights reserved.
Link Menu
This book is available now!
Buy at Amazon US or
Buy at Amazon UK
- ClientSettingsSection.cs
- Base64Decoder.cs
- AttributeXamlType.cs
- DataSetMappper.cs
- DataBindingList.cs
- BitmapImage.cs
- SqlAliasesReferenced.cs
- SudsParser.cs
- PlatformCulture.cs
- XComponentModel.cs
- CatalogPart.cs
- XmlSerializableServices.cs
- COM2ComponentEditor.cs
- ExpressionNode.cs
- CountAggregationOperator.cs
- TransformDescriptor.cs
- InkCanvasSelection.cs
- TextBoxView.cs
- CodeEntryPointMethod.cs
- RootBrowserWindowAutomationPeer.cs
- ListViewDeletedEventArgs.cs
- RC2CryptoServiceProvider.cs
- XmlEnumAttribute.cs
- CallbackValidatorAttribute.cs
- TdsRecordBufferSetter.cs
- DockPattern.cs
- NetMsmqBinding.cs
- ContextMenu.cs
- FactoryId.cs
- SendKeys.cs
- ScriptResourceAttribute.cs
- ImageDrawing.cs
- DataError.cs
- DataFieldConverter.cs
- UserControlAutomationPeer.cs
- SafeBitVector32.cs
- SQLCharsStorage.cs
- FontFamilyValueSerializer.cs
- WebBrowserPermission.cs
- panel.cs
- ReferenceEqualityComparer.cs
- StateItem.cs
- BindingNavigatorDesigner.cs
- CaseInsensitiveOrdinalStringComparer.cs
- DataTableReader.cs
- BookmarkScopeInfo.cs
- TraceInternal.cs
- Drawing.cs
- RenderDataDrawingContext.cs
- MultiTrigger.cs
- GuidConverter.cs
- SignatureHelper.cs
- DependencyPropertyKind.cs
- LambdaExpression.cs
- DataSourceCache.cs
- XmlSchemaObjectCollection.cs
- hwndwrapper.cs
- HttpListenerRequest.cs
- WebServiceClientProxyGenerator.cs
- IOException.cs
- Rule.cs
- HtmlInputControl.cs
- EditBehavior.cs
- FixedSOMImage.cs
- IApplicationTrustManager.cs
- ResourceIDHelper.cs
- TdsParserStaticMethods.cs
- WeakReadOnlyCollection.cs
- ActivityExecutorDelegateInfo.cs
- SecurityKeyIdentifier.cs
- NativeMethods.cs
- PersonalizationStateInfoCollection.cs
- WS2007HttpBindingElement.cs
- SamlConstants.cs
- ReleaseInstanceMode.cs
- Utils.cs
- AutoGeneratedFieldProperties.cs
- XPathNodePointer.cs
- SettingsAttributes.cs
- SHA256.cs
- HttpStreamMessageEncoderFactory.cs
- FrameworkContentElement.cs
- DesignTimeResourceProviderFactoryAttribute.cs
- UniqueConstraint.cs
- DropShadowBitmapEffect.cs
- DataGridTableCollection.cs
- XmlIncludeAttribute.cs
- ThreadPool.cs
- CompiledRegexRunner.cs
- TargetParameterCountException.cs
- FunctionUpdateCommand.cs
- HandlerBase.cs
- AsyncPostBackErrorEventArgs.cs
- SQLStringStorage.cs
- GeometryModel3D.cs
- ListControl.cs
- NavigationPropertyAccessor.cs
- TypedDataSourceCodeGenerator.cs
- CodeValidator.cs
- BoolLiteral.cs