Exemplo n.º 1
0
 // 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;
 }
        // called from native code when the IHttpContext is disposed
        internal static void AsyncCompletionHandler(IntPtr rootedObjectsPointer, int bytesCompleted, int hresult, IntPtr pAsyncCompletionContext)
        {
            HttpContext       context = UnwrapContext(rootedObjectsPointer);
            IIS7WorkerRequest wr      = context.WorkerRequest as IIS7WorkerRequest;

            wr.OnAsyncCompletion(bytesCompleted, hresult, pAsyncCompletionContext);
        }
Exemplo n.º 3
0
        private Task ProcessRequestAsync(HttpContext context)
        {
            IIS7WorkerRequest wr = context.WorkerRequest as IIS7WorkerRequest;

            if (wr == null)
            {
                throw new PlatformNotSupportedException(SR.GetString(SR.Requires_Iis_Integrated_Mode));
            }
            // Dev10 848405: use original unencoded URL (i.e., pass null for url so W3_REQUEST::SetUrl is not called)
            // Dev11 32511: Extensionless URL Handler should not pass parent IHttpUser to child requests
            wr.ScheduleExecuteUrl(null,
                                  null,
                                  null,
                                  true,
                                  context.Request.EntityBody,
                                  null,
                                  preserveUser: false);

            // force the completion of the current request so that the
            // child execution can be performed immediately after unwind
            var releaseStateTask = context.ApplicationInstance.EnsureReleaseStateAsync();

            // DevDiv Bugs 162750: IIS7 Integrated Mode:  TransferRequest performance issue
            // Instead of calling Response.End we call HttpApplication.CompleteRequest()
            if (releaseStateTask.IsCompleted)
            {
                context.ApplicationInstance.CompleteRequest();
                return(TaskAsyncHelper.CompletedTask);
            }
            else
            {
                return(releaseStateTask.ContinueWith((_) => context.ApplicationInstance.CompleteRequest()));
            }
        }
Exemplo n.º 4
0
 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;
             }
         }
     }
 }
Exemplo n.º 5
0
 /// <devdoc>
 /// Validates that the WebResource.axd handler is registered in config and actually
 /// points to the correct handler type.
 /// </devdoc>
 private static void EnsureHandlerExistenceChecked()
 {
     // First we have to check that the handler is registered:
     // <add path="WebResource.axd" verb="GET" type="System.Web.Handlers.AssemblyResourceLoader" validate="True" />
     if (!_handlerExistenceChecked)
     {
         HttpContext       context           = HttpContext.Current;
         IIS7WorkerRequest iis7WorkerRequest = (context != null) ? context.WorkerRequest as IIS7WorkerRequest : null;
         string            webResourcePath   = UrlPath.Combine(HttpRuntime.AppDomainAppVirtualPathString, _webResourceUrl);
         if (iis7WorkerRequest != null)
         {
             // check the IIS <handlers> section by mapping the handler
             string handlerTypeString = iis7WorkerRequest.MapHandlerAndGetHandlerTypeString(method: "GET",
                                                                                            path: UrlPath.Combine(HttpRuntime.AppDomainAppVirtualPathString, _webResourceUrl),
                                                                                            convertNativeStaticFileModule: false, ignoreWildcardMappings: true);
             if (!String.IsNullOrEmpty(handlerTypeString))
             {
                 _handlerExists = (typeof(AssemblyResourceLoader) == BuildManager.GetType(handlerTypeString, true /*throwOnFail*/, false /*ignoreCase*/));
             }
         }
         else
         {
             // check the <httpHandlers> section
             HttpHandlerAction httpHandler = RuntimeConfig.GetConfig(VirtualPath.Create(webResourcePath)).HttpHandlers.FindMapping("GET", VirtualPath.Create(_webResourceUrl));
             _handlerExists = (httpHandler != null) && (httpHandler.TypeInternal == typeof(AssemblyResourceLoader));
         }
         _handlerExistenceChecked = true;
     }
 }
Exemplo n.º 6
0
        [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 [....] 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);
            }
        }
Exemplo n.º 7
0
        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;
        }
