/*******************************************************************************
* Copyright (c) 2011 The Board of Trustees of the Leland Stanford Junior University
* as Operator of the SLAC National Accelerator Laboratory.
* Copyright (c) 2011 Brookhaven National Laboratory.
* EPICS archiver appliance is distributed subject to a Software License Agreement found
* in file LICENSE that is included with this distribution.
*******************************************************************************/
package org.epics.archiverappliance.retrieval.bpl;
import java.io.BufferedInputStream;
import java.io.ByteArrayOutputStream;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.HashMap;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.log4j.Logger;
import org.epics.archiverappliance.common.BPLAction;
import org.epics.archiverappliance.config.ConfigService;
import org.epics.archiverappliance.retrieval.mimeresponses.MimeResponse;
import org.epics.archiverappliance.utils.ui.MimeTypeConstants;
import org.json.simple.JSONValue;
/**
* Puts a client configuration JSON file given the file name.
* The new configuration is part of te POST body.
* @author mshankar
*
*/
public class PutClientConfiguration implements BPLAction {
private static Logger logger = Logger.getLogger(PutClientConfiguration.class.getName());
@Override
public void execute(HttpServletRequest req, HttpServletResponse resp, ConfigService configService) throws IOException {
if(!configService.getInstallationProperties().containsKey("org.epics.archiverappliance.retrieval.bpl.GetClientConfiguration.DocumentRoot")) {
logger.error("This installation has not been configured to serve archiver config files.");
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
byte[] newConfigBytes = null;
try(ByteArrayOutputStream bos = new ByteArrayOutputStream()) {
try(InputStream is = new BufferedInputStream(req.getInputStream())) {
byte[] buf = new byte[10*1024];
int bytesRead = is.read(buf);
while(bytesRead > 0) {
bos.write(buf, 0, bytesRead);
bytesRead = is.read(buf);
}
}
newConfigBytes = bos.toByteArray();
}
logger.debug("New configuraiton is of size " + newConfigBytes.length);
String configFileName = req.getParameter("configFile");
if(configFileName == null
|| configFileName.equals("")
|| configFileName.contains("..")
|| configFileName.startsWith("/")
|| !configFileName.endsWith(".json")) {
logger.error("The config file has not been specified (correctly) " + configFileName);
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
Path documentRoot = Paths.get((String) configService.getInstallationProperties().get("org.epics.archiverappliance.retrieval.bpl.GetClientConfiguration.DocumentRoot"));
if(!Files.exists(documentRoot)) {
logger.error("The document root does not exist " + documentRoot.toString());
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
Path configFilePath = documentRoot.resolve(configFileName);
if(!configFilePath.startsWith(documentRoot)) {
logger.error("The final path to the config file " + configFilePath + " does not seem to be part of the document root. Denying access to the file as a security precaution.");
resp.sendError(HttpServletResponse.SC_NOT_FOUND);
return;
}
if(req.getParameter("download") != null) {
logger.info("Sending back the incoming data as a content dispositon");
// Allow applications served from other URL's to access the JSON data from this server.
resp.addHeader(MimeResponse.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
resp.setContentType("application/force-download");
resp.setContentLength(newConfigBytes.length);
resp.setHeader("Content-Transfer-Encoding", "binary");
resp.setHeader("Content-Disposition","attachment; filename=\"" + "xxx\"");//fileName);
resp.setContentType(MimeTypeConstants.APPLICATION_JSON);
resp.setHeader("Content-Disposition", "attachment; filename=" + configFileName);
try (OutputStream out = resp.getOutputStream()) {
out.write(newConfigBytes);
}
return;
} else {
resp.setContentType(MimeTypeConstants.APPLICATION_JSON);
resp.addHeader(MimeResponse.ACCESS_CONTROL_ALLOW_ORIGIN, "*");
try(FileOutputStream fos = new FileOutputStream(configFilePath.toFile(), false)) {
fos.write(newConfigBytes);
}
HashMap<String, Object> infoValues = new HashMap<String, Object>();
try(PrintWriter out = resp.getWriter()) {
infoValues.put("status", "ok");
out.println(JSONValue.toJSONString(infoValues));
}
}
}
}