Permalink
Browse files

sconesite/SconesiteStream: Tidy, avoid duplication, move more into ha…

…ndler
  • Loading branch information...
sconemad committed Jun 7, 2017
1 parent 06b963a commit 8528fff5a8067292a28f75bae74e777698a46cc4
Showing with 53 additions and 66 deletions.
  1. +49 −64 sconesite/SconesiteStream.cpp
  2. +4 −2 sconesite/SconesiteStream.h
@@ -91,14 +91,21 @@ class ParamReaderStream : public scx::Stream {
SconesiteHandler::SconesiteHandler(SconesiteModule* module,
const scx::ScriptRef* args)
: m_module(module),
m_profile(0)
m_profile(0),
m_article(0)
{
const scx::ScriptString* profile_name =
scx::get_method_arg<scx::ScriptString>(args,0,"profile");
if (profile_name) {
m_profile = module->lookup_profile(profile_name->get_string());
}
}

//=========================================================================
SconesiteHandler::~SconesiteHandler()
{
delete m_article;
}

//=========================================================================
scx::Condition SconesiteHandler::handle_message(http::MessageStream* message)
@@ -123,10 +130,10 @@ scx::Condition SconesiteHandler::handle_message(http::MessageStream* message)

// Lookup the article and get remaining file path
std::string file;
Article::Ref* article = m_profile->lookup_article(pathinfo, file);
m_article = m_profile->lookup_article(pathinfo, file);

// Check article exists
if (!article) {
if (!m_article) {
log(message, "Request for '" + pathinfo + "' - NotFound (no article)");
resp.set_status(http::Status::NotFound);
return scx::Close;
@@ -135,7 +142,7 @@ scx::Condition SconesiteHandler::handle_message(http::MessageStream* message)
const scx::Uri& uri = req.get_uri();
if (file.empty()) {
// Article request, check if we need to redirect to correct the path
std::string href = article->object()->get_href_path();
std::string href = m_article->object()->get_href_path();
if (pathinfo != href) {
scx::Uri new_uri = uri;
new_uri.set_path(href);
@@ -147,42 +154,65 @@ scx::Condition SconesiteHandler::handle_message(http::MessageStream* message)

} else {
// File request, update the path in the request
scx::FilePath path = article->object()->get_root() + file;
scx::FilePath path = m_article->object()->get_root() + file;
req.set_path(path);
if (file.find("article.") == 0) {
// Don't allow any article source to be sent
log(message, "File request for '" + path.path() + "' - Forbidden (article source)");
log(message, "Request for '" + pathinfo + "' - Forbidden (article source)");
resp.set_status(http::Status::Forbidden);
return scx::Close;

} else if (!scx::FileStat(path).is_file()) {
log(message, "File request for '" + path.path() + "' - NotFound");
log(message, "Request for '" + pathinfo + "' - NotFound");
resp.set_status(http::Status::NotFound);
// Note that we don't return here, since we want to go ahead
// and process the article in order to display the 404.
// XXX does this make sense?

} else {
log(message, "File request for '" + path.path() + "'");
log(message, "Request for '" + pathinfo +"' - Using getfile");

// Pass on to the getfile handler
http::Handler* getfile = http::Handler::create("getfile",0);
if (!getfile) {
// getfile not available
resp.set_status(http::Status::InternalServerError);
return scx::Close;
}
scx::Condition c = getfile->handle_message(message);
delete getfile;
return c;
}
}

message->add_stream(new SconesiteStream(m_module.object(),
m_profile, message));
m_profile,
m_article->object(),
message));

return scx::Ok;
}

//=========================================================================
void SconesiteHandler::log(http::MessageStream* message, const std::string str)
{
scx::Log l("sconesite");
const http::Request& req = message->get_request();
scx::Log("sconesite").attach("id",req.get_id()).submit(str);
l.attach("id",req.get_id());
if (m_article) l.attach("article",m_article->object()->get_href_path());
l.submit(str);
}

//=========================================================================
SconesiteStream::SconesiteStream(SconesiteModule* module,
Profile* profile,
Article* article,
http::MessageStream* message)
: http::ResponseStream("sconesite"),
m_module(module),
m_profile(profile),
m_message(message),
m_article(0),
m_accept(false),
m_article(new Article::Ref(article)),
m_context(0)
{

@@ -209,9 +239,10 @@ std::string SconesiteStream::stream_status() const
//=========================================================================
void SconesiteStream::log(const std::string str)
{
// http::Request& req = const_cast<http::Request&>(m_message->get_request());
scx::Log l("sconesite-stream");
const http::Request& req = m_message->get_request();
scx::Log("sconesite").attach("id",req.get_id()).submit(str);
l.attach("id",req.get_id());
l.submit(str);
}

//=========================================================================
@@ -220,26 +251,6 @@ scx::Condition SconesiteStream::event(scx::Stream::Event e)
if (e == scx::Stream::Opening) {
http::Request& req = const_cast<http::Request&>(m_message->get_request());
http::Response& resp = m_message->get_response();
// const scx::Uri& uri = req.get_uri();
std::string pathinfo = req.get_path_info();

if (pathinfo.find("//") != std::string::npos ||
pathinfo.find("..") != std::string::npos) {
log("Request for '" + pathinfo + "' - Forbidden (path contains forbidden chars)");
resp.set_status(http::Status::Forbidden);
return scx::Close;
}

// Lookup the article and get remaining file path
m_article = m_profile->lookup_article(pathinfo,m_file);

// Check article exists
if (!m_article) {
log("Request for '" + pathinfo + "' - NotFound (no article)");
resp.set_status(http::Status::NotFound);
return scx::Close;
}

// Create context for rendering article
RenderMarkupContext* rmc = new RenderMarkupContext(m_profile,
*this,
@@ -248,15 +259,8 @@ scx::Condition SconesiteStream::event(scx::Stream::Event e)
resp);
m_context = new RenderMarkupContext::Ref(rmc);
rmc->set_article(m_article->object());

m_accept = true;
}

if (m_accept) {
return http::ResponseStream::event(e);
} else {
return scx::Ok;
}
return http::ResponseStream::event(e);
}

//=========================================================================
@@ -335,27 +339,7 @@ scx::Condition SconesiteStream::send_response()
http::Session* session = req.get_session();
std::string pathinfo = req.get_path_info();

if (resp.get_status().code() == http::Status::Ok && !m_file.empty()) {
// Request for a file

// Connect the getfile module and relinquish
http::Handler* getfile = http::Handler::create("getfile",0);
if (getfile) {
log("Article '" + m_article->object()->get_string() +
"' sending '" + pathinfo + "' with getfile");
scx::Condition c = getfile->handle_message(m_message);
delete getfile;
if (c == scx::Ok) return scx::End;
return c;
}
// Something went wrong
resp.set_status(http::Status::InternalServerError);
return scx::Close;

} else {
// Request for the article itself
log("Sending article '" + m_article->object()->get_string() + "'");
}
log("Sending article '" + m_article->object()->get_string() + "'");

// Find the template to use
Template* tpl = m_profile->lookup_template("start");
@@ -382,7 +366,8 @@ scx::Condition SconesiteStream::send_response()
resp.set_status(http::Status::InternalServerError);
}
} catch (...) {
DEBUG_LOG("EXCEPTION caught in SconesiteStream");
//XXX this happens too often to log!
//DEBUG_LOG("EXCEPTION caught in SconesiteStream");
}

// Unlock the session
@@ -34,6 +34,7 @@ class Profile;
class SconesiteHandler : public http::Handler {
public:
SconesiteHandler(SconesiteModule* module, const scx::ScriptRef* args);
virtual ~SconesiteHandler();

virtual scx::Condition handle_message(http::MessageStream* message);

@@ -43,6 +44,7 @@ class SconesiteHandler : public http::Handler {

scx::ScriptRefTo<SconesiteModule> m_module;
Profile* m_profile;
Article::Ref* m_article;
};


@@ -52,9 +54,10 @@ class SconesiteStream : public http::ResponseStream {

SconesiteStream(SconesiteModule* module,
Profile* profile,
Article* article,
http::MessageStream* message);

~SconesiteStream();
virtual ~SconesiteStream();

virtual std::string stream_status() const;

@@ -74,7 +77,6 @@ class SconesiteStream : public http::ResponseStream {
http::MessageStream* m_message;
Article::Ref* m_article;

bool m_accept;
RenderMarkupContext::Ref* m_context;
std::string m_file;

0 comments on commit 8528fff

Please sign in to comment.