Exemplo n.º 8
0
        // 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;
        }
Exemplo n.º 9
0
        public unsafe void RequestStarted(IIS7WorkerRequest wr)
        {
            if (!IsEnabled())
            {
                return;
            }

            RequestStartedImpl(wr);
        }
Exemplo n.º 10
0
        // Disposes of the worker request associated with this request.
        public void ReleaseWorkerRequest()
        {
            Debug.Trace("RootedObjects", "ReleaseWorkerRequest");
            if (WorkerRequest != null)
            {
                WorkerRequest.Dispose();
            }

            WorkerRequest = null;
        }
        // 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);
        }
Exemplo n.º 12
0
        public void RequestEnteredAspNetPipeline(IIS7WorkerRequest wr, Guid childActivityId)
        {
            if (!IsEnabled())
            {
                return;
            }

            Guid parentActivityId = wr.RequestTraceIdentifier;

            RequestEnteredAspNetPipelineImpl(parentActivityId, childActivityId);
        }
        public void ProcessRequest(HttpContext context)
        {
            IIS7WorkerRequest workerRequest = context.WorkerRequest as IIS7WorkerRequest;

            if (workerRequest == null)
            {
                throw new PlatformNotSupportedException(System.Web.SR.GetString("Requires_Iis_Integrated_Mode"));
            }
            bool preserveUser = false;

            workerRequest.ScheduleExecuteUrl(null, null, null, true, context.Request.EntityBody, null, preserveUser);
            context.ApplicationInstance.EnsureReleaseState();
            context.ApplicationInstance.CompleteRequest();
        }
 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);
     }
 }
Exemplo n.º 15
0
 void IHttpResponseElement.Send(HttpWorkerRequest wr)
 {
     if (this._isIIS7WorkerRequest)
     {
         IIS7WorkerRequest request = wr as IIS7WorkerRequest;
         if (request != null)
         {
             request.SendResponseFromIISAllocatedRequestMemory(this._firstSubstData, this._firstSubstDataSize);
         }
     }
     else
     {
         this._firstSubstitution.Send(wr);
     }
 }
        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);
            }
        }
Exemplo n.º 17
0
        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();
            }
        }
Exemplo n.º 18
0
        public void TransferRequest(string path, bool preserveForm, string method, NameValueCollection headers)
        {
            if (!HttpRuntime.UseIntegratedPipeline)
            {
                throw new PlatformNotSupportedException(System.Web.SR.GetString("Requires_Iis_Integrated_Mode"));
            }
            if (this._context == null)
            {
                throw new HttpException(System.Web.SR.GetString("Server_not_available"));
            }
            if (path == null)
            {
                throw new ArgumentNullException("path");
            }
            IIS7WorkerRequest workerRequest = this._context.WorkerRequest as IIS7WorkerRequest;
            HttpRequest       request       = this._context.Request;
            HttpResponse      response      = this._context.Response;

            if (workerRequest == null)
            {
                throw new HttpException(System.Web.SR.GetString("Server_not_available"));
            }
            path = response.RemoveAppPathModifier(path);
            string queryString = null;
            int    index       = path.IndexOf('?');

            if (index >= 0)
            {
                queryString = (index < (path.Length - 1)) ? path.Substring(index + 1) : string.Empty;
                path        = path.Substring(0, index);
            }
            if (!UrlPath.IsValidVirtualPathWithoutProtocol(path))
            {
                throw new ArgumentException(System.Web.SR.GetString("Invalid_path_for_child_request", new object[] { path }));
            }
            VirtualPath path2        = request.FilePathObject.Combine(VirtualPath.Create(path));
            bool        preserveUser = true;

            workerRequest.ScheduleExecuteUrl(path2.VirtualPathString, queryString, method, preserveForm, preserveForm ? request.EntityBody : null, headers, preserveUser);
            this._context.ApplicationInstance.EnsureReleaseState();
            this._context.ApplicationInstance.CompleteRequest();
        }
        // called from native code when the IHttpConnection is disconnected
        internal static void AsyncDisconnectNotificationHandler(IntPtr pManagedRootedObjects)
        {
            // Every object we're about to call into should be live / non-disposed,
            // but since we're paranoid we should put guard clauses everywhere.

            Debug.Assert(pManagedRootedObjects != IntPtr.Zero);
            if (pManagedRootedObjects != IntPtr.Zero)
            {
                RootedObjects rootObj = RootedObjects.FromPointer(pManagedRootedObjects);
                Debug.Assert(rootObj != null);
                if (rootObj != null)
                {
                    IIS7WorkerRequest workerRequest = rootObj.WorkerRequest;
                    Debug.Assert(workerRequest != null);
                    if (workerRequest != null)
                    {
                        workerRequest.NotifyOfAsyncDisconnect();
                    }
                }
            }
        }
