private unsafe void CreateFirstSubstData(string s, IIS7WorkerRequest iis7WorkerRequest, System.Text.Encoder encoder) { IntPtr ptr; int num = 0; int length = s.Length; if (length > 0) { fixed (char* str = ((char*) s)) { char* chars = str; int size = encoder.GetByteCount(chars, length, true); ptr = iis7WorkerRequest.AllocateRequestMemory(size); if (ptr != IntPtr.Zero) { num = encoder.GetBytes(chars, length, (byte*) ptr, size, true); } } } else { ptr = iis7WorkerRequest.AllocateRequestMemory(1); } if (ptr == IntPtr.Zero) { throw new OutOfMemoryException(); } this._firstSubstData = ptr; this._firstSubstDataSize = num; }
// This copy constructor is used by the granular request validation feature. Since these collections are immutable // once created, it's ok for us to have two collections containing the same data. internal HttpHeaderCollection(HttpHeaderCollection col) : base(col) { _request = col._request; _response = col._response; _iis7WorkerRequest = col._iis7WorkerRequest; }
public void RequestEnteredAspNetPipeline(IIS7WorkerRequest wr, Guid childActivityId) { if (!IsEnabled()) { return; } Guid parentActivityId = wr.RequestTraceIdentifier; RequestEnteredAspNetPipelineImpl(parentActivityId, childActivityId); }
// This constructor creates the header collection for response headers. // Try to preallocate the base collection with a size that should be sufficient // to store the headers for most requests. internal HttpHeaderCollection(HttpWorkerRequest wr, HttpResponse response, int capacity) : base(capacity) { // if this is an IIS7WorkerRequest, then the collection will be writeable and we will // call into IIS7 to update the header blocks when changes are made. _iis7WorkerRequest = wr as IIS7WorkerRequest; _response = response; }
// We preallocate the base collection with a size that should be sufficient // to store all server variables w/o having to expand internal HttpServerVarsCollection(HttpWorkerRequest wr, HttpRequest request) : base(59) { // if this is an IIS7WorkerRequest, then the collection will be writeable and we will // call into IIS7 to update the server var block when changes are made. _iis7workerRequest = wr as IIS7WorkerRequest; _request = request; _populated = false; Debug.Assert( _request != null ); }
internal HttpSubstBlockResponseElement(HttpResponseSubstitutionCallback callback, Encoding encoding, System.Text.Encoder encoder, IIS7WorkerRequest iis7WorkerRequest) { this._callback = callback; if (iis7WorkerRequest != null) { this._isIIS7WorkerRequest = true; string s = this._callback(HttpContext.Current); if (s == null) { throw new ArgumentNullException("substitutionString"); } this.CreateFirstSubstData(s, iis7WorkerRequest, encoder); } else { this._firstSubstitution = this.Substitute(encoding); } }
private static void InitializeRequestContext(IntPtr nativeRequestContext, int flags, out IIS7WorkerRequest wr, out HttpContext context) { wr = null; context = null; try { bool etwEnabled = ((flags & HttpContext.FLAG_ETW_PROVIDER_ENABLED) == HttpContext.FLAG_ETW_PROVIDER_ENABLED); // this may throw, e.g. if the request Content-Length header has a value greater than Int32.MaxValue wr = IIS7WorkerRequest.CreateWorkerRequest(nativeRequestContext, etwEnabled); // this may throw, e.g. see WOS 1724573: ASP.Net v2.0: wrong error code returned when ? is used in the URL context = new HttpContext(wr, false); } catch { // treat as "400 Bad Request" since that's the only reason the HttpContext.ctor should throw IIS.MgdSetBadRequestStatus(nativeRequestContext); } }
internal ArrayList GetIntegratedSnapshot(out bool hasSubstBlocks, IIS7WorkerRequest wr) { ArrayList list = null; ArrayList snapshot = this.GetSnapshot(out hasSubstBlocks); ArrayList list3 = wr.GetBufferedResponseChunks(true, this._substElements, ref hasSubstBlocks); if (list3 != null) { for (int i = 0; i < snapshot.Count; i++) { list3.Add(snapshot[i]); } list = list3; } else { list = snapshot; } if ((this._substElements != null) && (this._substElements.Count > 0)) { int num2 = 0; for (int j = 0; j < list.Count; j++) { if (list[j] is HttpSubstBlockResponseElement) { num2++; if (num2 == this._substElements.Count) { break; } } } if (num2 != this._substElements.Count) { throw new InvalidOperationException(System.Web.SR.GetString("Substitution_blocks_cannot_be_modified")); } this._response.Context.Request.SetDynamicCompression(true); } return list; }
internal static IIS7WorkerRequest CreateWorkerRequest(IntPtr requestContext, bool etwProviderEnabled) { IIS7WorkerRequest request = new IIS7WorkerRequest(requestContext, etwProviderEnabled); if (request != null) { request.Initialize(); } return request; }
// Disposes of the worker request associated with this request. public void ReleaseWorkerRequest() { Debug.Trace("RootedObjects", "ReleaseWorkerRequest"); if (WorkerRequest != null) { WorkerRequest.Dispose(); } WorkerRequest = null; }
private void ClearNativeResponse(bool clearEntity, bool clearHeaders, IIS7WorkerRequest wr) { wr.ClearResponse(clearEntity, clearHeaders); if (clearEntity) { this._httpWriter.ClearSubstitutionBlocks(); } }
private RequestNotificationStatus ProcessRequestNotificationPrivate(IIS7WorkerRequest wr, HttpContext context) { RequestNotificationStatus status = RequestNotificationStatus.Pending; try { int currentModuleIndex; bool isPostNotification; int currentNotification; UnsafeIISMethods.MgdGetCurrentNotificationInfo(wr.RequestContext, out currentModuleIndex, out isPostNotification, out currentNotification); context.CurrentModuleIndex = currentModuleIndex; context.IsPostNotification = isPostNotification; context.CurrentNotification = (RequestNotification) currentNotification; IHttpHandler httpHandler = (IHttpHandler) null; if (context.NeedToInitializeApp()) { try { this.EnsureFirstRequestInit(context); } catch { if (!context.Request.IsDebuggingRequest) throw; } context.Response.InitResponseWriter(); httpHandler = HttpApplicationFactory.GetApplicationInstance(context); if (httpHandler == null) throw new HttpException(System.Web.SR.GetString("Unable_create_app_object")); if (EtwTrace.IsTraceEnabled(5, 1)) EtwTrace.Trace(EtwTraceType.ETW_TYPE_START_HANDLER, context.WorkerRequest, httpHandler.GetType().FullName, "Start"); HttpApplication httpApplication = httpHandler as HttpApplication; if (httpApplication != null) httpApplication.AssignContext(context); } wr.SynchronizeVariables(context); if (context.ApplicationInstance != null) { if (context.ApplicationInstance.BeginProcessRequestNotification(context, this._requestNotificationCompletionCallback).CompletedSynchronously) status = RequestNotificationStatus.Continue; } else if (httpHandler != null) { httpHandler.ProcessRequest(context); status = RequestNotificationStatus.FinishRequest; } else status = RequestNotificationStatus.Continue; } catch (Exception ex) { status = RequestNotificationStatus.FinishRequest; context.Response.InitResponseWriter(); context.AddError(ex); } if (status != RequestNotificationStatus.Pending) this.FinishRequestNotification(wr, context, ref status); return status; }
internal static RequestNotificationStatus ProcessRequestNotification(IIS7WorkerRequest wr, HttpContext context) { return HttpRuntime._theRuntime.ProcessRequestNotificationPrivate(wr, context); }
private void FinishRequestNotification(IIS7WorkerRequest wr, HttpContext context, ref RequestNotificationStatus status) { HttpApplication applicationInstance = context.ApplicationInstance; if (context.NotificationContext.RequestCompleted) status = RequestNotificationStatus.FinishRequest; context.ReportRuntimeErrorIfExists(ref status); if (status == RequestNotificationStatus.FinishRequest && (context.CurrentNotification == RequestNotification.LogRequest || context.CurrentNotification == RequestNotification.EndRequest)) status = RequestNotificationStatus.Continue; IntPtr requestContext = wr.RequestContext; bool sendHeaders = UnsafeIISMethods.MgdIsLastNotification(requestContext, status); try { context.Response.UpdateNativeResponse(sendHeaders); } catch (Exception ex) { wr.UnlockCachedResponseBytes(); context.AddError(ex); context.ReportRuntimeErrorIfExists(ref status); context.Response.UpdateNativeResponse(sendHeaders); } if (sendHeaders) context.FinishPipelineRequest(); if (status == RequestNotificationStatus.Pending) return; PipelineRuntime.DisposeHandler(context, requestContext, status); }
// in integrated mode, snapshots need to pull the chunks from the IIS // buffers since they may have already been pushed through // Therefore, we can't rely solely on what's in the HttpWriter // at the moment internal ArrayList GetIntegratedSnapshot(out bool hasSubstBlocks, IIS7WorkerRequest wr) { ArrayList buffers = null; // first, get what's in our buffers ArrayList writerBuffers = GetSnapshot(out hasSubstBlocks); // now, get what's in the IIS buffers ArrayList nativeBuffers = wr.GetBufferedResponseChunks(true, _substElements, ref hasSubstBlocks); // try to append the current buffers to what we just // got from the native buffer if (null != nativeBuffers) { for (int i = 0; i < writerBuffers.Count; i++) { nativeBuffers.Add(writerBuffers[i]); } buffers = nativeBuffers; } else { buffers = writerBuffers; } // if we have substitution blocks: // 1) throw exception if someone modified the subst blocks // 2) re-enable compression if (_substElements != null && _substElements.Count > 0) { int substCount = 0; // scan buffers for subst blocks for(int i = 0; i < buffers.Count; i++) { if (buffers[i] is HttpSubstBlockResponseElement) { substCount++; if (substCount == _substElements.Count) { break; } } } if (substCount != _substElements.Count) { throw new InvalidOperationException(SR.GetString(SR.Substitution_blocks_cannot_be_modified)); } // re-enable dynamic compression when we have a snapshot of the subst blocks. _response.Context.Request.SetDynamicCompression(true /*enable*/); } return buffers; }
// WOS 1926509: ASP.NET: WriteSubstitution in integrated mode needs to support callbacks that return String.Empty private unsafe void CreateFirstSubstData(String s, IIS7WorkerRequest iis7WorkerRequest, Encoder encoder) { Debug.Assert(s != null, "s != null"); IntPtr pbBuffer; int numBytes = 0; int cch = s.Length; if (cch > 0) { fixed (char * pch = s) { int cbBuffer = encoder.GetByteCount(pch, cch, true /*flush*/); pbBuffer = iis7WorkerRequest.AllocateRequestMemory(cbBuffer); if (pbBuffer != IntPtr.Zero) { numBytes = encoder.GetBytes(pch, cch, (byte*)pbBuffer, cbBuffer, true /*flush*/); } } } else { // deal with empty string pbBuffer = iis7WorkerRequest.AllocateRequestMemory(1); } if (pbBuffer == IntPtr.Zero) { throw new OutOfMemoryException(); } _firstSubstData = pbBuffer; _firstSubstDataSize = numBytes; }
internal HttpHeaderCollection(HttpWorkerRequest wr, HttpResponse response, int capacity) : base(capacity) { this._iis7WorkerRequest = wr as IIS7WorkerRequest; this._response = response; }
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 static IIS7WorkerRequest CreateWorkerRequest(IntPtr requestContext, bool etwProviderEnabled) { IIS7WorkerRequest req = new IIS7WorkerRequest(requestContext, etwProviderEnabled); if ( null != req ) { Debug.Trace("ClientUrl", " *********** NEW REQUEST ****************"); req.Initialize(); } return req; }
internal HttpServerVarsCollection(HttpWorkerRequest wr, HttpRequest request) : base(0x3b) { this._iis7workerRequest = wr as IIS7WorkerRequest; this._request = request; this._populated = false; }
internal IIS7UserPrincipal(IIS7WorkerRequest wr, IIdentity identity) { this._wr = wr; this._identity = identity; }
// // 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 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(); } }
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; } } }
public unsafe void RequestStarted(IIS7WorkerRequest wr) { if (!IsEnabled()) { return; } RequestStartedImpl(wr); }
private static void InitializeRequestContext(IntPtr nativeRequestContext, int flags, out IIS7WorkerRequest wr, out HttpContext context) { wr = null; context = null; try { bool etwProviderEnabled = (flags & 0x40) == 0x40; wr = IIS7WorkerRequest.CreateWorkerRequest(nativeRequestContext, etwProviderEnabled); context = new HttpContext(wr, false); } catch { UnsafeIISMethods.MgdSetBadRequestStatus(nativeRequestContext); } }
[NonEvent] // use the private member signature for deducing ETW parameters private unsafe void RequestStartedImpl(IIS7WorkerRequest wr) { string httpVerb = wr.GetHttpVerbName(); HTTP_COOKED_URL* pCookedUrl = wr.GetCookedUrl(); Guid iisEtwActivityId = wr.RequestTraceIdentifier; Guid requestCorrelationId = wr.GetRequestCorrelationId(); fixed (char* pHttpVerb = httpVerb) { // !! WARNING !! // This logic must be kept in sync with the ETW-deduced parameters in RequestStarted, // otherwise type safety violations could occur. const int EVENTDATA_COUNT = 3; EventData* pEventData = stackalloc EventData[EVENTDATA_COUNT]; FillInEventData(&pEventData[0], httpVerb, pHttpVerb); // We have knowledge that pFullUrl is null-terminated so we can optimize away // the copy we'd otherwise have to perform. Still need to adjust the length // to account for the null terminator, though. Debug.Assert(pCookedUrl->pFullUrl != null); pEventData[1].DataPointer = (IntPtr)pCookedUrl->pFullUrl; pEventData[1].Size = checked(pCookedUrl->FullUrlLength + sizeof(char)); FillInEventData(&pEventData[2], &requestCorrelationId); WriteEventCore((int)Events.RequestStarted, EVENTDATA_COUNT, pEventData); } }