ListenerRequest.UrlReferrer is disposed

Hi all,

I’m guessing something has changed in v5 as my code below is now throwing an exception on the last line: Cannot access a disposed object.

public void Log(IRequest request, object requestDto, object response, TimeSpan elapsed)
    {
        if (ExcludeRequestDtoTypes != null && requestDto != null &&
            ExcludeRequestDtoTypes.Contains(requestDto.GetType()))
            return;

        var session = request.GetSession();

        var requestLogEntry = new ServiceModel.Database.Admin.RequestLogEntry();
        requestLogEntry.PopulateWith(request);
        requestLogEntry.Session = EnableSessionTracking ? session : null;
        requestLogEntry.SessionId = EnableSessionTracking ? session.Id : null;
        requestLogEntry.UserAuthId = session.UserAuthId;
        requestLogEntry.RequestDuration = elapsed;
        requestLogEntry.ResponseDto = EnableResponseTracking ? response : null;
        requestLogEntry.DateTime = DateTime.UtcNow;
        requestLogEntry.IpAddress = request.UserHostAddress ?? request.RemoteIp;
        requestLogEntry.Referer = request.UrlReferrer == null ? "n/a" : request.UrlReferrer.OriginalString;

Any ideas?

Not able to repro this either, is this failing for all Requests or only specific requests? If it’s a specific request can provide an example of the Request it fails for?

Also does changing it to access the referrer through the Headers still cause the error?

requestLogEntry.Referer = request.Headers[HttpHeaders.Referer];

I’ll do some more testing and get back to you - will probably be later in the weekend though

Going to need a stand-alone repro for this as I haven’t been able to repro this for either Normal Servoce or Error requests as seen in RequestLogsFeatureTests.cs.

It appears that’s something disposing/short-circuiting the Request which is preventing access to the HTTP Request context.

I just went to review this and found that I can’t reproduce it now either. The only thing I’ve changed (the SS service has been running in debug mode ever since) is I’ve swapped out the JsonServiceClient for Angular’s HttpClient…

I will swap the JsonServiceClient back in and see if that helps me recreate it…

OK, so I’ve swapped HttpClient back out for JsonServiceClient and can recreate the issue.

ServiceStack: 5.0.2
Webstorm: 2017.3.2
ServiceStack IDEA: 1.0.12

This works:

constructor(private _script: ScriptLoaderService, private httpClient: HttpClient) { }

ngOnInit() {
    this.httpClient.get<SystemsResponse>("http://localhost:8088/api/cached/systems").subscribe((systems: SystemsResponse) => console.log(systems));
}

But this doesn’t:

constructor(private _script: ScriptLoaderService, private jsonServiceClient: JsonServiceClient) { }

ngOnInit() {
    this.jsonServiceClient.get<CachedSystems>("/cached/systems").then(systems => console.log(systems));
}

Then I investigated and found that its the OPTIONS request sent by the JsonServiceClient (my HttpClient call doesn’t send them).
I then used Postman to send the same requests, GET works but OPTIONS causes the exception…

Does that help?

I’ve added a test for OPTIONS requests with CorsFeature enabled which short-circuits requests which also logs without error, but the default Memory Logger also checks if the Response is closed for additional properties to log, although it’s able to read the Referrer from request.Headers[HttpHeaders.Referer] fine.

I’ll change my RequestLogger to pull the OriginalReferrerUrl from request.Headers[HttpHeaders.Referer] instead then. Thanks.

Do you think there is something I’m doing that is causing this short circuit…?

If you have CorsFeature enabled it will short-circuit OPTIONS requests to return the appropriate response.

OK, I get it, thanks for your help