Apparently the response.GetResponseStream()
returns a Stream
that will not Read()
the entire response. In order to solve this issue I had to build up the following on the response:
byte[] data = new byte[response.ContentLength];
int offset = 0;
while (offset < response.ContentLength)
{
offset += dataStream.Read(data, offset, (int)(response.ContentLength - offset));
}
List<byte> content = new List<byte>(2 * (int)response.ContentLength);
Then, I was able to write out through the second stream, which finally did receive all the content that was sent. Each time I checked the file output before this change, the file contained exactly what was in content. So, it seems that the whole problem was based on the initial response not "Reading" all of the data that was sent.
EDIT:
Further, the data coming into the server was not complete. The boost:asio
http example code had issues for capturing all the content data. I would receive only a portion of the incoming content or file data. It seemed to stop at 8008 bytes every time. I found that the parse function was incorrect. So I modified it like this:
template <typename InputIterator>
boost::tuple<boost::tribool, InputIterator> parse(request& req,
InputIterator begin, InputIterator end)
{
//may have to handle multipart here.
while (begin != end)
{
boost::tribool result = consume(req, *begin++);
if (result || !result)
{
return boost::make_tuple(result, begin);
}
}
boost::tribool result = boost::indeterminate;
if(state_ == getting_content) {
if(req.content.length() < content_length_) {
result = boost::indeterminate;
} else {
result = true;//boost::indeterminate;
}
}
return boost::make_tuple(result, begin);
}
The biggest part was to make the check for the content
length and return indeterminate
for this function. And then ensure that the connection
had code to read_some
more, which the example code does have.