Web interface: support service.base_location=/something/ to override default '/' root location used by the web interface

This commit is contained in:
Jan Kaluza 2016-01-20 15:02:41 +01:00
parent 1c4f01269f
commit af6c160261
8 changed files with 43 additions and 14 deletions

View file

@ -8,3 +8,4 @@
</footer>
</div>
</body></html>
<!--#call replace_base_url -->

View file

@ -1,4 +1,4 @@
<!--#include virtual="/header.html" -->
<!--#include virtual="/header.shtml" -->
<script type="text/javascript">
$(function() {
@ -6,4 +6,4 @@ $(function() {
});
</script>
<!--#include virtual="/footer.html" -->
<!--#include virtual="/footer.shtml" -->

View file

@ -1,4 +1,4 @@
<!--#include virtual="/header.html" -->
<!--#include virtual="/header.shtml" -->
<h2>Register Spectrum 2 instance</h2>
<form action="/api/v1/instances/register" class="basic-grey" method="POST">
@ -29,4 +29,4 @@ $(function() {
});
</script>
<!--#include virtual="/footer.html" -->
<!--#include virtual="/footer.shtml" -->

View file

@ -1,5 +1,5 @@
function show_instances() {
$.get("/api/v1/instances", function(data) {
$.get($.cookie("base_location") + "api/v1/instances", function(data) {
$("#main_content").html("<h2>List of Spectrum 2 instances</h2><table id='main_result'><tr><th>Name<th>Status</th><th>Actions</th></tr>");
var admin = $.cookie("admin") == "1";
@ -26,7 +26,7 @@ function show_instances() {
row += '<td>' + instance.status + '</td>'
if (command == 'register') {
row += '<td><a class="button_command" href="/instances/register.shtml?id=' + instance.id + '">' + command + '</a>' + '</td></tr>';
row += '<td><a class="button_command" href="' + $.cookie("base_location") + 'instances/register.shtml?id=' + instance.id + '">' + command + '</a>' + '</td></tr>';
$("#main_result > tbody:last-child").append(row);
}
else if (command == "") {
@ -34,7 +34,7 @@ function show_instances() {
$("#main_result > tbody:last-child").append(row);
}
else {
row += '<td><a class="button_command" href="/api/v1/instances/' + command + '/' + instance.id + '">' + command + '</a>' + '</td></tr>';
row += '<td><a class="button_command" href="' + $.cookie("base_location") + 'api/v1/instances/' + command + '/' + instance.id + '">' + command + '</a>' + '</td></tr>';
$("#main_result > tbody:last-child").append(row);
$(".button_command").click(function(e) {
e.preventDefault();
@ -68,7 +68,7 @@ function fill_instances_register_form() {
var query = getQueryParams(document.location.search);
$("#instance").attr("value", query.id);
$.get("/api/v1/instances/register_form/" + query.id, function(data) {
$.get($.cookie("base_location") + "api/v1/instances/register_form/" + query.id, function(data) {
$("#jid_desc").html(data.username_label + ":");
$("#uin_desc").html(data.legacy_username_label + ":");
$("#password_desc").html(data.password_label + ":");

View file

@ -69,4 +69,5 @@
</body></html>
</body></html>
<!--#call replace_base_url -->

View file

@ -35,6 +35,7 @@ bool ManagerConfig::load(const std::string &configfile, boost::program_options::
("service.cert", value<std::string>()->default_value(""), "Web interface certificate in PEM format when TLS should be used.")
("service.config_directory", value<std::string>()->default_value("/etc/spectrum2/transports/"), "Directory with spectrum2 configuration files. One .cfg file per one instance")
("service.data_dir", value<std::string>()->default_value("/var/lib/spectrum2_manager/html"), "Directory to store Spectrum 2 manager data")
("service.base_location", value<std::string>()->default_value("/"), "Base location of the web interface")
("servers.server", value<std::vector<std::string> >()->multitoken(), "Server.")
("database.type", value<std::string>()->default_value("none"), "Database type.")
("database.database", value<std::string>()->default_value("/var/lib/spectrum2/$jid/database.sql"), "Database used to store data")

View file

@ -208,9 +208,10 @@ void Server::authorize(struct mg_connection *conn, struct http_message *hm) {
"Set-Cookie: session=%s; max-age=3600; http-only\r\n" // Session ID
"Set-Cookie: user=%s\r\n" // Set user, needed by Javascript code
"Set-Cookie: admin=%s\r\n" // Set user, needed by Javascript code
"Set-Cookie: base_location=%s\r\n" // Set user, needed by Javascript code
"Set-Cookie: original_url=/; max-age=0\r\n" // Delete original_url
"Location: %s/instances\r\n\r\n",
session->session_id, session->user, session->admin ? "1" : "0", host.c_str());
"Location: %s%sinstances\r\n\r\n",
session->session_id, session->user, session->admin ? "1" : "0", CONFIG_STRING(m_config, "service.base_location").c_str(), host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str());
} else {
// Authentication failure, redirect to login.
redirect_to(conn, hm, "/login");
@ -258,9 +259,11 @@ void Server::redirect_to(struct mg_connection *conn, struct http_message *hm, co
host += std::string(host_hdr->p, host_hdr->len);
}
where = where + 1;
mg_printf(conn, "HTTP/1.1 302 Found\r\n"
"Set-Cookie: original_url=/\r\n"
"Location: %s%s\r\n\r\n", host.c_str(), where);
"Location: %s%s%s\r\n\r\n", host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str(), where);
}
void Server::print_html(struct mg_connection *conn, struct http_message *hm, const std::string &html) {
@ -373,8 +376,8 @@ void Server::serve_logout(struct mg_connection *conn, struct http_message *hm) {
mg_printf(conn, "HTTP/1.1 302 Found\r\n"
"Set-Cookie: session=%s; max-age=0\r\n"
"Set-Cookie: admin=%s; max-age=0\r\n"
"Location: %s/\r\n\r\n",
session->session_id, session->admin ? "1" : "0", host.c_str());
"Location: %s%s\r\n\r\n",
session->session_id, session->admin ? "1" : "0", host.c_str(), CONFIG_STRING(m_config, "service.base_location").c_str());
sessions.erase(session->session_id);
delete session;
@ -727,10 +730,24 @@ void Server::serve_oauth2(struct mg_connection *conn, struct http_message *hm) {
void Server::event_handler(struct mg_connection *conn, int ev, void *p) {
struct http_message *hm = (struct http_message *) p;
if (ev == MG_EV_SSI_CALL) {
mbuf_resize(&conn->send_mbuf, conn->send_mbuf.size * 2);
std::string resp(conn->send_mbuf.buf, conn->send_mbuf.len);
boost::replace_all(resp, "href=\"/", std::string("href=\"") + CONFIG_STRING(m_config, "service.base_location"));
boost::replace_all(resp, "src=\"/", std::string("src=\"") + CONFIG_STRING(m_config, "service.base_location"));
boost::replace_all(resp, "action=\"/", std::string("action=\"") + CONFIG_STRING(m_config, "service.base_location"));
strcpy(conn->send_mbuf.buf, resp.c_str());
mbuf_trim(&conn->send_mbuf);
return;
}
if (ev != MG_EV_HTTP_REQUEST) {
return;
}
hm->uri.p += CONFIG_STRING(m_config, "service.base_location").size() - 1;
hm->uri.len -= CONFIG_STRING(m_config, "service.base_location").size() - 1;
if (!is_authorized(conn, hm)) {
redirect_to(conn, hm, "/login");
} else if (mg_vcmp(&hm->uri, "/authorize") == 0) {
@ -764,6 +781,15 @@ void Server::event_handler(struct mg_connection *conn, int ev, void *p) {
} else if (has_prefix(&hm->uri, "/api/v1/")) {
m_apiServer->handleRequest(this, get_session(hm), conn, hm);
} else {
if (hm->uri.p[hm->uri.len - 1] != '/') {
std::string url(hm->uri.p, hm->uri.len);
if (url.find(".") == std::string::npos) {
url += "/";
redirect_to(conn, hm, url.c_str());
conn->flags |= MG_F_SEND_AND_CLOSE;
return;
}
}
mg_serve_http(conn, hm, s_http_server_opts);
}