using System.Net.Sockets;
using System.Runtime.InteropServices;
namespace System.Net {
- class RequestStream : NetworkStream
+ class RequestStream : Stream
{
byte [] buffer;
int offset;
int length;
- long available;
+ long remaining_body;
bool disposed;
+ Stream stream;
- internal RequestStream (Socket sock, byte [] buffer, int offset, int length) :
- base (sock, false)
+ internal RequestStream (Stream stream, byte [] buffer, int offset, int length)
+ : this (stream, buffer, offset, length, -1)
{
- this.buffer = buffer;
- this.offset = offset;
- this.length = length;
- this.available = -1;
}
- internal RequestStream (Socket sock, byte [] buffer, int offset, int length, long contentlength) :
- base (sock, false)
+ internal RequestStream (Stream stream, byte [] buffer, int offset, int length, long contentlength)
{
+ this.stream = stream;
this.buffer = buffer;
this.offset = offset;
this.length = length;
- this.available = contentlength;
+ this.remaining_body = contentlength;
}
public override bool CanRead {
if (off > len - count)
throw new ArgumentException ("Reading would overrun buffer");
- if (this.available == 0)
+ if (this.remaining_body == 0)
return -1;
if (this.length == 0)
return 0;
int size = Math.Min (this.length, count);
- if (this.available > 0)
- size = (int) Math.Min (size, this.available);
+ if (this.remaining_body > 0)
+ size = (int) Math.Min (size, this.remaining_body);
+
+ if (this.offset > this.buffer.Length - size) {
+ size = Math.Min (size, this.buffer.Length - this.offset);
+ }
+ if (size == 0)
+ return 0;
+
Buffer.BlockCopy (this.buffer, this.offset, buffer, off, size);
this.offset += size;
this.length -= size;
- if (this.available > 0)
- available -= size;
+ if (this.remaining_body > 0)
+ remaining_body -= size;
return size;
}
if (disposed)
throw new ObjectDisposedException (typeof (RequestStream).ToString ());
- // Avoid reading past the end of the request to allow
- // for HTTP pipelining
+ // Call FillFromBuffer to check for buffer boundaries even when remaining_body is 0
int nread = FillFromBuffer (buffer, offset, count);
- if (nread == -1) // No more bytes available (Content-Length)
+ if (nread == -1) { // No more bytes available (Content-Length)
return 0;
- if (nread > 0)
+ } else if (nread > 0) {
return nread;
+ }
- nread = base.Read (buffer, offset, count);
+ nread = stream.Read (buffer, offset, count);
+ if (nread > 0 && remaining_body > 0)
+ remaining_body -= nread;
return nread;
}
// Avoid reading past the end of the request to allow
// for HTTP pipelining
- if (available != -1 && count > available)
- count = (int) Math.Min (Int32.MaxValue, available);
- return base.BeginRead (buffer, offset, count, cback, state);
+ if (remaining_body >= 0 && count > remaining_body)
+ count = (int) Math.Min (Int32.MaxValue, remaining_body);
+ return stream.BeginRead (buffer, offset, count, cback, state);
}
public override int EndRead (IAsyncResult ares)
}
// Close on exception?
- int nread = base.EndRead (ares);
- if (available != -1)
- available -= nread;
+ int nread = stream.EndRead (ares);
+ if (remaining_body > 0 && nread > 0)
+ remaining_body -= nread;
return nread;
}