private void FlushCharBuffer(bool flushEncoder) { int charCount = this._charBufferLength - this._charBufferFree; if (!this._responseEncodingUpdated) { this.UpdateResponseEncoding(); } this._responseEncodingUsed = true; int maxByteCount = this._responseEncoding.GetMaxByteCount(charCount); if ((maxByteCount <= 0x80) || !this._responseBufferingOn) { byte[] bytes = new byte[maxByteCount]; int size = this._responseEncoder.GetBytes(this._charBuffer, 0, charCount, bytes, 0, flushEncoder); this.BufferData(bytes, 0, size, false); } else { int freeBytes = (this._lastBuffer != null) ? this._lastBuffer.FreeBytes : 0; if (freeBytes < maxByteCount) { this._lastBuffer = this.CreateNewMemoryBufferElement(); this._buffers.Add(this._lastBuffer); freeBytes = this._lastBuffer.FreeBytes; } this._lastBuffer.AppendEncodedChars(this._charBuffer, 0, charCount, this._responseEncoder, flushEncoder); } this._charBufferFree = this._charBufferLength; }
internal void FilterIntegrated(bool finalFiltering, IIS7WorkerRequest wr) { if (this._installedFilter != null) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; ArrayList list = this._buffers; this._buffers = new ArrayList(); ArrayList list2 = null; bool hasSubstBlocks = false; list2 = wr.GetBufferedResponseChunks(false, null, ref hasSubstBlocks); this._filterSink.Filtering = true; try { if (list2 != null) { for (int i = 0; i < list2.Count; i++) { IHttpResponseElement element = (IHttpResponseElement)list2[i]; long size = element.GetSize(); if (size > 0L) { this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size)); } } wr.ClearResponse(true, false); } if (list != null) { for (int j = 0; j < list.Count; j++) { IHttpResponseElement element2 = (IHttpResponseElement)list[j]; long num4 = element2.GetSize(); if (num4 > 0L) { this._installedFilter.Write(element2.GetBytes(), 0, Convert.ToInt32(num4)); } } } this._installedFilter.Flush(); } finally { try { if (finalFiltering) { this._installedFilter.Close(); } } finally { this._filterSink.Filtering = false; } } } }
internal ArrayList GetSnapshot(out bool hasSubstBlocks) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; hasSubstBlocks = false; ArrayList list = new ArrayList(); int count = this._buffers.Count; for (int i = 0; i < count; i++) { object obj2 = this._buffers[i]; HttpBaseMemoryResponseBufferElement element = obj2 as HttpBaseMemoryResponseBufferElement; if (element != null) { if (element.FreeBytes > 0x1000) { obj2 = element.Clone(); } else { element.DisableRecycling(); } } else if (obj2 is HttpSubstBlockResponseElement) { hasSubstBlocks = true; } list.Add(obj2); } return(list); }
internal void MoveResponseBufferRangeForward(int srcIndex, int srcCount, int dstIndex) { if (srcCount > 0) { object[] array = new object[srcIndex - dstIndex]; this._buffers.CopyTo(dstIndex, array, 0, array.Length); for (int i = 0; i < srcCount; i++) { this._buffers[dstIndex + i] = this._buffers[srcIndex + i]; } for (int j = 0; j < array.Length; j++) { this._buffers[(dstIndex + srcCount) + j] = array[j]; } } HttpBaseMemoryResponseBufferElement element = this._buffers[this._buffers.Count - 1] as HttpBaseMemoryResponseBufferElement; if ((element != null) && (element.FreeBytes > 0)) { this._lastBuffer = element; } else { this._lastBuffer = null; } }
private void BufferResource(IntPtr data, int offset, int size) { if ((size > 0x1000) || !this._responseBufferingOn) { this._lastBuffer = null; this._buffers.Add(new HttpResourceResponseElement(data, offset, size)); } else { int num; if (this._lastBuffer != null) { num = this._lastBuffer.Append(data, offset, size); size -= num; offset += num; } while (size > 0) { this._lastBuffer = this.CreateNewMemoryBufferElement(); this._buffers.Add(this._lastBuffer); num = this._lastBuffer.Append(data, offset, size); offset += num; size -= num; } } }
internal int GetResponseBufferCountAfterFlush() { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; return(this._buffers.Count); }
internal HttpWriter(HttpResponse response) : base(null) { this._response = response; this._stream = new HttpResponseStream(this); this._buffers = new ArrayList(); this._lastBuffer = null; this._charBuffer = (char[])s_Allocator.GetBuffer(); this._charBufferLength = this._charBuffer.Length; this._charBufferFree = this._charBufferLength; this.UpdateResponseBuffering(); }
internal HttpWriter(HttpResponse response) : base(null) { this._response = response; this._stream = new HttpResponseStream(this); this._buffers = new ArrayList(); this._lastBuffer = null; this._charBuffer = (char[]) s_Allocator.GetBuffer(); this._charBufferLength = this._charBuffer.Length; this._charBufferFree = this._charBufferLength; this.UpdateResponseBuffering(); }
internal void ClearBuffers() { this.ClearCharBuffer(); if (this._substElements != null) { this._response.Context.Request.SetDynamicCompression(true); } this.RecycleBufferElements(); this._buffers = new ArrayList(); this._lastBuffer = null; this._hasBeenClearedRecently = true; }
internal void WriteFile(string filename, long offset, long size) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; this._buffers.Add(new HttpFileResponseElement(filename, offset, size)); if (!this._responseBufferingOn) { this._response.Flush(); } }
internal void TransmitFile(string filename, long offset, long size, bool isImpersonating, bool supportsLongTransmitFile) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; this._buffers.Add(new HttpFileResponseElement(filename, offset, size, isImpersonating, supportsLongTransmitFile)); if (!this._responseBufferingOn) { this._response.Flush(); } }
private void RecycleBufferElements() { if (this._buffers != null) { int count = this._buffers.Count; for (int i = 0; i < count; i++) { HttpBaseMemoryResponseBufferElement element = this._buffers[i] as HttpBaseMemoryResponseBufferElement; if (element != null) { element.Recycle(); } } this._buffers = null; } }
internal void DisposeIntegratedBuffers() { if (this._buffers != null) { int count = this._buffers.Count; for (int i = 0; i < count; i++) { HttpBaseMemoryResponseBufferElement element = this._buffers[i] as HttpBaseMemoryResponseBufferElement; if (element != null) { element.Recycle(); } } this._buffers = null; } this.ClearBuffers(); }
internal void Filter(bool finalFiltering) { if (this._installedFilter != null) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; if ((this._buffers.Count != 0) || finalFiltering) { ArrayList list = this._buffers; this._buffers = new ArrayList(); this._filterSink.Filtering = true; try { int count = list.Count; for (int i = 0; i < count; i++) { IHttpResponseElement element = (IHttpResponseElement)list[i]; long size = element.GetSize(); if (size > 0L) { this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size)); } } this._installedFilter.Flush(); } finally { try { if (finalFiltering) { this._installedFilter.Close(); } } finally { this._filterSink.Filtering = false; } } } } }
internal void WriteSubstBlock(HttpResponseSubstitutionCallback callback, IIS7WorkerRequest iis7WorkerRequest) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; IHttpResponseElement element = new HttpSubstBlockResponseElement(callback, this.Encoding, this.Encoder, iis7WorkerRequest); this._buffers.Add(element); if (iis7WorkerRequest != null) { this.SubstElements.Add(element); } if (!this._responseBufferingOn) { this._response.Flush(); } }
private void BufferData(byte[] data, int offset, int size, bool needToCopyData) { int num; if (this._lastBuffer != null) { num = this._lastBuffer.Append(data, offset, size); size -= num; offset += num; } else if ((!needToCopyData && (offset == 0)) && !this._responseBufferingOn) { this._buffers.Add(new HttpResponseBufferElement(data, size)); return; } while (size > 0) { this._lastBuffer = this.CreateNewMemoryBufferElement(); this._buffers.Add(this._lastBuffer); num = this._lastBuffer.Append(data, offset, size); offset += num; size -= num; } }
private void FlushCharBuffer(bool flushEncoder) { int numChars = _charBufferLength - _charBufferFree; Debug.Assert(numChars > 0); // remember that response required encoding (to indicate the charset= is needed) if (!_responseEncodingUpdated) { UpdateResponseEncoding(); } _responseEncodingUsed = true; // estimate conversion size int estByteSize = _responseEncoding.GetMaxByteCount(numChars); if (estByteSize <= BufferingParams.MAX_BYTES_TO_COPY || !_responseBufferingOn) { // small size -- allocate intermediate buffer and copy into the output buffer byte[] byteBuffer = new byte[estByteSize]; int realByteSize = _responseEncoder.GetBytes(_charBuffer, 0, numChars, byteBuffer, 0, flushEncoder); BufferData(byteBuffer, 0, realByteSize, false); } else { // convert right into the output buffer int free = (_lastBuffer != null) ? _lastBuffer.FreeBytes : 0; if (free < estByteSize) { // need new buffer -- last one doesn't have enough space _lastBuffer = CreateNewMemoryBufferElement(); _buffers.Add(_lastBuffer); free = _lastBuffer.FreeBytes; } // byte buffers must be long enough to keep everything in char buffer Debug.Assert(free >= estByteSize); _lastBuffer.AppendEncodedChars(_charBuffer, 0, numChars, _responseEncoder, flushEncoder); } _charBufferFree = _charBufferLength; }
private void BufferResource(IntPtr data, int offset, int size) { if (size > BufferingParams.MAX_RESOURCE_BYTES_TO_COPY || !_responseBufferingOn) { // for long response strings create its own buffer element to avoid copy cost // also, when not buffering, no need for an extra copy (nothing will get accumulated anyway) _lastBuffer = null; _buffers.Add(new HttpResourceResponseElement(data, offset, size)); return; } int n; // try last buffer if (_lastBuffer != null) { n = _lastBuffer.Append(data, offset, size); size -= n; offset += n; } // do other buffers if needed while (size > 0) { _lastBuffer = CreateNewMemoryBufferElement(); _buffers.Add(_lastBuffer); n = _lastBuffer.Append(data, offset, size); offset += n; size -= n; } }
internal ArrayList GetSnapshot(out bool hasSubstBlocks) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; hasSubstBlocks = false; ArrayList list = new ArrayList(); int count = this._buffers.Count; for (int i = 0; i < count; i++) { object obj2 = this._buffers[i]; HttpBaseMemoryResponseBufferElement element = obj2 as HttpBaseMemoryResponseBufferElement; if (element != null) { if (element.FreeBytes > 0x1000) { obj2 = element.Clone(); } else { element.DisableRecycling(); } } else if (obj2 is HttpSubstBlockResponseElement) { hasSubstBlocks = true; } list.Add(obj2); } return list; }
// // Snapshot for caching // internal ArrayList GetSnapshot(out bool hasSubstBlocks) { if (_charBufferLength != _charBufferFree) FlushCharBuffer(true); _lastBuffer = null; // to make sure nothing gets appended after hasSubstBlocks = false; ArrayList buffers = new ArrayList(); // copy buffer references to the returned list, make non-recyclable int n = _buffers.Count; for (int i = 0; i < n; i++) { Object responseElement = _buffers[i]; HttpBaseMemoryResponseBufferElement buffer = responseElement as HttpBaseMemoryResponseBufferElement; if (buffer != null) { if (buffer.FreeBytes > BufferingParams.MAX_FREE_BYTES_TO_CACHE) { // copy data if too much is free responseElement = buffer.Clone(); } else { // cache the buffer as is with free bytes buffer.DisableRecycling(); } } else if (responseElement is HttpSubstBlockResponseElement) { hasSubstBlocks = true; } buffers.Add(responseElement); } return buffers; }
internal void FilterIntegrated(bool finalFiltering, IIS7WorkerRequest wr) { if (this._installedFilter != null) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; ArrayList list = this._buffers; this._buffers = new ArrayList(); ArrayList list2 = null; bool hasSubstBlocks = false; list2 = wr.GetBufferedResponseChunks(false, null, ref hasSubstBlocks); this._filterSink.Filtering = true; try { if (list2 != null) { for (int i = 0; i < list2.Count; i++) { IHttpResponseElement element = (IHttpResponseElement) list2[i]; long size = element.GetSize(); if (size > 0L) { this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size)); } } wr.ClearResponse(true, false); } if (list != null) { for (int j = 0; j < list.Count; j++) { IHttpResponseElement element2 = (IHttpResponseElement) list[j]; long num4 = element2.GetSize(); if (num4 > 0L) { this._installedFilter.Write(element2.GetBytes(), 0, Convert.ToInt32(num4)); } } } this._installedFilter.Flush(); } finally { try { if (finalFiltering) { this._installedFilter.Close(); } } finally { this._filterSink.Filtering = false; } } } }
// Gets the response buffer count after flushing the char buffer. Note that _lastBuffer is cleared, // and therefore may not be filled, so calling this can lead to inefficient use of response buffers. internal int GetResponseBufferCountAfterFlush() { if (_charBufferLength != _charBufferFree) { FlushCharBuffer(true); } // set _lastBuffer to null to prevent more data from being added to it _lastBuffer = null; return _buffers.Count; }
// // Support for substitution blocks // internal void WriteSubstBlock(HttpResponseSubstitutionCallback callback, IIS7WorkerRequest iis7WorkerRequest) { if (_charBufferLength != _charBufferFree) FlushCharBuffer(true); _lastBuffer = null; // add new substitution block to the buffer list IHttpResponseElement element = new HttpSubstBlockResponseElement(callback, Encoding, Encoder, iis7WorkerRequest); _buffers.Add(element); if (iis7WorkerRequest != null) { SubstElements.Add(element); } if (!_responseBufferingOn) _response.Flush(); }
internal void WriteFile(String filename, long offset, long size) { if (_charBufferLength != _charBufferFree) FlushCharBuffer(true); _lastBuffer = null; _buffers.Add(new HttpFileResponseElement(filename, offset, size)); if (!_responseBufferingOn) _response.Flush(); }
internal void TransmitFile(string filename, long offset, long size, bool isImpersonating, bool supportsLongTransmitFile) { if (_charBufferLength != _charBufferFree) FlushCharBuffer(true); _lastBuffer = null; _buffers.Add(new HttpFileResponseElement(filename, offset, size, isImpersonating, supportsLongTransmitFile)); if (!_responseBufferingOn) _response.Flush(); }
internal HttpWriter(HttpResponse response): base(null) { _response = response; _stream = new HttpResponseStream(this); _buffers = new ArrayList(); _lastBuffer = null; // Setup the buffer on demand using CharBuffer property _charBuffer = null; _charBufferLength = 0; _charBufferFree = 0; UpdateResponseBuffering(); // delay getting response encoding until it is really needed // UpdateResponseEncoding(); }
internal int GetResponseBufferCountAfterFlush() { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; return this._buffers.Count; }
internal void Filter(bool finalFiltering) { // no filter? if (_installedFilter == null) return; // flush char buffer and remember old buffers if (_charBufferLength != _charBufferFree) FlushCharBuffer(true); _lastBuffer = null; // no content to filter // Allow the filter to be closed (Dev10 Bug 550168). if (_buffers.Count == 0 && !finalFiltering) return; // remember old buffers ArrayList oldBuffers = _buffers; _buffers = new ArrayList(); // push old buffer list through the filter Debug.Assert(_filterSink != null); _filterSink.Filtering = true; try { int n = oldBuffers.Count; for (int i = 0; i < n; i++) { IHttpResponseElement buf = (IHttpResponseElement)oldBuffers[i]; long len = buf.GetSize(); if (len > 0) { // Convert.ToInt32 will throw for sizes larger than Int32.MaxValue. // Filtering large response sizes is not supported _installedFilter.Write(buf.GetBytes(), 0, Convert.ToInt32(len)); } } _installedFilter.Flush(); } finally { try { if (finalFiltering) _installedFilter.Close(); } finally { _filterSink.Filtering = false; } } }
private void BufferData(byte[] data, int offset, int size, bool needToCopyData) { int n; // try last buffer if (_lastBuffer != null) { n = _lastBuffer.Append(data, offset, size); size -= n; offset += n; } else if (!needToCopyData && offset == 0 && !_responseBufferingOn) { // when not buffering, there is no need for big buffer accumulating multiple writes // the byte[] data can be sent as is _buffers.Add(new HttpResponseBufferElement(data, size)); return; } // do other buffers if needed while (size > 0) { _lastBuffer = CreateNewMemoryBufferElement(); _buffers.Add(_lastBuffer); n = _lastBuffer.Append(data, offset, size); offset += n; size -= n; } }
internal void FilterIntegrated(bool finalFiltering, IIS7WorkerRequest wr) { // no filter? if (_installedFilter == null) return; // flush char buffer and remember old buffers if (_charBufferLength != _charBufferFree) FlushCharBuffer(true); _lastBuffer = null; // ISAPI mode bails if it has no buffers // to filter, in integrated mode we need // to check the unified response buffers // maintained by IIS for content, as well // remember current buffers (if any) that might be // response entity from this transition // (not yet pushed through to IIS response buffers) ArrayList oldBuffers = _buffers; _buffers = new ArrayList(); // now, get what's in the IIS buffers ArrayList nativeBuffers = null; bool fDummy = false; nativeBuffers = wr.GetBufferedResponseChunks(false, null, ref fDummy); Debug.Assert(_filterSink != null); _filterSink.Filtering = true; try { // push buffers through installed filters // push the IIS ones through first since we need to maintain order if (null != nativeBuffers) { for (int i = 0; i < nativeBuffers.Count; i++) { IHttpResponseElement buf = (IHttpResponseElement)nativeBuffers[i]; long len = buf.GetSize(); if (len > 0) _installedFilter.Write(buf.GetBytes(), 0, Convert.ToInt32(len)); } // if we had stuff there, we now need to clear it since we may have // transformed it wr.ClearResponse(true /* entity */, false /* headers */); } // current buffers, if any if (null != oldBuffers) { for (int i = 0; i < oldBuffers.Count; i++) { IHttpResponseElement buf = (IHttpResponseElement)oldBuffers[i]; long len = buf.GetSize(); if (len > 0) _installedFilter.Write(buf.GetBytes(), 0, Convert.ToInt32(len)); } } _installedFilter.Flush(); } finally { try { if (finalFiltering) _installedFilter.Close(); } finally { _filterSink.Filtering = false; } } }
internal HttpWriter(HttpResponse response): base(null) { _response = response; _stream = new HttpResponseStream(this); _buffers = new ArrayList(); _lastBuffer = null; _charBuffer = (char[])s_Allocator.GetBuffer(); _charBufferLength = _charBuffer.Length; _charBufferFree = _charBufferLength; UpdateResponseBuffering(); // delay getting response encoding until it is really needed // UpdateResponseEncoding(); }
// Move the specified range of buffers forward in the buffer list. internal void MoveResponseBufferRangeForward(int srcIndex, int srcCount, int dstIndex) { Debug.Assert(dstIndex <= srcIndex); // DevDiv Bugs 154630: No need to copy the form between temporary array and the buffer list when // no hidden fields are written. if (srcCount > 0) { // create temporary storage for buffers that will be moved backwards object[] temp = new object[srcIndex - dstIndex]; // copy buffers that will be moved backwards _buffers.CopyTo(dstIndex, temp, 0, temp.Length); // move the range forward from srcIndex to dstIndex for (int i = 0; i < srcCount; i++) { _buffers[dstIndex + i] = _buffers[srcIndex + i]; } // insert buffers that were placed in temporary storage for (int i = 0; i < temp.Length; i++) { _buffers[dstIndex + srcCount + i] = temp[i]; } } // set _lastBuffer HttpBaseMemoryResponseBufferElement buf = _buffers[_buffers.Count-1] as HttpBaseMemoryResponseBufferElement; if (buf != null && buf.FreeBytes > 0) { _lastBuffer = buf; } else { _lastBuffer = null; } }
// // Buffer management // internal void ClearBuffers() { ClearCharBuffer(); // re-enable dynamic compression if we are about to clear substitution blocks if (_substElements != null) { _response.Context.Request.SetDynamicCompression(true /*enable*/); } //VSWhidbey 559434: Private Bytes goes thru roof because unmanaged buffers are not recycled when Response.Flush is called RecycleBufferElements(); _buffers = new ArrayList(); _lastBuffer = null; _hasBeenClearedRecently = true; }
internal void Filter(bool finalFiltering) { if (this._installedFilter != null) { if (this._charBufferLength != this._charBufferFree) { this.FlushCharBuffer(true); } this._lastBuffer = null; if ((this._buffers.Count != 0) || finalFiltering) { ArrayList list = this._buffers; this._buffers = new ArrayList(); this._filterSink.Filtering = true; try { int count = list.Count; for (int i = 0; i < count; i++) { IHttpResponseElement element = (IHttpResponseElement) list[i]; long size = element.GetSize(); if (size > 0L) { this._installedFilter.Write(element.GetBytes(), 0, Convert.ToInt32(size)); } } this._installedFilter.Flush(); } finally { try { if (finalFiltering) { this._installedFilter.Close(); } } finally { this._filterSink.Filtering = false; } } } } }