简体   繁体   中英

How can I modify the request body of an HttpWebRequest object?

I have an HttpWebRequest object that I obtain by overriding a method on some thirdparty library. The body of which contains some data that I want to strip out and replace. Is there a way that I can read the content of the HttpWebRequest object, do some replacements, and then write it back? The method I'm overriding allows you to modify the request object before attempting to get a response using it.

I know that I can write bytes to HttpWebRequest , but I'm stuck on how to read it. I want to do something like this, but I cannot.

protected override WebRequest GetWebRequest(Uri uri)
{
    request = (HttpWebRequest)base.GetWebRequest(uri);
    using (var reader = new StreamReader(request.GetRequestStream()))
    {
        var result = reader.ReadToEnd();
        // modify result text and write back
    }

    request.Headers.Add("Authorization", "Bearer " + token);
    return request;
}

I'm afraid this approach will not work, reason is,

if you look at the line 1490 of HttpWebRequest.cs

        /// <devdoc>
        /// <para>Gets a <see cref='System.IO.Stream'/> that the application can use to write request data.
        ///    This property returns a stream that the calling application can write on.
        ///    This property is not settable.  Getting this property may cause the
        ///    request to be sent, if it wasn't already. Getting this property after
        ///    a request has been sent that doesn't have an entity body causes an
        ///    exception to be thrown.
        ///</para>
        /// </devdoc>
        public Stream GetRequestStream(out TransportContext context) {

It states that once you get the property request is sent. Which means you won't be able to modify it. As an example you can try following code

            var postData = "thing1=hello";
            postData += "&thing2=world";
            var data = Encoding.ASCII.GetBytes(postData);

            var request = (HttpWebRequest)WebRequest.Create("https://www.google.com.au/");
            request.Method = "POST";
            request.ContentType = "application/x-www-form-urlencoded";
            request.ContentLength = data.Length;

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }

            using (var stream = request.GetRequestStream())
            {
                stream.Write(data, 0, data.Length);
            }

The second stram.Write will fail.

You could use something like Fiddler.Core to achieve what you need.

Simple answer: you cannot.
Detailed answer:

HttpWebRequest.GetRequestStream ultimately opens a socket connection to remote host. Everything you write to request stream is being sent to host.

In other words, request body isn't stored locally.
If some third party library has created request and has filled its body, then body was already sent to host.

All you can do is to contact library owner to update library API.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM