# HG changeset patch # User Sebastien Jodogne # Date 1597762593 -7200 # Node ID 732ad6c618bada3aa918361bd397eda4f6e868b3 # Parent ecc11c23232666df30565942b7ec44f0c3d34f1e removing ChunkedBuffer::AddChunkDestructive() diff -r ecc11c232326 -r 732ad6c618ba OrthancFramework/Sources/ChunkedBuffer.cpp --- a/OrthancFramework/Sources/ChunkedBuffer.cpp Tue Aug 18 16:11:03 2020 +0200 +++ b/OrthancFramework/Sources/ChunkedBuffer.cpp Tue Aug 18 16:56:33 2020 +0200 @@ -66,18 +66,17 @@ } - void ChunkedBuffer::AddChunkDestructive(std::string& chunk) + void ChunkedBuffer::AddChunk(const std::string::const_iterator& begin, + const std::string::const_iterator& end) { - size_t chunkSize = chunk.size(); - - if (chunkSize > 0) + const size_t s = end - begin; + + if (s > 0) { - chunks_.push_back(new std::string); - chunks_.back()->swap(chunk); - numBytes_ += chunkSize; + AddChunk(&begin[0], s); } } - + void ChunkedBuffer::Flatten(std::string& result) { diff -r ecc11c232326 -r 732ad6c618ba OrthancFramework/Sources/ChunkedBuffer.h --- a/OrthancFramework/Sources/ChunkedBuffer.h Tue Aug 18 16:11:03 2020 +0200 +++ b/OrthancFramework/Sources/ChunkedBuffer.h Tue Aug 18 16:56:33 2020 +0200 @@ -59,8 +59,8 @@ void AddChunk(const std::string& chunk); - // The source content will be emptied - void AddChunkDestructive(std::string& chunk); + void AddChunk(const std::string::const_iterator& begin, + const std::string::const_iterator& end); void Flatten(std::string& result); }; diff -r ecc11c232326 -r 732ad6c618ba OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp --- a/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp Tue Aug 18 16:11:03 2020 +0200 +++ b/OrthancFramework/Sources/HttpServer/MultipartStreamReader.cpp Tue Aug 18 16:56:33 2020 +0200 @@ -126,8 +126,7 @@ else { // We have not seen the end of the unused area yet - std::string reminder(current, corpusEnd); - buffer_.AddChunkDestructive(reminder); + buffer_.AddChunk(current, corpusEnd); return; } } @@ -206,8 +205,7 @@ if (current != corpusEnd) { - std::string reminder(current, corpusEnd); - buffer_.AddChunkDestructive(reminder); + buffer_.AddChunk(current, corpusEnd); } } diff -r ecc11c232326 -r 732ad6c618ba OrthancFramework/UnitTestsSources/RestApiTests.cpp --- a/OrthancFramework/UnitTestsSources/RestApiTests.cpp Tue Aug 18 16:11:03 2020 +0200 +++ b/OrthancFramework/UnitTestsSources/RestApiTests.cpp Tue Aug 18 16:56:33 2020 +0200 @@ -146,6 +146,8 @@ TEST(RestApi, ChunkedBuffer) { ChunkedBuffer b; + //b.SetTrailingBufferSize(0); // TODO + ASSERT_EQ(0u, b.GetNumBytes()); b.AddChunk("hello", 5); @@ -159,6 +161,7 @@ ASSERT_EQ("helloworld", s); } + TEST(RestApi, ParseCookies) { IHttpHandler::Arguments headers; @@ -878,3 +881,143 @@ w.SetUrl("coucou"); w.SetUrl("/coucou"); } + + + + +namespace +{ + class TotoBody : public HttpClient::IRequestBody + { + private: + size_t size_; + size_t chunkSize_; + size_t pos_; + + public: + TotoBody(size_t size, + size_t chunkSize) : + size_(size), + chunkSize_(chunkSize), + pos_(0) + { + } + + virtual bool ReadNextChunk(std::string& chunk) + { + if (pos_ == size_) + { + return false; + } + + chunk.clear(); + chunk.resize(chunkSize_); + + size_t i = 0; + while (pos_ < size_ && + i < chunkSize_) + { + chunk[i] = '0' + (pos_ % 7); + pos_++; + i++; + } + + if (i < chunk.size()) + { + chunk.erase(i, chunk.size()); + } + + return true; + } + }; + + class TotoServer : public IHttpHandler + { + public: + virtual bool CreateChunkedRequestReader(std::unique_ptr& target, + RequestOrigin origin, + const char* remoteIp, + const char* username, + HttpMethod method, + const UriComponents& uri, + const Arguments& headers) + { + return false; + } + + virtual bool Handle(HttpOutput& output, + RequestOrigin origin, + const char* remoteIp, + const char* username, + HttpMethod method, + const UriComponents& uri, + const Arguments& headers, + const GetArguments& getArguments, + const void* bodyData, + size_t bodySize) + { + printf("received %llu\n", bodySize); + + const uint8_t* b = reinterpret_cast(bodyData); + + for (size_t i = 0; i < bodySize; i++) + { + if (b[i] != ('0' + i % 7)) + { + throw; + } + } + + output.Answer("ok"); + return true; + } + }; +} + + +#include "../Sources/HttpServer/HttpServer.h" + +TEST(Toto, DISABLED_Toto) +{ + TotoServer handler; + HttpServer server; + server.SetPortNumber(5000); + server.Register(handler); + server.Start(); + + WebServiceParameters w; + w.SetUrl("http://localhost:5000"); + + TotoBody body(600 * 1024 * 1024, 6 * 1024 * 1024 - 17); + //TotoBody body(600 * 1024 * 1024, 1); + + HttpClient c(w, "toto"); + c.SetMethod(HttpMethod_Post); + c.AddHeader("Expect", ""); + c.AddHeader("Transfer-Encoding", "chunked"); + c.SetBody(body); + + std::string s; + ASSERT_TRUE(c.Apply(s)); + + printf(">> [%s]\n", s.c_str()); + + server.Stop(); +} + + + +TEST(Toto, DISABLED_Tata) +{ + boost::posix_time::ptime start = boost::posix_time::microsec_clock::local_time(); + + ChunkedBuffer b; + for (unsigned int i = 0; i < 600 * 1024 * 1024; i++) + { + b.AddChunk("a", 1); + } + + boost::posix_time::ptime end = boost::posix_time::microsec_clock::local_time(); + + printf("time: %d\n", (end-start).total_microseconds()); +}