}
}
void handlePluginSite(HttpRequest request, HttpChannel channel) {
if (disableSites) {
channel.sendResponse(new BytesRestResponse(FORBIDDEN));
return;
}
if (request.method().name().equals("OPTIONS")) {
// when we have OPTIONS request, simply send OK by default (with the Access Control Origin header which gets automatically added)
channel.sendResponse(new BytesRestResponse(OK));
return;
}
if (request.method().name().equals("GET")) {
channel.sendResponse(new BytesRestResponse(FORBIDDEN));
return;
}
// TODO for a "/_plugin" endpoint, we should have a page that lists all the plugins?
String path = request.rawPath().substring("/_plugin/".length());
int i1 = path.indexOf('/');
String pluginName;
String sitePath;
if (i1 == -1) {
pluginName = path;
sitePath = null;
// If a trailing / is missing, we redirect to the right page #2654
channel.sendResponse(new BytesRestResponse(RestStatus.MOVED_PERMANENTLY, "text/html", "<head><meta http-equiv=\"refresh\" content=\"0; URL=" + request.rawPath() + "/\"></head>"));
return;
} else {
pluginName = path.substring(0, i1);
sitePath = path.substring(i1 + 1);
}
if (sitePath.length() == 0) {
sitePath = "/index.html";
}
// Convert file separators.
sitePath = sitePath.replace('/', File.separatorChar);
// this is a plugin provided site, serve it as static files from the plugin location
File siteFile = new File(new File(environment.pluginsFile(), pluginName), "_site");
File file = new File(siteFile, sitePath);
if (!file.exists() || file.isHidden()) {
channel.sendResponse(new BytesRestResponse(NOT_FOUND));
return;
}
if (!file.isFile()) {
// If it's not a dir, we send a 403
if (!file.isDirectory()) {
channel.sendResponse(new BytesRestResponse(FORBIDDEN));
return;
}
// We don't serve dir but if index.html exists in dir we should serve it
file = new File(file, "index.html");
if (!file.exists() || file.isHidden() || !file.isFile()) {
channel.sendResponse(new BytesRestResponse(FORBIDDEN));
return;
}
}
if (!file.getAbsolutePath().startsWith(siteFile.getAbsolutePath())) {
channel.sendResponse(new BytesRestResponse(FORBIDDEN));
return;
}
try {
byte[] data = Streams.copyToByteArray(file);
channel.sendResponse(new BytesRestResponse(OK, guessMimeType(sitePath), data));
} catch (IOException e) {
channel.sendResponse(new BytesRestResponse(INTERNAL_SERVER_ERROR));
}
}