void MakeInputStream ()
{
if (input_stream != null)
return;
if (worker_request == null) {
input_stream = new MemoryStream (new byte [0], 0, 0, false, true);
DoFilter (new byte [1024]);
return;
}
//
// Use an unmanaged memory block as this might be a large
// upload
//
int content_length = ContentLength;
int content_length_kb = content_length / 1024;
HttpRuntimeSection config = HttpRuntime.Section;
if (content_length_kb > config.MaxRequestLength)
throw HttpException.NewWithCode (400, "Upload size exceeds httpRuntime limit.", WebEventCodes.RuntimeErrorPostTooLarge);
int total = 0;
byte [] buffer;
buffer = worker_request.GetPreloadedEntityBody ();
// we check the instance field 'content_length' here, not the local var.
if (this.content_length <= 0 || worker_request.IsEntireEntityBodyIsPreloaded ()) {
if (buffer == null || content_length == 0) {
input_stream = new MemoryStream (new byte [0], 0, 0, false, true);
} else {
input_stream = new MemoryStream (buffer, 0, buffer.Length, false, true);
}
DoFilter (new byte [1024]);
return;
}
if (buffer != null)
total = buffer.Length;
if (content_length > 0 && content_length_kb >= config.RequestLengthDiskThreshold) {
// Writes the request to disk
total = Math.Min (content_length, total);
request_file = GetTempStream ();
Stream output = request_file;
if (total > 0)
output.Write (buffer, 0, total);
if (total < content_length) {
buffer = new byte [Math.Min (content_length, INPUT_BUFFER_SIZE)];
do {
int n;
int min = Math.Min (content_length - total, INPUT_BUFFER_SIZE);
n = worker_request.ReadEntityBody (buffer, min);
if (n <= 0)
break;
output.Write (buffer, 0, n);
total += n;
} while (total < content_length);
}
request_file.SetReadOnly ();
input_stream = request_file;
} else if (content_length > 0) {
// Buffers the request in an IntPtrStream
total = Math.Min (content_length, total);
IntPtr content = Marshal.AllocHGlobal (content_length);
if (content == (IntPtr) 0)
throw HttpException.NewWithCode (
String.Format ("Not enough memory to allocate {0} bytes.", content_length),
WebEventCodes.WebErrorOtherError);
if (total > 0)
Marshal.Copy (buffer, 0, content, total);
if (total < content_length) {
buffer = new byte [Math.Min (content_length, INPUT_BUFFER_SIZE)];
do {
int n;
int min = Math.Min (content_length - total, INPUT_BUFFER_SIZE);
n = worker_request.ReadEntityBody (buffer, min);
if (n <= 0)
break;
Marshal.Copy (buffer, 0, (IntPtr) ((long)content + total), n);
total += n;
} while (total < content_length);
}
input_stream = new IntPtrStream (content, total);
} else {
// Buffers the request in a MemoryStream or writes to disk if threshold exceeded
MemoryStream ms = new MemoryStream ();
Stream output = ms;
if (total > 0)
ms.Write (buffer, 0, total);
buffer = new byte [INPUT_BUFFER_SIZE];
long maxlength = config.MaxRequestLength * 1024L;
long disk_th = config.RequestLengthDiskThreshold * 1024L;
int n;
while (true) {
n = worker_request.ReadEntityBody (buffer, INPUT_BUFFER_SIZE);
if (n <= 0)
break;
total += n;
if (total < 0 || total > maxlength)
throw HttpException.NewWithCode (400, "Upload size exceeds httpRuntime limit.", WebEventCodes.RuntimeErrorPostTooLarge);
if (ms != null && total > disk_th) {
// Swith to on-disk file.
request_file = GetTempStream ();
ms.WriteTo (request_file);
ms = null;
output = request_file;
}
output.Write (buffer, 0, n);
}
if (ms != null) {
input_stream = new MemoryStream (ms.GetBuffer (), 0, (int) ms.Length, false, true);
} else {
request_file.SetReadOnly ();
input_stream = request_file;
}
}
DoFilter (buffer);
if (total < content_length)
throw HttpException.NewWithCode (411, "The request body is incomplete.", WebEventCodes.WebErrorOtherError);
}
#endif