Mercurial > hg > orthanc
diff OrthancFramework/Sources/HttpServer/HttpOutput.cpp @ 4672:d9942d48fea7
ZipWriter::CancelStream(), ZipWriter::GetArchiveSize() and HttpOutput::AnswerWithoutBuffering()
author | Sebastien Jodogne <s.jodogne@gmail.com> |
---|---|
date | Wed, 02 Jun 2021 17:35:39 +0200 |
parents | c1f36fd13730 |
children | 7053502fbf97 |
line wrap: on
line diff
--- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Fri May 28 18:44:00 2021 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Wed Jun 02 17:35:39 2021 +0200 @@ -573,8 +573,7 @@ } - void HttpOutput::StateMachine::StartMultipart(const std::string& subType, - const std::string& contentType) + void HttpOutput::StateMachine::StartStreamInternal(const std::string& contentType) { if (state_ != State_WritingHeader) { @@ -620,22 +619,37 @@ header += "Connection: close\r\n"; } - // Possibly add the cookies - CheckHeadersCompatibilityWithMultipart(); - for (std::list<std::string>::const_iterator it = headers_.begin(); it != headers_.end(); ++it) { header += *it; } + header += ("Content-Type: " + contentType + "\r\n\r\n"); + + stream_.Send(true, header.c_str(), header.size()); + } + + + void HttpOutput::StateMachine::StartMultipart(const std::string& subType, + const std::string& contentType) + { + CheckHeadersCompatibilityWithMultipart(); + std::string contentTypeHeader; PrepareMultipartMainHeader(multipartBoundary_, contentTypeHeader, subType, contentType); multipartContentType_ = contentType; - header += ("Content-Type: " + contentTypeHeader + "\r\n\r\n"); + + StartStreamInternal(contentTypeHeader); + + state_ = State_WritingMultipart; + } - stream_.Send(true, header.c_str(), header.size()); - state_ = State_WritingMultipart; + + void HttpOutput::StateMachine::StartStream(const std::string& contentType) + { + StartStreamInternal(contentType); + state_ = State_WritingStream; } @@ -736,6 +750,36 @@ } + void HttpOutput::StateMachine::SendStreamItem(const void* data, + size_t size) + { + if (state_ != State_WritingStream) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + if (size > 0) + { + stream_.Send(false, data, size); + } + } + } + + + void HttpOutput::StateMachine::CloseStream() + { + if (state_ != State_WritingStream) + { + throw OrthancException(ErrorCode_BadSequenceOfCalls); + } + else + { + state_ = State_Done; + } + } + + static void AnswerStreamAsBuffer(HttpOutput& output, IHttpStreamAnswer& stream) { @@ -860,4 +904,29 @@ chunked.Flatten(body); Answer(body); } + + + void HttpOutput::AnswerWithoutBuffering(IHttpStreamAnswer& stream) + { + std::string contentType = stream.GetContentType(); + if (contentType.empty()) + { + contentType = MIME_BINARY; + } + + std::string filename; + if (stream.HasContentFilename(filename)) + { + stateMachine_.AddHeader("Content-Disposition", "filename=\"" + std::string(filename) + "\""); + } + + stateMachine_.StartStream(contentType.c_str()); + + while (stream.ReadNextChunk()) + { + stateMachine_.SendStreamItem(stream.GetChunkContent(), stream.GetChunkSize()); + } + + stateMachine_.CloseStream(); + } }