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
- QilReference.cs
- ToolstripProfessionalRenderer.cs
- ViewEvent.cs
- HttpCapabilitiesBase.cs
- DataGridSortCommandEventArgs.cs
- Size3DValueSerializer.cs
- DBCommand.cs
- SqlInternalConnectionTds.cs
- __Filters.cs
- RecognitionEventArgs.cs
- ModelUtilities.cs
- ControlBuilder.cs
- ErrorRuntimeConfig.cs
- Image.cs
- CharUnicodeInfo.cs
- BinaryObjectWriter.cs
- FolderBrowserDialog.cs
- SectionRecord.cs
- DBCommand.cs
- SchemaMapping.cs
- Control.cs
- StorageModelBuildProvider.cs
- DateTimePicker.cs
- ReferencedAssemblyResolver.cs
- UpdatableGenericsFeature.cs
- ContextMenuService.cs
- ByteAnimation.cs
- SmtpCommands.cs
- ValueExpressions.cs
- ResourcePermissionBase.cs
- ReachVisualSerializerAsync.cs
- BaseCAMarshaler.cs
- CalendarAutoFormat.cs
- DemultiplexingClientMessageFormatter.cs
- CompilerErrorCollection.cs
- BrowserPolicyValidator.cs
- FocusWithinProperty.cs
- SizeAnimation.cs
- ServicePoint.cs
- NavigationHelper.cs
- RealProxy.cs
- TerminatorSinks.cs
- DataGridColumn.cs
- DataKey.cs
- TextEditorParagraphs.cs
- UdpTransportSettingsElement.cs
- CanonicalFontFamilyReference.cs
- Interop.cs
- GridToolTip.cs
- PageStatePersister.cs
- HttpCookiesSection.cs
- MatrixAnimationUsingPath.cs
- ViewStateChangedEventArgs.cs
- BinaryKeyIdentifierClause.cs
- UpdatePanelControlTrigger.cs
- CheckoutException.cs
- TraceLog.cs
- Pts.cs
- OptionUsage.cs
- BitmapEffectrendercontext.cs
- Stack.cs
- ForceCopyBuildProvider.cs
- ObjectPropertyMapping.cs
- PageParserFilter.cs
- ManagementEventWatcher.cs
- EventHandlerService.cs
- VariableValue.cs
- Subtree.cs
- SizeAnimationBase.cs
- ButtonChrome.cs
- TraceUtility.cs
- SrgsItemList.cs
- DataGridViewColumnDesigner.cs
- RawStylusActions.cs
- ResXBuildProvider.cs
- DataGridViewComboBoxEditingControl.cs
- WebBrowserNavigatedEventHandler.cs
- SecurityTokenSerializer.cs
- CustomWebEventKey.cs
- AppliesToBehaviorDecisionTable.cs
- MenuItemStyle.cs
- TextRunCache.cs
- DataControlCommands.cs
- GlyphInfoList.cs
- StrongNameUtility.cs
- MsmqBindingBase.cs
- ChannelServices.cs
- BasicDesignerLoader.cs
- TextPatternIdentifiers.cs
- WebPartDisplayModeCollection.cs
- AdRotator.cs
- IPHostEntry.cs
- Point.cs
- CompilerScope.cs
- ColorComboBox.cs
- VisemeEventArgs.cs
- ContainerParagraph.cs
- QueryCursorEventArgs.cs
- DBParameter.cs
- Win32Exception.cs