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) , setsystem.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
Post a Comment