2012-01-26 3 views
1

У меня есть служба WCF REST, работающая в потоковом (небуферизованном) режиме, которая принимает файл в виде необработанных байтов в теле HTTP-запроса. Прежде чем читать входящий поток (a MessageBodyStream), я проверяю заголовки запросов и удостоверяюсь, что Content-Length является правильным размером для этой конкретной операции.Прерывание, считывающее входящий запрос в WCF REST

Если размер Content-Length больше разрешенного размера, я хотел бы немедленно вернуть ответ об ошибке (путем выброса WebFaultException), не дожидаясь передачи остальной части запроса.

Однако кажется, что WCF пытается прочитать поток до конца даже после того, как выбрано исключение - если клиент отправляет файл размером 50 МБ, все 50 МБ будут переданы до отправки ответа.

Есть ли способ избежать этого и прервать прием HTTP-запроса?

Связанные вопрос: Why is WCF reading input stream to EOF on Close()?

EDIT: Добавлен фрагмент кода

OperationContract и вспомогательный метод загрузки:

[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; 
} 
+0

Показать код. 'Я проверяю заголовки запросов, где вы это делаете? Где вы читаете поток? – Aliostad

+0

@Aliostad, я разместил выдержку. – kpozin

+0

Хорошо. Спасибо .... – Aliostad

ответ

0

HttpWebRequest и, как правило HTTP запрос не поддерживает потоковое, который под это реализованный с помощью кодированной кодировки, которая является концепцией серверной стороны.

этот вопрос, я просто ответил тоже что связано: IIS7 refuses chunked-encoded file upload

Когда вы пишете для запроса потока, то в настоящее время в локальном буфере до тех пор, пока отправлено, так как он имеет окукливаются заголовок длины содержимого. Вы можете это проверить в fiddler.

+0

На самом деле меня не беспокоит то, что делает клиент (в этом случае я на самом деле вручную заполняю заголовок Content-Length на стороне клиента, прежде чем писать в поток запросов). Я просто хочу, чтобы * сервер * мог отменить * получение запроса *. Я знаю, что это технически возможно, потому что WCF может прерывать запросы, когда они превышают настроенный максимальный размер сообщения. Я хотел бы сделать это из моего собственного кода сервера, когда моя операция не похожа на запрос. – kpozin

1

Возможно, вы можете написать компонент инспектор сообщений, который может перехватить тело и контекст запроса.

После проверки сообщения/контекста вы можете выполнить исключение (если хотите).

HTH

Смежные вопросы