Exemplo n.º 20
0
        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);
        }
 private static void DisposeHandlerPrivate(HttpContext context)
 {
     try
     {
         context.FinishPipelineRequest();
         IIS7WorkerRequest workerRequest = context.WorkerRequest as IIS7WorkerRequest;
         if (workerRequest != null)
         {
             workerRequest.Dispose();
         }
         PerfCounters.DecrementCounter(AppPerfCounter.REQUESTS_EXECUTING);
         context.DisposePrincipal();
     }
     finally
     {
         if (context != null)
         {
             context.Unroot();
         }
         HttpRuntime.DecrementActivePipelineCount();
     }
 }
Exemplo n.º 22
0
 private static void EnsureHandlerExistenceChecked()
 {
     if (!_handlerExistenceChecked)
     {
         HttpContext       current = HttpContext.Current;
         IIS7WorkerRequest request = (current != null) ? (current.WorkerRequest as IIS7WorkerRequest) : null;
         string            path    = UrlPath.Combine(HttpRuntime.AppDomainAppVirtualPathString, "WebResource.axd");
         if (request != null)
         {
             string str2 = request.MapHandlerAndGetHandlerTypeString("GET", path, false);
             if (!string.IsNullOrEmpty(str2))
             {
                 _handlerExists = typeof(AssemblyResourceLoader) == BuildManager.GetType(str2, true, false);
             }
         }
         else
         {
             HttpHandlerAction action = RuntimeConfig.GetConfig(VirtualPath.Create(path)).HttpHandlers.FindMapping("GET", VirtualPath.Create("WebResource.axd"));
             _handlerExists = (action != null) && (action.TypeInternal == typeof(AssemblyResourceLoader));
         }
         _handlerExistenceChecked = true;
     }
 }
