richardszalay/mockhttp

If HttpResponseMessage with StringContent is disposed next request fails

qingqu opened this issue · 4 comments

Here is the repro code:

`var handler = new MockHttpMessageHandler();
var error = @"{""Code"":""ServiceUnavailable"", ""Message"" : ""Service Unavailable.""}";

        handler.When($"https://github.com/richardszalay/mockhttp").Respond(HttpStatusCode.InternalServerError, new StringContent(error));

        var client = handler.ToHttpClient();
        //HttpClient client = new HttpClient();

        var responseA = client.GetAsync("https://github.com/richardszalay/mockhttp").GetAwaiter().GetResult();
        responseA.Dispose();

        var responseB = client.GetAsync("https://github.com/richardszalay/mockhttp").GetAwaiter().GetResult();`

The exception is ObjectDisposedException: Cannot access a disposed object.
Object name: 'System.Net.Http.StringContent'. It doesn't repro with real http request

You should a Respond overload that accepts a Func<HttpContent> or Func<HttpRequestMessage, HttpContent>, that way it will be created for each match.

var handler = new MockHttpMessageHandler();
var error = @"{""Code"":""ServiceUnavailable"", ""Message"" : ""Service Unavailable.""}";

handler.When($"https://github.com/richardszalay/mockhttp")
    .Respond(HttpStatusCode.InternalServerError, () => new StringContent(error));

var client = handler.ToHttpClient(); //HttpClient client = new HttpClient();

var responseA = client.GetAsync("https://github.com/richardszalay/mockhttp").GetAwaiter().GetResult(); responseA.Dispose();

var responseB = client.GetAsync("https://github.com/richardszalay/mockhttp").GetAwaiter().GetResult();

I thought I'd actually marked the regular HttpContent overloads as obsolete. I'll double check and fix it up for a future release.

Thanks for the quick comment, the code you gave can't compile though.

handler.When($"https://github.com/richardszalay/mockhttp") .Respond(HttpStatusCode.InternalServerError, () => new StringContent(error));

Sorry, sent from my phone. Try:

handler.When($"https://github.com/richardszalay/mockhttp") .Respond(HttpStatusCode.InternalServerError, (req) => new StringContent(error));

it works, thanks a lot!