From 8f5a0d64f2ec7a8de4234c2b2277d0f8c5b014ae Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Wed, 30 Dec 2015 14:29:59 +0100 Subject: [PATCH] spectrum2_manager server: Allow serving static content --- spectrum_manager/src/CMakeLists.txt | 5 + spectrum_manager/src/html/footer.html | 10 + spectrum_manager/src/html/form.css | 84 ++++ spectrum_manager/src/html/header.html | 32 ++ spectrum_manager/src/html/login/index.html | 71 ++++ spectrum_manager/src/html/logo.png | Bin 0 -> 11091 bytes spectrum_manager/src/html/style.css | 465 +++++++++++++++++++++ spectrum_manager/src/managerconfig.cpp | 1 + spectrum_manager/src/server.cpp | 247 ++++------- spectrum_manager/src/server.h | 4 +- 10 files changed, 744 insertions(+), 175 deletions(-) create mode 100644 spectrum_manager/src/html/footer.html create mode 100644 spectrum_manager/src/html/form.css create mode 100644 spectrum_manager/src/html/header.html create mode 100644 spectrum_manager/src/html/login/index.html create mode 100644 spectrum_manager/src/html/logo.png create mode 100644 spectrum_manager/src/html/style.css diff --git a/spectrum_manager/src/CMakeLists.txt b/spectrum_manager/src/CMakeLists.txt index 2ebdd2dd..22be5837 100644 --- a/spectrum_manager/src/CMakeLists.txt +++ b/spectrum_manager/src/CMakeLists.txt @@ -17,3 +17,8 @@ INSTALL(FILES spectrum_manager.cfg DESTINATION /etc/spectrum2 ) + +INSTALL(DIRECTORY + html + DESTINATION /var/lib/spectrum2_manager + ) diff --git a/spectrum_manager/src/html/footer.html b/spectrum_manager/src/html/footer.html new file mode 100644 index 00000000..2822dd86 --- /dev/null +++ b/spectrum_manager/src/html/footer.html @@ -0,0 +1,10 @@ + + + + + + diff --git a/spectrum_manager/src/html/form.css b/spectrum_manager/src/html/form.css new file mode 100644 index 00000000..d617f1f4 --- /dev/null +++ b/spectrum_manager/src/html/form.css @@ -0,0 +1,84 @@ +/* Basic Grey */ +.basic-grey { + margin-left:auto; + margin-right:auto; + max-width: 500px; + background: #F7F7F7; + padding: 25px 15px 25px 10px; + font: 12px Georgia, "Times New Roman", Times, serif; + color: #888; + text-shadow: 1px 1px 1px #FFF; + border:1px solid #E4E4E4; +} +.basic-grey h1 { + font-size: 25px; + padding: 0px 0px 10px 40px; + display: block; + border-bottom:1px solid #E4E4E4; + margin: -10px -15px 30px -10px;; + color: #888; +} +.basic-grey h1>span { + display: block; + font-size: 11px; +} +.basic-grey label { + display: block; + margin: 0px; +} +.basic-grey label>span { + float: left; + width: 20%; + text-align: right; + padding-right: 10px; + margin-top: 10px; + color: #888; +} +.basic-grey input[type="text"], .basic-grey input[type="email"], .basic-grey input[type="password"], .basic-grey textarea, .basic-grey select { + border: 1px solid #DADADA; + color: #888; + height: 30px; + margin-bottom: 16px; + margin-right: 6px; + margin-top: 2px; + outline: 0 none; + padding: 3px 3px 3px 5px; + width: 70%; + font-size: 12px; + line-height:15px; + box-shadow: inset 0px 1px 4px #ECECEC; + -moz-box-shadow: inset 0px 1px 4px #ECECEC; + -webkit-box-shadow: inset 0px 1px 4px #ECECEC; +} +.basic-grey textarea{ + padding: 5px 3px 3px 5px; +} +.basic-grey select { + background: #FFF url('down-arrow.png') no-repeat right; + background: #FFF url('down-arrow.png') no-repeat right); + appearance:none; + -webkit-appearance:none; + -moz-appearance: none; + text-indent: 0.01px; + text-overflow: ''; + width: 70%; + height: 35px; + line-height: 25px; +} +.basic-grey textarea{ + height:100px; +} +.basic-grey .button { + background: #E27575; + border: none; + padding: 10px 25px 10px 25px; + color: #FFF; + box-shadow: 1px 1px 5px #B6B6B6; + border-radius: 3px; + text-shadow: 1px 1px 1px #9E3F3F; + cursor: pointer; +} +.basic-grey .button:hover { + background: #CF7A7A +} + diff --git a/spectrum_manager/src/html/header.html b/spectrum_manager/src/html/header.html new file mode 100644 index 00000000..f4baa073 --- /dev/null +++ b/spectrum_manager/src/html/header.html @@ -0,0 +1,32 @@ + + + + + + + + + + + Spectrum 2 + + + + + +
+
+ + + + +
+
+ + +
+
diff --git a/spectrum_manager/src/html/login/index.html b/spectrum_manager/src/html/login/index.html new file mode 100644 index 00000000..c97ad5aa --- /dev/null +++ b/spectrum_manager/src/html/login/index.html @@ -0,0 +1,71 @@ + + + + + + + + + + + Spectrum 2 + + + + + +
+
+ + + + +
+
+ + +
+
+ + +
+

Login form + Use your username and password to login to Spectrum 2 Manager. +

+ + + +
+ +
+
+ + + + + + + + + + \ No newline at end of file diff --git a/spectrum_manager/src/html/logo.png b/spectrum_manager/src/html/logo.png new file mode 100644 index 0000000000000000000000000000000000000000..91a2d38defca30262f1fb5a2afed0328dc6312fa GIT binary patch literal 11091 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 E12JRW?f?J) literal 0 HcmV?d00001 diff --git a/spectrum_manager/src/html/style.css b/spectrum_manager/src/html/style.css new file mode 100644 index 00000000..5b66f658 --- /dev/null +++ b/spectrum_manager/src/html/style.css @@ -0,0 +1,465 @@ +/******************************************************************************* +Slate Theme for Github Pages +by Jason Costello, @jsncostello +*******************************************************************************/ + +@import url(pygment_trac.css); + +/******************************************************************************* +MeyerWeb Reset +*******************************************************************************/ + +html, body, div, span, applet, object, iframe, +h1, h2, h3, h4, h5, h6, p, blockquote, pre, +a, abbr, acronym, address, big, cite, code, +del, dfn, em, img, ins, kbd, q, s, samp, +small, strike, strong, sub, sup, tt, var, +b, u, i, center, +dl, dt, dd, ol, ul, li, +fieldset, form, label, legend, +table, caption, tbody, tfoot, thead, tr, th, td, +article, aside, canvas, details, embed, +figure, figcaption, footer, header, hgroup, +menu, nav, output, ruby, section, summary, +time, mark, audio, video { + margin: 0; + padding: 0; + border: 0; + font: inherit; + vertical-align: baseline; +} + +/* HTML5 display-role reset for older browsers */ +article, aside, details, figcaption, figure, +footer, header, hgroup, menu, nav, section { + display: block; +} + +ol, ul { + list-style: none; +} + +blockquote, q { +} + +table { + border-collapse: collapse; + border-spacing: 0; + width:100%; +} + +a:focus { + outline: none; +} + +/******************************************************************************* +Theme Styles +*******************************************************************************/ + +body { + box-sizing: border-box; + color:#373737; + background: #212121; + font-size: 16px; + font-family: 'Myriad Pro', Calibri, Helvetica, Arial, sans-serif; + line-height: 1.5; + -webkit-font-smoothing: antialiased; +} + +h1, h2, h3, h4, h5, h6 { + margin: 10px 0; + font-weight: 700; + color:#222222; + font-family: 'Lucida Grande', 'Calibri', Helvetica, Arial, sans-serif; + letter-spacing: -1px; +} + +h1 { + font-size: 36px; + font-weight: 700; +} + +h2 { + padding-bottom: 10px; + font-size: 32px; + background: url('../images/bg_hr.png') repeat-x bottom; +} + +h3 { + font-size: 24px; +} + +h4 { + font-size: 21px; +} + +h5 { + font-size: 18px; +} + +h6 { + font-size: 16px; +} + +p { + margin: 10px 0 15px 0; +} + +footer p { + color: #f2f2f2; +} + +a { + text-decoration: none; + color: #007edf; + text-shadow: none; + + transition: color 0.5s ease; + transition: text-shadow 0.5s ease; + -webkit-transition: color 0.5s ease; + -webkit-transition: text-shadow 0.5s ease; + -moz-transition: color 0.5s ease; + -moz-transition: text-shadow 0.5s ease; + -o-transition: color 0.5s ease; + -o-transition: text-shadow 0.5s ease; + -ms-transition: color 0.5s ease; + -ms-transition: text-shadow 0.5s ease; +} + +#main_content a:hover { + color: #0069ba; + text-shadow: #0090ff 0px 0px 2px; +} + +footer a:hover { + color: #43adff; + text-shadow: #0090ff 0px 0px 2px; +} + +#menu a:hover { + color: #212121; + text-shadow: #0090ff 0px 0px 2px; +} + +em { + font-style: italic; +} + +strong { + font-weight: bold; +} + +img { + position: relative; + margin: 0 auto; + max-width: 739px; + padding: 5px; + margin: 10px 0 10px 0; +/* border: 1px solid #ebebeb; + + box-shadow: 0 0 5px #ebebeb; + -webkit-box-shadow: 0 0 5px #ebebeb; + -moz-box-shadow: 0 0 5px #ebebeb; + -o-box-shadow: 0 0 5px #ebebeb; + -ms-box-shadow: 0 0 5px #ebebeb;*/ +} + +header img { + border: 0; + box-shadow: 0 0 0px #ebebeb; + -webkit-box-shadow: 0 0 0px #ebebeb; + -moz-box-shadow: 0 0 0px #ebebeb; + -o-box-shadow: 0 0 0px #ebebeb; + -ms-box-shadow: 0 0 0px #ebebeb; +} + +pre, code { + width: 100%; + color: #222; + background-color: #fff; + + font-family: Monaco, "Bitstream Vera Sans Mono", "Lucida Console", Terminal, monospace; + font-size: 14px; + + border-radius: 2px; + -moz-border-radius: 2px; + -webkit-border-radius: 2px; + + + +} + +pre { + width: 100%; + padding: 10px; + box-shadow: 0 0 10px rgba(0,0,0,.1); + overflow: auto; +} + +code { + padding: 3px; + margin: 0 3px; + box-shadow: 0 0 10px rgba(0,0,0,.1); +} + +pre code { + display: block; + box-shadow: none; +} + +blockquote { + color: #666; + margin-bottom: 20px; + padding: 0 0 0 20px; + border-left: 3px solid #bbb; +} + +ul, ol, dl { + margin-bottom: 15px +} + +ul li { + list-style: inside; + padding-left: 20px; +} + +ol li { + list-style: decimal inside; + padding-left: 20px; +} + +dl dt { + font-weight: bold; +} + +dl dd { + padding-left: 20px; + font-style: italic; +} + +dl p { + padding-left: 20px; + font-style: italic; +} + +hr { + height: 1px; + margin-bottom: 5px; + border: none; + background: url('../images/bg_hr.png') repeat-x center; +} + +table { + border: 1px solid #373737; + margin-bottom: 10px; + text-align: left; + } + +th { + font-family: 'Lucida Grande', 'Helvetica Neue', Helvetica, Arial, sans-serif; + padding: 5px; + background: #373737; + color: #fff; + } + +td { + padding: 3px; + border: 1px solid #373737; + } + +form { + background: #f2f2f2; + padding: 20px; +} + +img { +/* width: 100%; */ + max-width: 100%; + display:block ; margin:0 auto ; +} + +/******************************************************************************* +Full-Width Styles +*******************************************************************************/ + +.outer { + width: 100%; +} + +.inner { + position: relative; + max-width: 880px; + padding: 20px 10px; + margin: 0 auto; +} + +#forkme_banner { + display: block; + position: absolute; + top:0; + right: 10px; + z-index: 10; + padding: 10px 50px 10px 10px; + color: #fff; + background: url('../images/blacktocat.png') #0090ff no-repeat 95% 50%; + font-weight: 700; + box-shadow: 0 0 10px rgba(0,0,0,.5); + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; +} + +#header_wrap { + background: #212121; + background: -moz-linear-gradient(top, #373737, #212121); + background: -webkit-linear-gradient(top, #373737, #212121); + background: -ms-linear-gradient(top, #373737, #212121); + background: -o-linear-gradient(top, #373737, #212121); + background: linear-gradient(top, #373737, #212121); +} + +#header_wrap .inner { + padding: 50px 10px 30px 10px; +} + +#project_title { + margin: 0; + color: #fff; + font-size: 42px; + font-weight: 700; + text-shadow: #111 0px 0px 10px; +} + +#project_tagline { + color: #fff; + font-size: 24px; + font-weight: 300; + background: none; + text-shadow: #111 0px 0px 10px; +} + +#downloads { + position: absolute; + width: 210px; + z-index: 10; + bottom: -40px; + right: 0; + height: 70px; + background: url('../images/icon_download.png') no-repeat 0% 90%; +} + +#menu { + position: absolute; + width: 100%; + z-index: 10; + bottom: -20px; + left: 0; + height: 35px; +} + +.menuitem { + margin:0; + margin-right:7px; + color:white; + padding:10px; + height: 35px; + background: #0090FF; +} + +.zip_download_link { + display: block; + float: right; + width: 90px; + height:70px; + text-indent: -5000px; + overflow: hidden; + background: url(../images/sprite_download.png) no-repeat bottom left; +} + +.tar_download_link { + display: block; + float: right; + width: 90px; + height:70px; + text-indent: -5000px; + overflow: hidden; + background: url(../images/sprite_download.png) no-repeat bottom right; + margin-left: 10px; +} + +.zip_download_link:hover { + background: url(../images/sprite_download.png) no-repeat top left; +} + +.tar_download_link:hover { + background: url(../images/sprite_download.png) no-repeat top right; +} + +#main_content_wrap { + background: #f2f2f2; + border-top: 1px solid #111; + border-bottom: 1px solid #111; +} + +#main_content { + padding-top: 40px; +} + +#footer_wrap { + background: #212121; +} + + + +/******************************************************************************* +Small Device Styles +*******************************************************************************/ + +@media screen and (max-width: 480px) { + body { + font-size:14px; + } + + #downloads { + display: none; + } + + .inner { + min-width: 320px; + max-width: 480px; + } + + #project_title { + font-size: 32px; + } + + h1 { + font-size: 28px; + } + + h2 { + font-size: 24px; + } + + h3 { + font-size: 21px; + } + + h4 { + font-size: 18px; + } + + h5 { + font-size: 14px; + } + + h6 { + font-size: 12px; + } + + code, pre { + min-width: 320px; + max-width: 480px; + font-size: 11px; + } + +} diff --git a/spectrum_manager/src/managerconfig.cpp b/spectrum_manager/src/managerconfig.cpp index b3c159c4..0087df9c 100644 --- a/spectrum_manager/src/managerconfig.cpp +++ b/spectrum_manager/src/managerconfig.cpp @@ -33,6 +33,7 @@ bool ManagerConfig::load(const std::string &configfile, boost::program_options:: ("service.admin_password", value()->default_value(""), "Administrator password.") ("service.port", value()->default_value(8081), "Web interface port.") ("service.config_directory", value()->default_value("/etc/spectrum2/transports/"), "Directory with spectrum2 configuration files. One .cfg file per one instance") + ("service.data_dir", value()->default_value("/var/lib/spectrum2_manager"), "Directory to store Spectrum 2 manager data") ("servers.server", value >()->multitoken(), "Server.") ; diff --git a/spectrum_manager/src/server.cpp b/spectrum_manager/src/server.cpp index 39b7c1e2..c279c240 100644 --- a/spectrum_manager/src/server.cpp +++ b/spectrum_manager/src/server.cpp @@ -8,123 +8,18 @@ #include #include #include +#include +#include +#include #define SESSION_TTL 120 -static std::string get_header() { -return "\ - \ - \ - \ - Spectrum 2 web interface\ - \ - \ -

Spectrum 2 web interface

"; -} +static struct mg_serve_http_opts s_http_server_opts; static void get_qsvar(const struct http_message *hm, const char *name, char *dst, size_t dst_len) { - mg_get_http_var(&hm->query_string, name, dst, dst_len); + mg_get_http_var(&hm->body, name, dst, dst_len); } static void my_strlcpy(char *dst, const char *src, size_t len) { @@ -153,6 +48,26 @@ Server::Server(ManagerConfig *config) { mg_mgr_init(&m_mgr, this); m_nc = mg_bind(&m_mgr, std::string(":" + boost::lexical_cast(CONFIG_INT(m_config, "service.port"))).c_str(), &_event_handler); mg_set_protocol_http_websocket(m_nc); + + s_http_server_opts.document_root = CONFIG_STRING(m_config, "service.data_dir").c_str(); + + std::ifstream header(std::string(CONFIG_STRING(m_config, "service.data_dir") + "/header.html").c_str(), std::ios::in); + if (header) { + header.seekg(0, std::ios::end); + m_header.resize(header.tellg()); + header.seekg(0, std::ios::beg); + header.read(&m_header[0], m_header.size()); + header.close(); + } + + std::ifstream footer(std::string(CONFIG_STRING(m_config, "service.data_dir") + "/footer.html").c_str(), std::ios::in); + if (footer) { + footer.seekg(0, std::ios::end); + m_footer.resize(footer.tellg()); + footer.seekg(0, std::ios::beg); + footer.read(&m_footer[0], m_footer.size()); + footer.close(); + } } Server::~Server() { @@ -179,6 +94,7 @@ Server::session *Server::new_session(const char *user) { snprintf(session->random, sizeof(session->random), "%d", rand()); generate_session_id(session->session_id, session->random, session->user); session->expire = time(0) + SESSION_TTL; + session->admin = std::string(user) == m_user; sessions[session->session_id] = session; return session; @@ -243,11 +159,14 @@ bool Server::is_authorized(const struct mg_connection *conn, struct http_message // Always authorize accesses to login page and to authorize URI if (!mg_vcmp(&hm->uri, "/login") || + !mg_vcmp(&hm->uri, "/login/") || + !mg_vcmp(&hm->uri, "/form.css") || + !mg_vcmp(&hm->uri, "/style.css") || + !mg_vcmp(&hm->uri, "/logo.png") || !mg_vcmp(&hm->uri, "/authorize")) { return true; } -// pthread_rwlock_rdlock(&rwlock); if ((session = get_session(hm)) != NULL) { generate_session_id(valid_id, session->random, session->user); if (strcmp(valid_id, session->session_id) == 0) { @@ -255,7 +174,6 @@ bool Server::is_authorized(const struct mg_connection *conn, struct http_message authorized = true; } } -// pthread_rwlock_unlock(&rwlock); return authorized; } @@ -272,37 +190,12 @@ void Server::print_html(struct mg_connection *conn, struct http_message *hm, con "Content-Type: text/html\r\n" "Content-Length: %d\r\n" // Always set Content-Length "\r\n" - "%s", - (int) html.size(), html.c_str()); -} - -void Server::serve_login(struct mg_connection *conn, struct http_message *hm) { - std::string html= "\ - \ - \ - \ - Spectrum 2 web interface\ - \ - \ - \ -
\ -

Spectrum 2 web interface login

\ -
\ -
\ - Username:
\ - Password:
\ - \ -
\ -
\ - \ -"; - - print_html(conn, hm, html); + "%s%s%s", + (int) html.size() + m_header.size() + m_footer.size(), m_header.c_str(), html.c_str(), m_footer.c_str()); } void Server::serve_onlineusers(struct mg_connection *conn, struct http_message *hm) { - std::string html = get_header(); + std::string html; char jid[255]; get_qsvar(hm, "jid", jid, sizeof(jid)); @@ -331,7 +224,7 @@ void Server::serve_onlineusers(struct mg_connection *conn, struct http_message * } void Server::serve_cmd(struct mg_connection *conn, struct http_message *hm) { - std::string html = get_header(); + std::string html; char jid[255]; get_qsvar(hm, "jid", jid, sizeof(jid)); char cmd[4096]; @@ -358,7 +251,7 @@ void Server::serve_cmd(struct mg_connection *conn, struct http_message *hm) { void Server::serve_start(struct mg_connection *conn, struct http_message *hm) { - std::string html= get_header() ; + std::string html; char jid[255]; get_qsvar(hm, "jid", jid, sizeof(jid)); @@ -369,7 +262,7 @@ void Server::serve_start(struct mg_connection *conn, struct http_message *hm) { } void Server::serve_stop(struct mg_connection *conn, struct http_message *hm) { - std::string html= get_header(); + std::string html; char jid[255]; get_qsvar(hm, "jid", jid, sizeof(jid)); @@ -378,40 +271,45 @@ void Server::serve_stop(struct mg_connection *conn, struct http_message *hm) { html += ""; print_html(conn, hm, html); } - void Server::serve_root(struct mg_connection *conn, struct http_message *hm) { std::vector list = show_list(m_config, false); - std::string html= get_header() + "

List of instances

"; + std::string html = "

List of instances

"; - BOOST_FOREACH(std::string &instance, list) { - html += ""; - html += ""; - Swift::SimpleEventLoop eventLoop; - Swift::BoostNetworkFactories networkFactories(&eventLoop); - - ask_local_server(m_config, networkFactories, instance, "status"); - eventLoop.runUntilEvents(); - while(get_response().empty()) { - eventLoop.runUntilEvents(); - } - html += ""; - if (get_response().find("Running") == 0) { - html += ""; - html += ""; - } - else { - html += ""; - html += ""; - } - - html += ""; + if (list.empty()) { + html += "

There are no Spectrum 2 instances yet. You can create new instance by adding configuration files into

/etc/spectrum2/transports
directory. You can then maintain the Spectrum 2 instance here.

"; } + else { + html += "
JIDStatusCommandRun command
" + instance + "" + get_response() + "Stop
"; - html += ""; - html += ""; - html += ""; - html += "
Start
"; + BOOST_FOREACH(std::string &instance, list) { + html += ""; + html += ""; + Swift::SimpleEventLoop eventLoop; + Swift::BoostNetworkFactories networkFactories(&eventLoop); - html += "
JIDStatusCommandRun command
" + instance + "
"; + ask_local_server(m_config, networkFactories, instance, "status"); + eventLoop.runUntilEvents(); + while(get_response().empty()) { + eventLoop.runUntilEvents(); + } + html += "" + get_response() + ""; + if (get_response().find("Running") == 0) { + html += "Stop"; + html += "
"; + html += ""; + html += ""; + html += ""; + html += "
"; + } + else { + html += "Start"; + html += ""; + } + + html += ""; + } + + html += ""; + } print_html(conn, hm, html); } @@ -421,12 +319,11 @@ void Server::event_handler(struct mg_connection *conn, int ev, void *p) { if (ev != MG_EV_HTTP_REQUEST) { return; } + if (!is_authorized(conn, hm)) { redirect_to(conn, hm, "/login"); } else if (mg_vcmp(&hm->uri, "/authorize") == 0) { authorize(conn, hm); - } else if (mg_vcmp(&hm->uri, "/login") == 0) { - serve_login(conn, hm); } else if (mg_vcmp(&hm->uri, "/") == 0) { serve_root(conn, hm); } else if (mg_vcmp(&hm->uri, "/onlineusers") == 0) { @@ -437,6 +334,8 @@ void Server::event_handler(struct mg_connection *conn, int ev, void *p) { serve_start(conn, hm); } else if (mg_vcmp(&hm->uri, "/stop") == 0) { serve_stop(conn, hm); + } else { + mg_serve_http(conn, hm, s_http_server_opts); } conn->flags |= MG_F_SEND_AND_CLOSE; diff --git a/spectrum_manager/src/server.h b/spectrum_manager/src/server.h index ecd52fa5..c9d31726 100644 --- a/spectrum_manager/src/server.h +++ b/spectrum_manager/src/server.h @@ -38,6 +38,7 @@ class Server { char random[20]; // Random data used for extra user validation char user[255]; // Authenticated user time_t expire; // Expiration timestamp, UTC + bool admin; }; /// Constructor. @@ -51,7 +52,6 @@ class Server { void event_handler(struct mg_connection *nc, int ev, void *p); private: - void serve_login(struct mg_connection *conn, struct http_message *hm); void serve_root(struct mg_connection *conn, struct http_message *hm); void serve_start(struct mg_connection *conn, struct http_message *hm); void serve_stop(struct mg_connection *conn, struct http_message *hm); @@ -78,4 +78,6 @@ class Server { std::string m_user; std::string m_password; ManagerConfig *m_config; + std::string m_header; + std::string m_footer; };