| 221 | |
| 222 | template<bool isRequest, typename Body, typename StreamVariant> |
| 223 | void OutgoingHttpMessage<isRequest, Body, StreamVariant>::SendFile( |
| 224 | const String& path, |
| 225 | const boost::asio::yield_context& yc |
| 226 | ) |
| 227 | { |
| 228 | std::ifstream fp(path.CStr(), std::ifstream::in | std::ifstream::binary | std::ifstream::ate); |
| 229 | fp.exceptions(std::ifstream::failbit | std::ifstream::badbit | std::ifstream::eofbit); |
| 230 | |
| 231 | std::uint64_t remaining = fp.tellg(); |
| 232 | fp.seekg(0); |
| 233 | |
| 234 | Base::content_length(remaining); |
| 235 | Base::body().Start(); |
| 236 | |
| 237 | while (remaining) { |
| 238 | auto maxTransfer = std::min(remaining, static_cast<std::uint64_t>(l_FlushThreshold)); |
| 239 | |
| 240 | using BodyBuffer = std::decay_t<decltype(std::declval<typename Body::value_type>().Buffer())>; |
| 241 | using BufferOrSequence = typename BodyBuffer::mutable_buffers_type; |
| 242 | |
| 243 | boost::asio::mutable_buffer buf; |
| 244 | |
| 245 | if constexpr (!std::is_same_v<BufferOrSequence, boost::asio::mutable_buffer>) { |
| 246 | buf = *Base::body().Buffer().prepare(maxTransfer).begin(); |
| 247 | } else { |
| 248 | buf = Base::body().Buffer().prepare(maxTransfer); |
| 249 | } |
| 250 | fp.read(static_cast<char*>(buf.data()), buf.size()); |
| 251 | Base::body().Buffer().commit(buf.size()); |
| 252 | |
| 253 | remaining -= buf.size(); |
| 254 | Flush(yc); |
| 255 | } |
| 256 | } |
| 257 | |
| 258 | template<bool isRequest, typename Body, typename StreamVariant> |
| 259 | JsonEncoder OutgoingHttpMessage<isRequest, Body, StreamVariant>::GetJsonEncoder(bool pretty) |
no test coverage detected