Exemplo n.º 23
0
        internal static void Trace(EtwTraceType traceType, HttpWorkerRequest workerRequest, string data1, string data2, string data3, string data4)
        {
            if (workerRequest == null)
            {
                return;
            }

            //
            // IIS7WorkerRequest
            IIS7WorkerRequest iis7wr = workerRequest as IIS7WorkerRequest;

            if (iis7wr != null)
            {
                UnsafeNativeMethods.TraceRaiseEventMgdHandler((int)traceType, iis7wr.RequestContext, data1, data2, data3, data4);
                return;
            }

            //
            // ISAPIWorkerRequestInProc
            ISAPIWorkerRequestInProc inproc = workerRequest as ISAPIWorkerRequestInProc;

            if (inproc != null)
            {
                UnsafeNativeMethods.TraceRaiseEventWithEcb((int)traceType, inproc.Ecb, data1, data2, data3, data4);
                return;
            }

            //
            // ISAPIWorkerRequestOutOfProc
            ISAPIWorkerRequestOutOfProc outofproc = workerRequest as ISAPIWorkerRequestOutOfProc;

            if (outofproc != null)
            {
                UnsafeNativeMethods.PMTraceRaiseEvent((int)traceType, outofproc.Ecb, data1, data2, data3, data4);
                return;
            }
        }
        internal static int ProcessRequestNotificationHelper(
            IntPtr rootedObjectsPointer,
            IntPtr nativeRequestContext,
            IntPtr moduleData,
            int flags)
        {
            IIS7WorkerRequest         wr      = null;
            HttpContext               context = null;
            RequestNotificationStatus status  = RequestNotificationStatus.Continue;
            RootedObjects             root;
            bool workerRequestWasJustCreated = false;

            if (rootedObjectsPointer == IntPtr.Zero)
            {
                InitializeRequestContext(nativeRequestContext, flags, out wr, out context);
                workerRequestWasJustCreated = true;
                if (context == null)
                {
                    return((int)RequestNotificationStatus.FinishRequest);
                }

                root               = RootedObjects.Create();
                root.HttpContext   = context;
                root.WorkerRequest = wr;
                root.WriteTransferEventIfNecessary();
                context.RootedObjects = root;

                IIS.MgdSetManagedHttpContext(nativeRequestContext, root.Pointer);
            }
            else
            {
                root    = RootedObjects.FromPointer(rootedObjectsPointer);
                context = root.HttpContext;
                wr      = root.WorkerRequest as IIS7WorkerRequest;
            }

            Debug.Assert(root != null, "We should have a RootedObjects instance by this point.");
            Debug.Assert(wr != null, "We should have an IIS7WorkerRequest instance by this point.");

            using (root.WithinTraceBlock()) {
                if (workerRequestWasJustCreated)
                {
                    AspNetEventSource.Instance.RequestStarted(wr);
                }

                int  currentModuleIndex;
                bool isPostNotification;
                int  currentNotification;
                IIS.MgdGetCurrentNotificationInfo(nativeRequestContext, out currentModuleIndex, out isPostNotification, out currentNotification);

                // If the HttpContext is null at this point, then we've already transitioned this request to a WebSockets request.
                // The WebSockets module should already be running, and asynchronous module-level events (like SendResponse) are
                // ineligible to be hooked by managed code.
                if (context == null || context.HasWebSocketRequestTransitionStarted)
                {
                    return((int)RequestNotificationStatus.Continue);
                }

                // It is possible for a notification to complete asynchronously while we're in
                // a call to IndicateCompletion, in which case a new IIS thread might enter before
                // the call to IndicateCompletion returns.  If this happens, block the thread until
                // IndicateCompletion returns.  But never block a SendResponse notification, because
                // that can cause the request to hang (DevDiv Bugs 187441).
                if (context.InIndicateCompletion &&
                    context.ThreadInsideIndicateCompletion != Thread.CurrentThread &&
                    RequestNotification.SendResponse != (RequestNotification)currentNotification)
                {
                    while (context.InIndicateCompletion)
                    {
                        Thread.Sleep(10);
                    }
                }

                // RQ_SEND_RESPONSE fires out of band and completes synchronously only.
                // The pipeline must be reentrant to support this, so the notification
                // context for the previous notification must be saved and restored.
                NotificationContext savedNotificationContext = context.NotificationContext;
                bool cancellable = context.IsInCancellablePeriod;
                bool locked      = false;
                try {
                    if (cancellable)
                    {
                        context.EndCancellablePeriod();
                    }
                    bool isReEntry = (savedNotificationContext != null);
                    if (isReEntry)
                    {
                        context.ApplicationInstance.AcquireNotifcationContextLock(ref locked);
                    }
                    context.NotificationContext = new NotificationContext(flags /*CurrentNotificationFlags*/,
                                                                          isReEntry);
                    status = HttpRuntime.ProcessRequestNotification(wr, context);
                }
                finally {
                    if (status != RequestNotificationStatus.Pending)
                    {
                        // if we completed the notification, pop the notification context stack
                        // if this is an asynchronous unwind, then the completion will clear the context
                        context.NotificationContext = savedNotificationContext;

                        // DevDiv 112755 restore cancellable state if its changed
                        if (cancellable && !context.IsInCancellablePeriod)
                        {
                            context.BeginCancellablePeriod();
                        }
                        else if (!cancellable && context.IsInCancellablePeriod)
                        {
                            context.EndCancellablePeriod();
                        }
                    }
                    if (locked)
                    {
                        context.ApplicationInstance.ReleaseNotifcationContextLock();
                    }
                }

                if (status != RequestNotificationStatus.Pending)
                {
                    // The current notification may have changed due to the HttpApplication progressing the IIS state machine, so retrieve the info again.
                    IIS.MgdGetCurrentNotificationInfo(nativeRequestContext, out currentModuleIndex, out isPostNotification, out currentNotification);

                    // WOS 1785741: (Perf) In profiles, 8% of HelloWorld is transitioning from native to managed.
                    // The fix is to keep managed code on the stack so that the AppDomain context remains on the
                    // thread, and we can re-enter managed code without setting up the AppDomain context.
                    // If this optimization is possible, MgdIndicateCompletion will execute one or more notifications
                    // and return PENDING as the status.
                    ThreadContext threadContext = context.IndicateCompletionContext;
                    // DevDiv 482614:
                    // Don't use local copy to detect if we can call MgdIndicateCompletion because another thread
                    // unwinding from MgdIndicateCompletion may be changing context.IndicateCompletionContext at the same time.
                    if (!context.InIndicateCompletion && context.IndicateCompletionContext != null)
                    {
                        if (status == RequestNotificationStatus.Continue)
                        {
                            try {
                                context.InIndicateCompletion = true;
                                Interlocked.Increment(ref _inIndicateCompletionCount);
                                context.ThreadInsideIndicateCompletion = Thread.CurrentThread;
                                IIS.MgdIndicateCompletion(nativeRequestContext, ref status);
                            }
                            finally {
                                context.ThreadInsideIndicateCompletion = null;
                                Interlocked.Decrement(ref _inIndicateCompletionCount);

                                // Leave will have been called already if the last notification is returning pending
                                // DTS267762: Make sure InIndicateCompletion is released, not based on the thread context state
                                // Otherwise the next request notification may deadlock
                                if (!threadContext.HasBeenDisassociatedFromThread || context.InIndicateCompletion)
                                {
                                    lock (threadContext) {
                                        if (!threadContext.HasBeenDisassociatedFromThread)
                                        {
                                            threadContext.DisassociateFromCurrentThread();
                                        }

                                        context.IndicateCompletionContext = null;
                                        context.InIndicateCompletion      = false;
                                    }
                                }
                            }
                        }
                        else
                        {
                            if (!threadContext.HasBeenDisassociatedFromThread || context.InIndicateCompletion)
                            {
                                lock (threadContext) {
                                    if (!threadContext.HasBeenDisassociatedFromThread)
                                    {
                                        threadContext.DisassociateFromCurrentThread();
                                    }

                                    context.IndicateCompletionContext = null;
                                    context.InIndicateCompletion      = false;
                                }
                            }
                        }
                    }
                }

                if (context.HasWebSocketRequestTransitionStarted && status == RequestNotificationStatus.Pending)
                {
                    // At this point, the WebSocket module event (PostEndRequest) has executed and set up the appropriate contexts for us.
                    // However, there is a race condition that we need to avoid. It is possible that one thread has kicked off some async
                    // work, e.g. via an IHttpAsyncHandler, and that thread is unwinding and has reached this line of execution.
                    // Meanwhile, the IHttpAsyncHandler completed quickly (but asynchronously) and invoked MgdPostCompletion, which
                    // resulted in a new thread calling ProcessRequestNotification. If this second thread starts the WebSocket transition,
                    // then there's the risk that *both* threads might attempt to call WebSocketPipeline.ProcessRequest, which could AV
                    // the process.
                    //
                    // We protect against this by allowing only the thread which started the transition to complete the transition, so in
                    // the above scenario the original thread (which invoked the IHttpAsyncHandler) no-ops at this point and just returns
                    // Pending to its caller.

                    if (context.DidCurrentThreadStartWebSocketTransition)
                    {
                        // We'll mark the HttpContext as complete, call the continuation to kick off the socket send / receive loop, and return
                        // Pending to IIS so that it doesn't advance the state machine until the WebSocket loop completes.
                        root.ReleaseHttpContext();
                        root.WebSocketPipeline.ProcessRequest();
                    }
                }

                return((int)status);
            }
        }
