Unverified Commit dd5e155d authored by Dennis Jenkins's avatar Dennis Jenkins Committed by GitHub

Merge pull request #620 from Ne02ptzero/work/louis/sendfile_tls

Transport: Fix static file serving from SSL connections
parents 1c9d71ad 44e40478
/* utils.h
Louis Solofrizzo 2019-10-17
Utilities for pistache
*/
#pragma once
#ifdef PISTACHE_USE_SSL
#include <openssl/ssl.h>
/*!
* \brief sendfile(2) like utility for OpenSSL contexts
*
* \param[out] out The SSL context
* \param[in] in File descriptor to stream
* \param[out] offset See below.
* \param[in] count Number of bytes to write
*
* Unlike the system call, this function will bufferise data in user-space,
* thus making it blocking and memory hungry.
*
* If offset is not NULL, then it points to a variable holding the file offset
* from which SSL_sendfile() will start reading data from in. When
* SSL_sendfile() returns, this variable will be set to the offset of the byte
* following the last byte that was read.
*
* \note This function exists in OpenSSL3[1]. It uses KTLS features which are
* far more superior that this function. We'll need to do the switch when
* OpenSSL3 becomes the SSL mainline.
*
* \return The number of bytes written to the SSL context
*
* [1] https://www.openssl.org/docs/manmaster/man3/SSL_sendfile.html
*/
ssize_t SSL_sendfile(SSL *out, int in, off_t *offset, size_t count);
#endif /* PISTACHE_USE_SSL */
......@@ -12,6 +12,7 @@
#include <pistache/peer.h>
#include <pistache/tcp.h>
#include <pistache/os.h>
#include <pistache/utils.h>
namespace Pistache {
......@@ -257,7 +258,21 @@ Transport::asyncWriteImpl(Fd fd)
} else {
auto file = buffer.fd();
off_t offset = totalWritten;
bytesWritten = ::sendfile(fd, file, &offset, len);
#ifdef PISTACHE_USE_SSL
auto it = peers.find(fd);
if (it == std::end(peers))
throw std::runtime_error("No peer found for fd: " + std::to_string(fd));
if (it->second->ssl() != NULL) {
bytesWritten = SSL_sendfile((SSL *)it->second->ssl(), file, &offset, len);
} else {
#endif /* PISTACHE_USE_SSL */
bytesWritten = ::sendfile(fd, file, &offset, len);
#ifdef PISTACHE_USE_SSL
}
#endif /* PISTACHE_USE_SSL */
}
if (bytesWritten < 0) {
if (errno == EAGAIN || errno == EWOULDBLOCK) {
......
/* utils.cc
Louis Solofrizzo 2019-10-17
Utilities for pistache
*/
#include <pistache/peer.h>
#include <unistd.h>
ssize_t SSL_sendfile(SSL *out, int in, off_t *offset, size_t count)
{
unsigned char buffer[4096] = { 0 };
ssize_t ret;
ssize_t written;
size_t to_read;
if (in == -1)
return -1;
to_read = sizeof(buffer) > count ? count : sizeof(buffer);
if (offset != NULL)
ret = pread(in, buffer, to_read, *offset);
else
ret = read(in, buffer, to_read);
if (ret == -1)
return -1;
written = SSL_write(out, buffer, ret);
if (offset != NULL)
*offset += written;
return written;
}
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment