#include "common.hh" #include "document.hh" #include "hash_method.hh" #include "htmlutil.hh" #include "tag.hh" #include namespace { class DocumentImpl : public Document { public: explicit DocumentImpl(std::string title) : html_(Tag::create("html")), head_(html_->add_tag("head")), title_(head_->add_tag("title", std::move(title))), body_(html_->add_tag("body")) { } void add_style(std::string rel_path) override { head_->add_tag("link") ->attr("rel", "stylesheet") ->attr("href", std::move(rel_path)); } void add_script(std::string src_path) override { head_->add_tag("script") ->attr("type", "text/javascript") ->attr("src", std::move(src_path)); } void add_script(std::unique_ptr script) override { if (!script->has_attr("type")) script->attr("type", "text/javascript"); head_->add(std::move(script)); } Tag* body() override { return body_; } std::unique_ptr build(Transport* transport) override { std::string data; html_->render(&data); auto sha256 = HashMethod::sha256(); sha256->update(data.data(), data.size()); auto etag = "\"" + sha256->finish() + "\""; auto resp = transport->create_ok_data(std::move(data)); resp->add_header("Content-Type", "text/html; charset=utf-8"); resp->add_header("ETag", etag); return resp; } private: std::unique_ptr html_; Tag* head_; Tag* title_; Tag* body_; }; } // namespace std::unique_ptr Document::create(std::string title) { return std::make_unique(std::move(title)); }