I have a WCF REST service running in streaming (unbuffered) mode that is receiving a file upload as raw bytes in the body of an HTTP request. Before reading the incoming stream (a MessageBodyStream
), I check the request headers and make sure that the Content-Length
is the right size for that particular operation.
If the Content-Length
is larger than the allowed size, I'd like to immediate return an error response (by throwing a WebFaultException
) without waiting for the rest of the request to be transferred.
However, it seems that WCF tries to read the stream to the end even after the exception is thrown -- if the client is sending a 50 MB file, all 50 MB will be transferred before a response is sent.
Is there any way to avoid this, and to interrupt receiving the HTTP request?
Related question: Why is WCF reading input stream to EOF on Close()?
EDIT: Added code excerpt
The OperationContract
and the upload helper method:
[OperationContract]
[WebInvoke(UriTemplate = /* ... */, Method = "POST",
ResponseFormat = WebMessageFormat.Json, BodyStyle = WebMessageBodyStyle.Bare)]
public void UploadMyFile(string guid, Stream fileStream)
{
string targetPath = /* targetPath */;
UploadFile(fileStream, targetPath, /* targetFileName */);
}
private bool UploadFile(Stream stream, string targetDirectory,
string targetFileName = null, int maximumSize = 1024 * 500,
Func<string, bool> tempFileValidator = null)
{
int size = 0;
int.TryParse(IncomingRequest.Headers[HttpRequestHeader.ContentLength], out size);
if (size == 0)
{
ThrowJsonException(HttpStatusCode.LengthRequired, "Valid Content-Length required");
}
else if (size > maximumSize)
{
ThrowJsonException(HttpStatusCode.RequestEntityTooLarge, "File is too big");
}
if (!FileSystem.SaveFileFromStream(stream, targetDirectory, targetFileName, tempFileValidator))
{
ThrowJsonException(HttpStatusCode.InternalServerError, "Saving file failed");
}
return true;
}