Copying Http Request InputStream

不问归期 提交于 2019-12-04 22:14:23

问题


I'm implementing a proxy action method that forwards the incoming web request and forwards it to another web page, adding a few headers. The action method works file for GET requests, but I'm still struggling with forwarding the incoming POST request.

The problem is that I don't know how to properly write the request body to the outgoing HTTP request stream.

Here's a shortened version of what I've got so far:

//the incoming request stream
var requestStream=HttpContext.Current.Request.InputStream;
//the outgoing web request
var webRequest = (HttpWebRequest)WebRequest.Create(url);
...

//copy incoming request body to outgoing request
if (requestStream != null && requestStream.Length>0)
            {
                long length = requestStream.Length;
                webRequest.ContentLength = length;
                requestStream.CopyTo(webRequest.GetRequestStream())                    
            }

//THE NEXT LINE THROWS A ProtocolViolationException
 using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse())
                {
                    ...
                }

As soon as I call GetResponse on the outgoing http request, I get the following exception:

ProtocolViolationException: You must write ContentLength bytes to the request stream before calling [Begin]GetResponse.

I don't understand why this is happening, since requestStream.CopyTo should have taken care of writing the right amount of bytes.

Any suggestions would be greatly appreciated.

Thanks,

Adrian


回答1:


Yes, .Net is very finicky about this. The way to solve the problem is to both flush and close the stream. In other words:

Stream webStream = null;

try
{
    //copy incoming request body to outgoing request
    if (requestStream != null && requestStream.Length>0)
    {
        long length = requestStream.Length;
        webRequest.ContentLength = length;
        webStream = webRequest.GetRequestStream();
        requestStream.CopyTo(webStream);
    }
}
finally
{
    if (null != webStream)
    {
        webStream.Flush();
        webStream.Close();    // might need additional exception handling here
    }
}

// No more ProtocolViolationException!
using (HttpWebResponse response = (HttpWebResponse)webRequest.GetResponse())
{
    ...
}



回答2:


The answer @brian works, however, I found that once requestStream.CopyTo(stream) was called, it would fire off my HttpWebResponse. This was an issue since I wasn't quite ready to send the request. So if anyone is having an issue with not all of the request headers or other data being sent, it is because CopyTo is firing your request.




回答3:


try modifying the block inside if statement

long length = requestStream.Length;
webRequest.ContentLength = length;
requestStream.CopyTo(webRequest.GetRequestStream())

with

webRequest.Method = "POST";
webRequest.ContentLength = requestStream.Length;
webRequest.ContentType = "application/x-www-form-urlencoded";
Stream stream = webRequest.GetRequestStream();
requestStream.CopyTo(stream);
stream.Close();


来源:https://stackoverflow.com/questions/3447589/copying-http-request-inputstream

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!