You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

137 lines
2.9 KiB
C++

#include "webcc/body.h"
#include "boost/algorithm/string.hpp"
#include "boost/core/ignore_unused.hpp"
#include "webcc/logger.h"
#include "webcc/utility.h"
#if WEBCC_ENABLE_GZIP
#include "webcc/gzip.h"
#endif
namespace webcc {
// -----------------------------------------------------------------------------
#if WEBCC_ENABLE_GZIP
bool StringBody::Compress() {
if (data_.size() <= kGzipThreshold) {
return false;
}
std::string compressed;
if (gzip::Compress(data_, &compressed)) {
data_ = std::move(compressed);
return true;
}
LOG_WARN("Failed to compress the body data!");
return false;
}
#endif // WEBCC_ENABLE_GZIP
void StringBody::InitPayload() {
index_ = 0;
}
Payload StringBody::NextPayload(bool free_previous) {
boost::ignore_unused(free_previous);
if (index_ == 0) {
index_ = 1;
return Payload{ boost::asio::buffer(data_) };
}
return {};
}
// NOTE:
// - The data will be truncated if it's too large to display.
// - Binary content will not be dumped (TODO).
void StringBody::Dump(std::ostream& os, const std::string& prefix) const {
if (!data_.empty()) {
utility::DumpByLine(data_, os, prefix);
}
}
// -----------------------------------------------------------------------------
FormBody::FormBody(const std::vector<FormPartPtr>& parts,
const std::string& boundary)
: parts_(parts), boundary_(boundary) {
}
std::size_t FormBody::GetSize() const {
std::size_t size = 0;
for (auto& part : parts_) {
size += boundary_.size() + 4; // 4: -- and CRLF
size += part->GetSize();
}
size += boundary_.size() + 6;
return size;
}
void FormBody::Dump(std::ostream& os, const std::string& prefix) const {
for (auto& part : parts_) {
os << prefix << "--" << boundary_ << std::endl;
part->Dump(os, prefix);
}
os << prefix << "--" << boundary_ << "--" << std::endl;
}
void FormBody::InitPayload() {
index_ = 0;
}
Payload FormBody::NextPayload(bool free_previous) {
Payload payload;
// Free previous payload.
if (free_previous) {
if (index_ > 0) {
Free(index_ - 1);
}
}
if (index_ < parts_.size()) {
AddBoundary(&payload);
parts_[index_]->Prepare(&payload);
if (index_ + 1 == parts_.size()) {
AddBoundaryEnd(&payload);
}
}
++index_;
return payload;
}
void FormBody::AddBoundary(Payload* payload) {
using boost::asio::buffer;
payload->push_back(buffer(literal_buffers::DOUBLE_DASHES));
payload->push_back(buffer(boundary_));
payload->push_back(buffer(literal_buffers::CRLF));
}
void FormBody::AddBoundaryEnd(Payload* payload) {
using boost::asio::buffer;
payload->push_back(buffer(literal_buffers::DOUBLE_DASHES));
payload->push_back(buffer(boundary_));
payload->push_back(buffer(literal_buffers::DOUBLE_DASHES));
payload->push_back(buffer(literal_buffers::CRLF));
}
void FormBody::Free(std::size_t index) {
if (index < parts_.size()) {
parts_[index]->Free();
}
}
} // namespace webcc