HttpWebRequest scope response stream

I have this method:

public Stream Load(string term)
{
    var url = CreateSearchUrl(term);

    var webRequest = (HttpWebRequest)WebRequest.Create(url);
    var webResponse = webRequest.GetResponse();

    return new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
}

As you can see, I am returning the stream back to the caller, but I'm not sure if this is safe from the point of view of WebRequest, which is removed by the runtime and thus invalidates my returned stream.

I could convert it to an array of bytes and return a MemoryStream or even use a WebClient, but I just don't like this idea =).

Thank!

+3
source share
1 answer

There is no easy way to safely return a Stream without leaking resources. The main problem is removing WebResponse:

public Stream Load(string term)
{
    var url = CreateSearchUrl(term);

    var webRequest = (HttpWebRequest)WebRequest.Create(url);
    var webResponse = webRequest.GetResponse(); // whoops this doesn't get disposed!

    return new GZipStream(webResponse.GetResponseStream(), CompressionMode.Decompress);
}

Closing WebResponse is actually more important than closing the response stream, since closing WebResponse implicitly closes the response stream.

, WebResponse Stream, - GZipStream, WebResponse ( GZipStream), . , :

class WebResponseDisposingStream : Stream
{
    private readonly WebResponse response;
    private readonly Stream stream;

    public WebResponseDisposingStream(WebResponse response, Stream stream)
    {
        if (response == null)
            throw new ArgumentNullException("response");
        if (stream == null)
            throw new ArgumentNullException("stream");

        this.response = response;
        this.stream = stream;
    }

    public override void Close()
    {
        this.response.Close();
        this.stream.Close();
    }

    // override all the methods on stream and delegate the call to this.stream

    public override void Flush() { this.stream.Flush(); } // example delegation for Flush()
    // ... on and on for all the other members of Stream
}

, , , Stream, :

public void Load(string term, Action<Stream> action)
{
    var url = CreateSearchUrl(term);

    var webRequest = (HttpWebRequest)WebRequest.Create(url);

    using (var webResponse = webRequest.GetResponse())
    using (var responseStream = webResponse.GetResponseStream())
    using (var gzipStream = new GZipStream(responseStream, CompressionMode.Decompress))
    {
        action(gzipStream);
    }
}

, Stream. :

Load("test", stream => Console.WriteLine("Length=={0}", stream.Length));

: , HTTP . . Wikipedia. HttpWebRequest HTTP- AutomaticDecompression. HTTP , HTTP (, ..).

+3

All Articles