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
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())
{
...
}