c# - Transfering large files: combining streamed transfer and content-length -


tl;dr: how can stream large files known size using wcf, , still show progress (content-length) final user (a web browser)?

i have wcf rest service downloads , serves large files (1-20gb) web browser. simplify, think of service proxy. obliges me set transfermode = streamed or transfermode = streamedresponse on binding, or end client have wait source files downloaded webserver before actual download begins. also, buffered transfer mode kills server large files (ram usage). intermediate disk storage not option. transfermode man page:

(...) buffered transfers hold entire message in memory buffer until transfer complete.

but when setting transfermode streamed or streamedresponse, wcf no longer returns header content-length client, , new header transfer-encoding: chunked added. consistent wikipedias article on chunked transfer:

(...) uses transfer-encoding http header in place of content-length header (...)

but know size of data transferred beforehand, , end user, it's frustrating not know size of download. so:

(how) can configure wcf binding use "streaming" transfer mode (more specifically, not buffering entire message before sending) , still use content-length header?

some leads:

  • this q/a states http standard disallows both transfer-encoding , content-length: 123456 in same message, guess that's not option?

  • i have tried modifying headers using inspector in idispatchmessage.beforesendreply @ point content-length header has not yet been removed, , transfer-encoding has not yet been set, it's "too early". have later read chunked transfer encoding on tcp level, changing header @ point wont work if could.

  • i have tried setting aspnetcompatibilityenabled="true", setting wcf transfer mode buffered output (default) , set system.web.httpcontext.current.response.bufferoutput = false;. ignored wcf though, message buffered.

  • it seems missing feature, according this link. there may still quirky workaround somewhere..

this tested workaround, works wcf under iis - have not found solution self-hosted service.

in short - turn on aspnetcompatibility gives runtime access system.web.httpcontext.current.

web.config:

(...)     <system.servicemodel>       <bindings>           <webhttpbinding>               <binding transfermode="streamed">               </binding>           </webhttpbinding>       </bindings>     <servicehostingenvironment aspnetcompatibilityenabled="true" /> (...) </system.servicemodel> 

and in service function returns stream:

httpcontext.current.response.headers.add("content-length",  contentlength.tostring()); 

anything following silently ignored:

weboperationcontext.current.outgoingresponse.headers["content-length"] =          contentlength.tostring(); 

simple that! creds goes uffe lausen's question on msdn


Comments

Popular posts from this blog

c# - How to get the current UAC mode -

postgresql - Lazarus + Postgres: incomplete startup packet -

javascript - Ajax jqXHR.status==0 fix error -