Files
nuki_hub/lib/PsychicHttp/src/PsychicStreamResponse.cpp
2024-12-30 21:45:23 +01:00

90 lines
2.1 KiB
C++

#include "PsychicStreamResponse.h"
#include "PsychicRequest.h"
#include "PsychicResponse.h"
PsychicStreamResponse::PsychicStreamResponse(PsychicResponse* response, const String& contentType)
: PsychicResponseDelegate(response), _buffer(NULL)
{
//setContentType(contentType.c_str());
//addHeader("Content-Disposition", "inline");
}
PsychicStreamResponse::PsychicStreamResponse(PsychicResponse* response, const String& contentType, const String& name)
: PsychicResponseDelegate(response), _buffer(NULL)
{
setContentType(contentType.c_str());
char buf[26 + name.length()];
snprintf(buf, sizeof(buf), "attachment; filename=\"%s\"", name.c_str());
addHeader("Content-Disposition", buf);
}
PsychicStreamResponse::~PsychicStreamResponse()
{
endSend();
}
esp_err_t PsychicStreamResponse::beginSend()
{
if (_buffer)
return ESP_OK;
// Buffer to hold ChunkPrinter and stream buffer. Using placement new will keep us at a single allocation.
_buffer = (uint8_t*)malloc(STREAM_CHUNK_SIZE + sizeof(ChunkPrinter));
if (!_buffer)
{
/* Respond with 500 Internal Server Error */
ESP_LOGE(PH_TAG, "Unable to allocate %" PRIu32 " bytes to send chunk", STREAM_CHUNK_SIZE + sizeof(ChunkPrinter));
httpd_resp_send_err(request(), HTTPD_500_INTERNAL_SERVER_ERROR, "Unable to allocate memory.");
return ESP_FAIL;
}
_printer = new (_buffer) ChunkPrinter(_response, _buffer + sizeof(ChunkPrinter), STREAM_CHUNK_SIZE);
sendHeaders();
return ESP_OK;
}
esp_err_t PsychicStreamResponse::endSend()
{
esp_err_t err = ESP_OK;
if (!_buffer)
err = ESP_FAIL;
else
{
_printer->~ChunkPrinter(); // flushed on destruct
err = finishChunking();
free(_buffer);
_buffer = NULL;
}
return err;
}
void PsychicStreamResponse::flush()
{
if (_buffer)
_printer->flush();
}
size_t PsychicStreamResponse::write(uint8_t data)
{
return _buffer ? _printer->write(data) : 0;
}
size_t PsychicStreamResponse::write(const uint8_t* buffer, size_t size)
{
return _buffer ? _printer->write(buffer, size) : 0;
}
size_t PsychicStreamResponse::copyFrom(Stream& stream)
{
if (_buffer)
return _printer->copyFrom(stream);
return 0;
}