mirror of
https://github.com/octoleo/plantuml-server.git
synced 2024-12-22 08:48:54 +00:00
Refactoring relative paths PR#209.
- use html `base` tag containing the context path once instead inside every single URL/link. - update and enhance `nginx-contextpath` example - export javascript code into separated file - Add TODO note to javascript clipboard check (from PR#250) since Firefox and Safari do not support the current implementation
This commit is contained in:
parent
1245b15e01
commit
638724925e
@ -41,10 +41,6 @@ YEAH! You are now using PlantUML behind a simple Nginx reverse proxy.
|
|||||||
|
|
||||||
# PlantUML
|
# PlantUML
|
||||||
location /plantuml/ {
|
location /plantuml/ {
|
||||||
proxy_set_header HOST $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
proxy_pass http://plantuml-server:8080/plantuml/;
|
proxy_pass http://plantuml-server:8080/plantuml/;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -52,12 +48,31 @@ location /plantuml/ {
|
|||||||
```
|
```
|
||||||
|
|
||||||
- `location /plantuml/` to reverse only the context path `/plantuml`
|
- `location /plantuml/` to reverse only the context path `/plantuml`
|
||||||
- `proxy_set_header HOST $host` and `proxy_set_header X-Forwarded-Host $host` to replaces local plantuml server ip with FQDN
|
|
||||||
- `proxy_set_header X-Forwarded-Proto $scheme` to use reverse proxy protocol schema instead of communication schema between reverse proxy and plantuml server
|
|
||||||
- `proxy_pass http://plantuml-server:8080/plantuml/` to set reverse proxy path to plantuml server.
|
- `proxy_pass http://plantuml-server:8080/plantuml/` to set reverse proxy path to plantuml server.
|
||||||
Use the docker container name `plantuml-server` instead of ip addresses.
|
Use the docker container name `plantuml-server` instead of ip addresses.
|
||||||
Also, use the same context path (`BASE_URL`) as PlantUML, which is configurable as an environment variable in the docker-compose file.
|
Also, use the same context path (`BASE_URL`) as PlantUML, which is configurable as an environment variable in the docker-compose file.
|
||||||
|
|
||||||
|
NOTE: `BASE_URL`, `location` and therefore the `proxy_pass` should have the some context path!
|
||||||
|
If that is not possible it may be possible to solve the problem by using NGINX `sub_filter`:
|
||||||
|
```nginx
|
||||||
|
# PlantUML
|
||||||
|
location /plantuml/ {
|
||||||
|
sub_filter '<base href="/" />' '<base href="/plantuml/" />';
|
||||||
|
sub_filter_types text/html;
|
||||||
|
|
||||||
|
proxy_pass http://plantuml-server:8080/;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
NOTE: Since [PR#256](https://github.com/plantuml/plantuml-server/pull/256) it is possible to use deep base URLs.
|
||||||
|
So with e.g. `BASE_URL=foo/bar` the following is possible:
|
||||||
|
```nginx
|
||||||
|
# PlantUML
|
||||||
|
location /foo/bar/ {
|
||||||
|
proxy_pass http://plantuml-server:8080/foo/bar/;
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
|
||||||
## Nginx and PlantUML server
|
## Nginx and PlantUML server
|
||||||
|
|
||||||
|
@ -18,10 +18,6 @@ http {
|
|||||||
|
|
||||||
# PlantUML
|
# PlantUML
|
||||||
location /plantuml/ {
|
location /plantuml/ {
|
||||||
proxy_set_header HOST $host;
|
|
||||||
proxy_set_header X-Forwarded-Host $host;
|
|
||||||
proxy_set_header X-Forwarded-Proto $scheme;
|
|
||||||
|
|
||||||
proxy_pass http://plantuml-server:8080/plantuml/;
|
proxy_pass http://plantuml-server:8080/plantuml/;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -254,17 +254,14 @@ public class PlantUmlServlet extends HttpServlet {
|
|||||||
// properties
|
// properties
|
||||||
request.setAttribute("showSocialButtons", Configuration.get("SHOW_SOCIAL_BUTTONS"));
|
request.setAttribute("showSocialButtons", Configuration.get("SHOW_SOCIAL_BUTTONS"));
|
||||||
request.setAttribute("showGithubRibbon", Configuration.get("SHOW_GITHUB_RIBBON"));
|
request.setAttribute("showGithubRibbon", Configuration.get("SHOW_GITHUB_RIBBON"));
|
||||||
// URL base
|
|
||||||
final String contextpath = request.getContextPath();
|
|
||||||
request.setAttribute("contextpath", contextpath);
|
|
||||||
// image URLs
|
// image URLs
|
||||||
final boolean hasImg = !text.isEmpty();
|
final boolean hasImg = !text.isEmpty();
|
||||||
request.setAttribute("hasImg", hasImg);
|
request.setAttribute("hasImg", hasImg);
|
||||||
request.setAttribute("imgurl", contextpath + "/png/" + index + encoded);
|
request.setAttribute("imgurl", "png/" + index + encoded);
|
||||||
request.setAttribute("svgurl", contextpath + "/svg/" + index + encoded);
|
request.setAttribute("svgurl", "svg/" + index + encoded);
|
||||||
request.setAttribute("pdfurl", contextpath + "/pdf/" + index + encoded);
|
request.setAttribute("pdfurl", "pdf/" + index + encoded);
|
||||||
request.setAttribute("txturl", contextpath + "/txt/" + index + encoded);
|
request.setAttribute("txturl", "txt/" + index + encoded);
|
||||||
request.setAttribute("mapurl", contextpath + "/map/" + index + encoded);
|
request.setAttribute("mapurl", "map/" + index + encoded);
|
||||||
// map for diagram source if necessary
|
// map for diagram source if necessary
|
||||||
final boolean hasMap = PlantumlUtils.hasCMapData(text);
|
final boolean hasMap = PlantumlUtils.hasCMapData(text);
|
||||||
request.setAttribute("hasMap", hasMap);
|
request.setAttribute("hasMap", hasMap);
|
||||||
@ -312,14 +309,13 @@ public class PlantUmlServlet extends HttpServlet {
|
|||||||
String encoded,
|
String encoded,
|
||||||
Integer index
|
Integer index
|
||||||
) throws IOException {
|
) throws IOException {
|
||||||
final String result;
|
final String path;
|
||||||
if (index == null || index < 0) {
|
if (index == null || index < 0) {
|
||||||
result = request.getContextPath() + "/uml/" + encoded;
|
path = request.getContextPath() + "/uml/" + encoded;
|
||||||
} else {
|
} else {
|
||||||
result = request.getContextPath() + "/uml/" + index + "/" + encoded;
|
path = request.getContextPath() + "/uml/" + index + "/" + encoded;
|
||||||
}
|
}
|
||||||
|
response.sendRedirect(path);
|
||||||
response.sendRedirect(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1,19 +1,16 @@
|
|||||||
<%@ page isErrorPage="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8" session="false" %>
|
<%@ page isErrorPage="true" contentType="text/html; charset=utf-8" pageEncoding="utf-8" session="false" %>
|
||||||
|
|
||||||
<%
|
|
||||||
String contextpath = request.getContextPath();
|
|
||||||
%>
|
|
||||||
|
|
||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
|
<base href="<%= request.getContextPath() %>/" />
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta http-equiv="expires" content="0" />
|
<meta http-equiv="expires" content="0" />
|
||||||
<meta http-equiv="pragma" content="no-cache" />
|
<meta http-equiv="pragma" content="no-cache" />
|
||||||
<meta http-equiv="cache-control" content="no-cache, must-revalidate" />
|
<meta http-equiv="cache-control" content="no-cache, must-revalidate" />
|
||||||
<link rel="stylesheet" href="<%= contextpath %>/plantuml.css" type="text/css"/>
|
<link rel="stylesheet" href="plantuml.css" type="text/css"/>
|
||||||
<link rel="icon" href="<%= contextpath %>/favicon.ico" type="image/x-icon"/>
|
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
|
||||||
<link rel="shortcut icon" href="<%= contextpath %>/favicon.ico" type="image/x-icon"/>
|
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
|
||||||
<title>PlantUMLServer Error</title>
|
<title>PlantUMLServer Error</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
|
@ -6,8 +6,6 @@
|
|||||||
// properties
|
// properties
|
||||||
boolean showSocialButtons = (boolean)request.getAttribute("showSocialButtons");
|
boolean showSocialButtons = (boolean)request.getAttribute("showSocialButtons");
|
||||||
boolean showGithubRibbon = (boolean)request.getAttribute("showGithubRibbon");
|
boolean showGithubRibbon = (boolean)request.getAttribute("showGithubRibbon");
|
||||||
// URL base
|
|
||||||
String contextpath = request.getAttribute("contextpath").toString();
|
|
||||||
// image URLs
|
// image URLs
|
||||||
boolean hasImg = (boolean)request.getAttribute("hasImg");
|
boolean hasImg = (boolean)request.getAttribute("hasImg");
|
||||||
String imgurl = request.getAttribute("imgurl").toString();
|
String imgurl = request.getAttribute("imgurl").toString();
|
||||||
@ -23,31 +21,17 @@
|
|||||||
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">
|
||||||
<html xmlns="http://www.w3.org/1999/xhtml">
|
<html xmlns="http://www.w3.org/1999/xhtml">
|
||||||
<head>
|
<head>
|
||||||
|
<base href="<%= request.getContextPath() %>/" />
|
||||||
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
|
||||||
<meta http-equiv="expires" content="0" />
|
<meta http-equiv="expires" content="0" />
|
||||||
<meta http-equiv="pragma" content="no-cache" />
|
<meta http-equiv="pragma" content="no-cache" />
|
||||||
<meta http-equiv="cache-control" content="no-cache, must-revalidate" />
|
<meta http-equiv="cache-control" content="no-cache, must-revalidate" />
|
||||||
<link rel="icon" href="<%= contextpath %>/favicon.ico" type="image/x-icon"/>
|
<link rel="icon" href="favicon.ico" type="image/x-icon"/>
|
||||||
<link rel="shortcut icon" href="<%= contextpath %>/favicon.ico" type="image/x-icon"/>
|
<link rel="shortcut icon" href="favicon.ico" type="image/x-icon"/>
|
||||||
<link rel="stylesheet" href="<%= contextpath %>/plantuml.css" />
|
<link rel="stylesheet" href="plantuml.css" />
|
||||||
<link rel="stylesheet" href="<%= contextpath %>/webjars/codemirror/5.63.0/lib/codemirror.css" />
|
<link rel="stylesheet" href="webjars/codemirror/5.63.0/lib/codemirror.css" />
|
||||||
<script src="<%= contextpath %>/webjars/codemirror/5.63.0/lib/codemirror.js"></script>
|
<script src="plantuml.js"></script>
|
||||||
<script>
|
<script src="webjars/codemirror/5.63.0/lib/codemirror.js"></script>
|
||||||
window.onload = function() {
|
|
||||||
// load CodeMirror
|
|
||||||
document.myCodeMirror = CodeMirror.fromTextArea(
|
|
||||||
document.getElementById("text"),
|
|
||||||
{ lineNumbers: true,
|
|
||||||
extraKeys: {Tab: false, "Shift-Tab": false}
|
|
||||||
}
|
|
||||||
);
|
|
||||||
// resolve relative path inside url input once
|
|
||||||
const url = document.getElementById("url");
|
|
||||||
if (!url.value.startsWith("http")) {
|
|
||||||
url.value = window.location.origin + url.value;
|
|
||||||
}
|
|
||||||
};
|
|
||||||
</script>
|
|
||||||
<title>PlantUMLServer</title>
|
<title>PlantUMLServer</title>
|
||||||
</head>
|
</head>
|
||||||
<body>
|
<body>
|
||||||
@ -64,7 +48,7 @@
|
|||||||
</div>
|
</div>
|
||||||
<div id="content">
|
<div id="content">
|
||||||
<%-- CONTENT --%>
|
<%-- CONTENT --%>
|
||||||
<form method="post" accept-charset="utf-8" action="<%= contextpath %>/form">
|
<form method="post" accept-charset="utf-8" action="form">
|
||||||
<p> <label for="text">UML Editor Content</label>
|
<p> <label for="text">UML Editor Content</label>
|
||||||
<textarea id="text" name="text" cols="120" rows="10"><%= net.sourceforge.plantuml.servlet.PlantUmlServlet.stringToHTMLString(decoded) %></textarea>
|
<textarea id="text" name="text" cols="120" rows="10"><%= net.sourceforge.plantuml.servlet.PlantUmlServlet.stringToHTMLString(decoded) %></textarea>
|
||||||
<input type="submit" value="Submit" title="Submit Code and generate diagram"/>
|
<input type="submit" value="Submit" title="Submit Code and generate diagram"/>
|
||||||
@ -73,7 +57,7 @@
|
|||||||
</form>
|
</form>
|
||||||
<hr/>
|
<hr/>
|
||||||
<p>You can enter here a previously generated URL:</p>
|
<p>You can enter here a previously generated URL:</p>
|
||||||
<form method="post" action="<%= contextpath %>/form">
|
<form method="post" action="form">
|
||||||
<p> <label for="url">previously generated URL</label>
|
<p> <label for="url">previously generated URL</label>
|
||||||
<input id="url" name="url" type="text" size="150" value="<%= imgurl %>" />
|
<input id="url" name="url" type="text" size="150" value="<%= imgurl %>" />
|
||||||
<br/>
|
<br/>
|
||||||
@ -103,33 +87,6 @@
|
|||||||
</p>
|
</p>
|
||||||
<% } %>
|
<% } %>
|
||||||
</div>
|
</div>
|
||||||
<script>
|
|
||||||
var clipboard_write=false;
|
|
||||||
var clipboard_read=false;
|
|
||||||
|
|
||||||
if (navigator.permissions){
|
|
||||||
navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
|
|
||||||
if (result.state == "granted" || result.state == "prompt") {
|
|
||||||
clipboard_write = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
|
|
||||||
if (result.state == "granted" || result.state == "prompt") {
|
|
||||||
clipboard_read = true;
|
|
||||||
}
|
|
||||||
});
|
|
||||||
};
|
|
||||||
|
|
||||||
function copyToClipboard(fieldid, fielddesc) {
|
|
||||||
if (clipboard_write == true){
|
|
||||||
var copyText = '';
|
|
||||||
copyText = document.getElementById(fieldid).value;
|
|
||||||
navigator.clipboard.writeText(document.getElementById(fieldid).value)
|
|
||||||
alert(fielddesc + " copied to clipboard");
|
|
||||||
}
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
</script>
|
|
||||||
<%-- FOOTER --%>
|
<%-- FOOTER --%>
|
||||||
<%@ include file="footer.jspf" %>
|
<%@ include file="footer.jspf" %>
|
||||||
</body>
|
</body>
|
||||||
|
58
src/main/webapp/plantuml.js
Normal file
58
src/main/webapp/plantuml.js
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
/*************************
|
||||||
|
* PlantUMLServlet script *
|
||||||
|
**************************/
|
||||||
|
|
||||||
|
let clipboard_write = false;
|
||||||
|
let clipboard_read = false;
|
||||||
|
|
||||||
|
function copyToClipboard(fieldid, fielddesc) {
|
||||||
|
if (clipboard_write) {
|
||||||
|
navigator.clipboard.writeText(document.getElementById(fieldid).value);
|
||||||
|
alert(fielddesc + " copied to clipboard");
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
function loadCodeMirror() {
|
||||||
|
document.myCodeMirror = CodeMirror.fromTextArea(
|
||||||
|
document.getElementById("text"),
|
||||||
|
{
|
||||||
|
lineNumbers: true,
|
||||||
|
extraKeys: {Tab: false, "Shift-Tab": false}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
function resolvePath(path) {
|
||||||
|
if (path.startsWith("http")) return path;
|
||||||
|
if (path.startsWith("/")) return window.location.origin + path;
|
||||||
|
|
||||||
|
if (path.slice(0, 2) == "./") path = path.slice(2);
|
||||||
|
let base = (document.querySelector('base') || {}).href || window.location.origin;
|
||||||
|
if (base.slice(-1) == "/") base = base.slice(0, -1);
|
||||||
|
return base + "/" + path;
|
||||||
|
}
|
||||||
|
|
||||||
|
window.onload = function() {
|
||||||
|
loadCodeMirror();
|
||||||
|
|
||||||
|
// resolve relative path inside url input once
|
||||||
|
const url = document.getElementById("url");
|
||||||
|
url.value = resolvePath(url.value);
|
||||||
|
|
||||||
|
// clipboard check (from PR#250)
|
||||||
|
// TODO: not supported by Firefox, Safari or WebView Android
|
||||||
|
// https://developer.mozilla.org/en-US/docs/Web/API/Permissions_API#browser_compatibility
|
||||||
|
if (navigator.permissions){
|
||||||
|
navigator.permissions.query({ name: "clipboard-write" }).then((result) => {
|
||||||
|
if (result.state == "granted" || result.state == "prompt") {
|
||||||
|
clipboard_write = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
navigator.permissions.query({ name: "clipboard-read" }).then((result) => {
|
||||||
|
if (result.state == "granted" || result.state == "prompt") {
|
||||||
|
clipboard_read = true;
|
||||||
|
}
|
||||||
|
});
|
||||||
|
};
|
||||||
|
};
|
Loading…
Reference in New Issue
Block a user