Exemplo n.º 25
0
 internal HttpServerVarsCollection(HttpWorkerRequest wr, HttpRequest request) : base(0x3b)
 {
     this._iis7workerRequest = wr as IIS7WorkerRequest;
     this._request           = request;
     this._populated         = false;
 }
        internal static int ProcessRequestNotificationHelper(IntPtr managedHttpContext, IntPtr nativeRequestContext, IntPtr moduleData, int flags)
        {
            IIS7WorkerRequest         wr                 = null;
            HttpContext               context            = null;
            RequestNotificationStatus notificationStatus = RequestNotificationStatus.Continue;

            if (managedHttpContext == IntPtr.Zero)
            {
                InitializeRequestContext(nativeRequestContext, flags, out wr, out context);
                if (context == null)
                {
                    return(2);
                }
                context.Root();
                UnsafeIISMethods.MgdSetManagedHttpContext(nativeRequestContext, context.ContextPtr);
                HttpRuntime.IncrementActivePipelineCount();
            }
            else
            {
                context = UnwrapContext(managedHttpContext);
                wr      = context.WorkerRequest as IIS7WorkerRequest;
            }
            if ((context.InIndicateCompletion && (context.CurrentThread != Thread.CurrentThread)) && (0x20000000 != UnsafeIISMethods.MgdGetCurrentNotification(nativeRequestContext)))
            {
                while (context.InIndicateCompletion)
                {
                    Thread.Sleep(10);
                }
            }
            NotificationContext notificationContext = context.NotificationContext;
            bool locked = false;

            try
            {
                bool isReEntry = notificationContext != null;
                if (isReEntry)
                {
                    context.ApplicationInstance.AcquireNotifcationContextLock(ref locked);
                }
                context.NotificationContext = new NotificationContext(flags, isReEntry);
                notificationStatus          = HttpRuntime.ProcessRequestNotification(wr, context);
            }
            finally
            {
                if (notificationStatus != RequestNotificationStatus.Pending)
                {
                    context.NotificationContext = notificationContext;
                }
                if (locked)
                {
                    context.ApplicationInstance.ReleaseNotifcationContextLock();
                }
            }
            if (notificationStatus != RequestNotificationStatus.Pending)
            {
                HttpApplication.ThreadContext indicateCompletionContext = context.IndicateCompletionContext;
                if (!context.InIndicateCompletion && (indicateCompletionContext != null))
                {
                    if (notificationStatus == RequestNotificationStatus.Continue)
                    {
                        try
                        {
                            context.InIndicateCompletion = true;
                            Interlocked.Increment(ref _inIndicateCompletionCount);
                            UnsafeIISMethods.MgdIndicateCompletion(nativeRequestContext, ref notificationStatus);
                            goto Label_01C2;
                        }
                        finally
                        {
                            Interlocked.Decrement(ref _inIndicateCompletionCount);
                            if (!indicateCompletionContext.HasLeaveBeenCalled)
                            {
                                lock (indicateCompletionContext)
                                {
                                    if (!indicateCompletionContext.HasLeaveBeenCalled)
                                    {
                                        indicateCompletionContext.Leave();
                                        context.IndicateCompletionContext = null;
                                        context.InIndicateCompletion      = false;
                                    }
                                }
                            }
                        }
                    }
                    if (!indicateCompletionContext.HasLeaveBeenCalled)
                    {
                        lock (indicateCompletionContext)
                        {
                            if (!indicateCompletionContext.HasLeaveBeenCalled)
                            {
                                indicateCompletionContext.Leave();
                                context.IndicateCompletionContext = null;
                                context.InIndicateCompletion      = false;
                            }
                        }
                    }
                }
            }
Label_01C2:
            return((int)notificationStatus);
        }
 internal IIS7UserPrincipal(IIS7WorkerRequest wr, IIdentity identity)
 {
     this._wr       = wr;
     this._identity = identity;
 }
Exemplo n.º 28
0
 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);
     }
 }
Exemplo n.º 29
0
 internal HttpHeaderCollection(HttpWorkerRequest wr, HttpResponse response, int capacity) : base(capacity)
 {
     this._iis7WorkerRequest = wr as IIS7WorkerRequest;
     this._response          = response;
 }