Skip to content

Ignore Missing Entity on Parent Requests #235

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged

Conversation

samunro
Copy link
Contributor

@samunro samunro commented Mar 11, 2022

The Rewrite module for example can result in HttpApplication.EndRequest being called multiple times - once for the original (parent) request and once for the child request which has the rewritten URL. The parent request will skip BeginRequest and will not be populated with an X-Ray Entity. It is the child request which is the important one and the parent request will only fail when AddHttpInformation is called anyway. So bail out here in the parent request.

"The parent request jumps ahead in the pipeline to the end request notification, and waits for the child request to complete."
microsoft/ApplicationInsights-dotnet#1744

"When a client requests a specific URL (webpage), IIS may sometimes re-request the same URL or another URL on the server side. The client's original request is called the parent request, and the request that IIS executes is called the child request.
https://docs.microsoft.com/en-us/troubleshoot/developer/webapps/iis/development/duplicate-aspnet-events

By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license.

…s that have not been populated with an X-Ray Entity.
@samunro samunro requested a review from a team as a code owner March 11, 2022 11:55
@samunro
Copy link
Contributor Author

samunro commented Mar 22, 2022

Here are a few more details as the issue that this pull request addresses is still affecting us.

URL Rewrite is a very popular extension to IIS that is provided and supported by Microsoft. One of its core features is to map URLs that are exposed to users to internal URLs. When this happens, the 'parent' request spawns a 'child' request with the mapped URL. This is passed through the complete request and response processing pipeline. The 'parent' request skips most of that and 'waits' for the 'child' request at the end of the pipeline (see the links that I provided above for some more details). The effect is that the parent request does not trigger a call to AWSXRayASPNET.ProcessHTTPRequest but does result in a call to AWSXRayASPNET.ProcessHTTPResponse as can be seen in the stack trace below.

There is an implicit assumption in AWSXRayASPNET.ProcessHTTPResponse that a segment was started in a call to AWSXRayRecorderImpl.BeginSegment in AWSXRayASPNET.ProcessHTTPRequest. That is not the case for a 'parent' request and an EntityNotAvailableException is thrown.

I think that the only reasonable way to handle this scenario is to bail out of AWSXRayASPNET.ProcessHTTPResponse for the 'parent' request. I.e. Not attempt to add HTTP information to a segment that does not exist because it was never started.

@srprash Any thoughts?

Amazon.XRay.Recorder.Core.Exceptions.EntityNotAvailableException: Entity doesn't exist in HTTPContext
   at Amazon.XRay.Recorder.Core.Internal.Context.HybridContextContainer.InjectEntityInTraceContext()
   at Amazon.XRay.Recorder.Core.AWSXRayRecorderImpl.AddHttpInformation(String key, Object value)
--- End of stack trace from previous location where exception was thrown ---
   at System.Runtime.ExceptionServices.ExceptionDispatchInfo.Throw()
   at Amazon.XRay.Recorder.Core.AWSXRayRecorderImpl.AddHttpInformation(String key, Object value)
   at Amazon.XRay.Recorder.Handlers.AspNet.AWSXRayASPNET.ProcessHTTPResponse(Object sender, EventArgs e)
   at System.Web.HttpApplication.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute()
   at System.Web.HttpApplication.ExecuteStepImpl(IExecutionStep step)
   at System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously)

@srprash
Copy link
Collaborator

srprash commented Mar 28, 2022

Hi @samunro
Thanks for opening this PR and providing detailed background. I am not familiar URL rewrite at all so I'm going to need some time to review the PR.
Thanks for being patient. I will get to it soon.

@samunro
Copy link
Contributor Author

samunro commented Apr 11, 2022

Hi @srprash,

I was able to reproduce this scenario in a new project based on the following Visual Studio 2022 project template.

ASP.NET Web Application (.NET Framework)

These are the changes that I made.

Add this as a child of the configuration element in Web.config. It will rewrite a URL where the path is '/rewrite' to target the root path.

<system.webServer>
	<rewrite>
		<rules>
			<rule name="Rewrite">
				<match url=".*"/>
				<conditions>
					<add input="{PATH_INFO}" pattern="^\/rewrite$" />
				</conditions>
				<action type="Rewrite" url="/" />
			</rule>
		</rules>
	</rewrite>
</system.webServer>

Add this to the MvcApplication class in Global.asax.cs.

    protected void Application_BeginRequest(object sender, EventArgs args)
    {

    }

    protected void Application_EndRequest(object sender, EventArgs args)
    {

    }

To test, I set breakpoints on both BeginRequest and EndRequest above and then browsed to the following URL.

https://localhost:44327/rewrite

I inspected Request.Url as the breakpoints were hit and this is what I saw.

BeginRequest and then EndRequest were hit for the following URL (the 'child request').

https://localhost:44327/

Then EndRequest (but not BeginRequest) was hit for the following URL (the 'parent request').

https://localhost:44327/rewrite

I hope this shows that assuming in EndRequest that a segment will have been created in BeginRequest is not valid.

Copy link
Collaborator

@srprash srprash left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @samunro for handling this case. Apologies for delay in reviewing the PR.

@srprash srprash merged commit d1cdfdb into aws:master May 31, 2022
@samunro
Copy link
Contributor Author

samunro commented May 31, 2022

Thanks @srprash! Do you have any idea when this will make it through to the NuGet package?

@samunro samunro deleted the ignore-missing-entity-on-parent-requests branch June 17, 2022 10:44
jon-armen pushed a commit to jon-armen/aws-xray-sdk-dotnet that referenced this pull request Jul 11, 2022
…s that have not been populated with an X-Ray Entity. (aws#235)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants