Mercurial > hg > orthanc
changeset 6302:27fe473be5b7
Improved streaming of HTTP responses under OS pressure
author | Alain Mazy <am@orthanc.team> |
---|---|
date | Tue, 09 Sep 2025 12:54:00 +0200 |
parents | 470e2a8b42e0 |
children | 88b7494557f2 |
files | NEWS OrthancFramework/Sources/HttpServer/HttpOutput.cpp OrthancFramework/Sources/HttpServer/HttpServer.cpp |
diffstat | 3 files changed, 21 insertions(+), 5 deletions(-) [+] |
line wrap: on
line diff
--- a/NEWS Tue Sep 02 18:00:26 2025 +0200 +++ b/NEWS Tue Sep 09 12:54:00 2025 +0200 @@ -6,6 +6,11 @@ * Under Windows, the console output is now configured to interpret strings as UTF-8. This notably allow cyrillic strings to display correctly in the console. +* Improved streaming of HTTP responses under OS pressure. In some conditions, when the OS + was not able to send a full buffer over the network, Orthanc was not retrying + to send the remaining part. This is now fixed. + (https://discourse.orthanc-server.org/t/incomplete-zip-downloads-from-get-studies-id-media/6046) + Version 1.12.9 (2025-08-11)
--- a/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Tue Sep 02 18:00:26 2025 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpOutput.cpp Tue Sep 09 12:54:00 2025 +0200 @@ -805,6 +805,8 @@ void HttpOutput::StateMachine::SendStreamItem(const void* data, size_t size) { + LOG(TRACE) << "SendStreamItem " << size << " bytes"; + if (state_ != State_WritingStream) { throw OrthancException(ErrorCode_BadSequenceOfCalls); @@ -821,6 +823,8 @@ void HttpOutput::StateMachine::CloseStream() { + LOG(TRACE) << "CloseStream"; + if (state_ != State_WritingStream) { throw OrthancException(ErrorCode_BadSequenceOfCalls);
--- a/OrthancFramework/Sources/HttpServer/HttpServer.cpp Tue Sep 02 18:00:26 2025 +0200 +++ b/OrthancFramework/Sources/HttpServer/HttpServer.cpp Tue Sep 09 12:54:00 2025 +0200 @@ -119,12 +119,19 @@ { size_t packetSize = std::min(remainingSize, static_cast<size_t>(INT_MAX)); - int status = mg_write(connection_, &(reinterpret_cast<const char*>(buffer)[offset]), packetSize); + // note: mg_write may sometimes only send a part of the buffer e.g. when the OS is not able to send the full buffer -> we might need to iterate a few times + size_t totalSent = 0; + while (totalSent < packetSize) + { + int status = mg_write(connection_, &(reinterpret_cast<const char*>(buffer)[offset + totalSent]), packetSize - totalSent); - if (status != static_cast<int>(packetSize)) - { - // status == 0 when the connection has been closed, -1 on error - throw OrthancException(ErrorCode_NetworkProtocol); + if (status <= 0) + { + // status == 0 when the connection has been closed, -1 on error + throw OrthancException(ErrorCode_NetworkProtocol); + } + + totalSent += status; } offset += packetSize;