Move http serving into socket impl.

Avoid caching headers with parameter, and add Date: parameter.
This commit is contained in:
Michael Meeks 2017-03-15 18:21:59 +00:00
parent d19b6eb351
commit f392d9e6f0
3 changed files with 62 additions and 48 deletions

View file

@ -12,6 +12,10 @@
#include <stdio.h>
#include <ctype.h>
#include <Poco/DateTime.h>
#include <Poco/DateTimeFormat.h>
#include <Poco/DateTimeFormatter.h>
#include "SigUtil.hpp"
#include "Socket.hpp"
#include "ServerSocket.hpp"
@ -147,4 +151,57 @@ void SocketPoll::dumpState(std::ostream& os)
i->dumpState(os);
}
namespace HttpHelper
{
void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path,
Poco::Net::HTTPResponse& response, bool noCache)
{
struct stat st;
if (stat(path.c_str(), &st) != 0)
{
LOG_WRN("#" << socket->getFD() << ": Failed to stat [" << path << "]. File will not be sent.");
throw Poco::FileNotFoundException("Failed to stat [" + path + "]. File will not be sent.");
return;
}
int bufferSize = std::min(st.st_size, (off_t)Socket::MaximumSendBufferSize);
if (st.st_size >= socket->getSendBufferSize())
{
socket->setSocketBufferSize(bufferSize);
bufferSize = socket->getSendBufferSize();
}
response.setContentLength(st.st_size);
response.set("User-Agent", HTTP_AGENT_STRING);
response.set("Date", Poco::DateTimeFormatter::format(Poco::Timestamp(), Poco::DateTimeFormat::HTTP_FORMAT));
if (!noCache)
{
// 60 * 60 * 24 * 128 (days) = 11059200
response.set("Cache-Control", "max-age=11059200");
response.set("ETag", "\"" LOOLWSD_VERSION_HASH "\"");
}
std::ostringstream oss;
response.write(oss);
const std::string header = oss.str();
LOG_TRC("#" << socket->getFD() << ": Sending file [" << path << "]: " << header);
socket->send(header);
std::ifstream file(path, std::ios::binary);
bool flush = true;
do
{
char buf[bufferSize];
file.read(buf, sizeof(buf));
const int size = file.gcount();
if (size > 0)
socket->send(buf, size, flush);
else
break;
flush = false;
}
while (file);
}
}
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */

View file

@ -820,58 +820,15 @@ protected:
namespace HttpHelper
{
inline void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path,
Poco::Net::HTTPResponse& response)
{
struct stat st;
if (stat(path.c_str(), &st) != 0)
{
LOG_WRN("#" << socket->getFD() << ": Failed to stat [" << path << "]. File will not be sent.");
throw Poco::FileNotFoundException("Failed to stat [" + path + "]. File will not be sent.");
return;
}
int bufferSize = std::min(st.st_size, (off_t)Socket::MaximumSendBufferSize);
if (st.st_size >= socket->getSendBufferSize())
{
socket->setSocketBufferSize(bufferSize);
bufferSize = socket->getSendBufferSize();
}
response.setContentLength(st.st_size);
response.set("User-Agent", HTTP_AGENT_STRING);
// 60 * 60 * 24 * 128 (days) = 11059200
response.set("Cache-Control", "max-age=11059200");
response.set("ETag", "\"" LOOLWSD_VERSION_HASH "\"");
std::ostringstream oss;
response.write(oss);
const std::string header = oss.str();
LOG_TRC("#" << socket->getFD() << ": Sending file [" << path << "]: " << header);
socket->send(header);
std::ifstream file(path, std::ios::binary);
bool flush = true;
do
{
char buf[bufferSize];
file.read(buf, sizeof(buf));
const int size = file.gcount();
if (size > 0)
socket->send(buf, size, flush);
else
break;
flush = false;
}
while (file);
}
void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path,
Poco::Net::HTTPResponse& response, bool noCache = false);
inline void sendFile(const std::shared_ptr<StreamSocket>& socket, const std::string& path,
const std::string& mediaType)
const std::string& mediaType, bool noCache = false)
{
Poco::Net::HTTPResponse response;
response.setContentType(mediaType);
sendFile(socket, path, response);
sendFile(socket, path, response, noCache);
}
};

View file

@ -197,7 +197,7 @@ void FileServerRequestHandler::handleRequest(const HTTPRequest& request, Poco::M
}
response.setContentType(mimeType);
HttpHelper::sendFile(socket, filepath, response);
HttpHelper::sendFile(socket, filepath, response, noCache);
}
}
catch (const Poco::Net::NotAuthenticatedException& exc)