Mercurial > hg > orthanc
comparison 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 |
comparison
equal
deleted
inserted
replaced
4671:42e1f5bde40b | 4672:d9942d48fea7 |
---|---|
571 | 571 |
572 contentTypeHeader = ("multipart/" + subType + "; type=" + tmp + "; boundary=" + boundary); | 572 contentTypeHeader = ("multipart/" + subType + "; type=" + tmp + "; boundary=" + boundary); |
573 } | 573 } |
574 | 574 |
575 | 575 |
576 void HttpOutput::StateMachine::StartMultipart(const std::string& subType, | 576 void HttpOutput::StateMachine::StartStreamInternal(const std::string& contentType) |
577 const std::string& contentType) | |
578 { | 577 { |
579 if (state_ != State_WritingHeader) | 578 if (state_ != State_WritingHeader) |
580 { | 579 { |
581 throw OrthancException(ErrorCode_BadSequenceOfCalls); | 580 throw OrthancException(ErrorCode_BadSequenceOfCalls); |
582 } | 581 } |
618 else | 617 else |
619 { | 618 { |
620 header += "Connection: close\r\n"; | 619 header += "Connection: close\r\n"; |
621 } | 620 } |
622 | 621 |
623 // Possibly add the cookies | |
624 CheckHeadersCompatibilityWithMultipart(); | |
625 | |
626 for (std::list<std::string>::const_iterator | 622 for (std::list<std::string>::const_iterator |
627 it = headers_.begin(); it != headers_.end(); ++it) | 623 it = headers_.begin(); it != headers_.end(); ++it) |
628 { | 624 { |
629 header += *it; | 625 header += *it; |
630 } | 626 } |
627 | |
628 header += ("Content-Type: " + contentType + "\r\n\r\n"); | |
629 | |
630 stream_.Send(true, header.c_str(), header.size()); | |
631 } | |
632 | |
633 | |
634 void HttpOutput::StateMachine::StartMultipart(const std::string& subType, | |
635 const std::string& contentType) | |
636 { | |
637 CheckHeadersCompatibilityWithMultipart(); | |
631 | 638 |
632 std::string contentTypeHeader; | 639 std::string contentTypeHeader; |
633 PrepareMultipartMainHeader(multipartBoundary_, contentTypeHeader, subType, contentType); | 640 PrepareMultipartMainHeader(multipartBoundary_, contentTypeHeader, subType, contentType); |
634 multipartContentType_ = contentType; | 641 multipartContentType_ = contentType; |
635 header += ("Content-Type: " + contentTypeHeader + "\r\n\r\n"); | 642 |
636 | 643 StartStreamInternal(contentTypeHeader); |
637 stream_.Send(true, header.c_str(), header.size()); | 644 |
638 state_ = State_WritingMultipart; | 645 state_ = State_WritingMultipart; |
646 } | |
647 | |
648 | |
649 void HttpOutput::StateMachine::StartStream(const std::string& contentType) | |
650 { | |
651 StartStreamInternal(contentType); | |
652 state_ = State_WritingStream; | |
639 } | 653 } |
640 | 654 |
641 | 655 |
642 static void PrepareMultipartItemHeader(std::string& target, | 656 static void PrepareMultipartItemHeader(std::string& target, |
643 size_t length, | 657 size_t length, |
731 catch (OrthancException&) | 745 catch (OrthancException&) |
732 { | 746 { |
733 } | 747 } |
734 | 748 |
735 state_ = State_Done; | 749 state_ = State_Done; |
750 } | |
751 | |
752 | |
753 void HttpOutput::StateMachine::SendStreamItem(const void* data, | |
754 size_t size) | |
755 { | |
756 if (state_ != State_WritingStream) | |
757 { | |
758 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
759 } | |
760 else | |
761 { | |
762 if (size > 0) | |
763 { | |
764 stream_.Send(false, data, size); | |
765 } | |
766 } | |
767 } | |
768 | |
769 | |
770 void HttpOutput::StateMachine::CloseStream() | |
771 { | |
772 if (state_ != State_WritingStream) | |
773 { | |
774 throw OrthancException(ErrorCode_BadSequenceOfCalls); | |
775 } | |
776 else | |
777 { | |
778 state_ = State_Done; | |
779 } | |
736 } | 780 } |
737 | 781 |
738 | 782 |
739 static void AnswerStreamAsBuffer(HttpOutput& output, | 783 static void AnswerStreamAsBuffer(HttpOutput& output, |
740 IHttpStreamAnswer& stream) | 784 IHttpStreamAnswer& stream) |
858 | 902 |
859 std::string body; | 903 std::string body; |
860 chunked.Flatten(body); | 904 chunked.Flatten(body); |
861 Answer(body); | 905 Answer(body); |
862 } | 906 } |
907 | |
908 | |
909 void HttpOutput::AnswerWithoutBuffering(IHttpStreamAnswer& stream) | |
910 { | |
911 std::string contentType = stream.GetContentType(); | |
912 if (contentType.empty()) | |
913 { | |
914 contentType = MIME_BINARY; | |
915 } | |
916 | |
917 std::string filename; | |
918 if (stream.HasContentFilename(filename)) | |
919 { | |
920 stateMachine_.AddHeader("Content-Disposition", "filename=\"" + std::string(filename) + "\""); | |
921 } | |
922 | |
923 stateMachine_.StartStream(contentType.c_str()); | |
924 | |
925 while (stream.ReadNextChunk()) | |
926 { | |
927 stateMachine_.SendStreamItem(stream.GetChunkContent(), stream.GetChunkSize()); | |
928 } | |
929 | |
930 stateMachine_.CloseStream(); | |
931 } | |
863 } | 932 } |