/*******************************************************************************
* ============LICENSE_START==================================================
* * org.onap.dmaap
* * ===========================================================================
* * Copyright © 2017 AT&T Intellectual Property. All rights reserved.
* * ===========================================================================
* * Licensed under the Apache License, Version 2.0 (the "License");
* * you may not use this file except in compliance with the License.
* * You may obtain a copy of the License at
* *
* * http://www.apache.org/licenses/LICENSE-2.0
* *
* * Unless required by applicable law or agreed to in writing, software
* * distributed under the License is distributed on an "AS IS" BASIS,
* * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* * See the License for the specific language governing permissions and
* * limitations under the License.
* * ============LICENSE_END====================================================
* *
* * ECOMP is a trademark and service mark of AT&T Intellectual Property.
* *
******************************************************************************/
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URLEncoder;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.apache.commons.codec.binary.Base64;
import org.apache.log4j.Logger;
/**
* Example stand alone subscriber servlet with Authorization header checking
*/
public class SubscriberServlet extends HttpServlet {
private static Logger logger = Logger.getLogger("com.att.datarouter.pubsub.ssasubscribe.SubscriberServlet");
private String Login = "LOGIN";
private String Password = "PASSWORD";
private String OutputDirectory = "/root/sub/received";
private String auth;
private static String gp(ServletConfig config, String param, String deflt) {
param = config.getInitParameter(param);
if (param == null || param.length() == 0) {
param = deflt;
}
return(param);
}
/**
* Configure this subscriberservlet. Configuration parameters from config.getInitParameter() are:
*
* - Login - The login expected in the Authorization header (default "LOGIN").
*
- Password - The password expected in the Authorization header (default "PASSWORD").
*
- OutputDirectory - The directory where files are placed (default "received").
*
*/
public void init(ServletConfig config) throws ServletException {
Login = gp(config, "Login", Login);
Password = gp(config, "Password", Password);
OutputDirectory = gp(config, "OutputDirectory", OutputDirectory);
(new File(OutputDirectory)).mkdirs();
auth = "Basic " + Base64.encodeBase64String((Login + ":" + Password).getBytes());
}
/**
* Invoke common(req, resp, false).
*/
protected void doPut(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
common(req, resp, false);
}
/**
* Invoke common(req, resp, true).
*/
protected void doDelete(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
common(req, resp, true);
}
/**
* Process a PUT or DELETE request.
*
* - Verify that the request contains an Authorization header
* or else UNAUTHORIZED.
*
- Verify that the Authorization header matches the configured
* Login and Password or else FORBIDDEN.
*
- If the request is PUT, store the message body as a file
* in the configured OutputDirectory directory protecting against
* evil characters in the received FileID. The file is created
* initially with its name prefixed with a ".", and once it is complete, it is
* renamed to remove the leading "." character.
*
- If the request is DELETE, instead delete the file (if it exists) from the configured OutputDirectory directory.
*
- Respond with NO_CONTENT.
*
*/
protected void common(HttpServletRequest req, HttpServletResponse resp, boolean isdelete) throws ServletException, IOException {
String ah = req.getHeader("Authorization");
if (ah == null) {
logger.info("Rejecting request with no Authorization header from " + req.getRemoteAddr() + ": " + req.getPathInfo());
resp.sendError(HttpServletResponse.SC_UNAUTHORIZED);
return;
}
if (!auth.equals(ah)) {
logger.info("Rejecting request with incorrect Authorization header from " + req.getRemoteAddr() + ": " + req.getPathInfo());
resp.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
String fileid = req.getPathInfo();
fileid = fileid.substring(fileid.lastIndexOf('/') + 1);
String qs = req.getQueryString();
if (qs != null) {
fileid = fileid + "?" + qs;
}
String publishid = req.getHeader("X-ATT-DR-PUBLISH-ID");
String filename = URLEncoder.encode(fileid, "UTF-8").replaceAll("^\\.", "%2E").replaceAll("\\*", "%2A");
String finalname = OutputDirectory + "/" + filename;
String tmpname = OutputDirectory + "/." + filename;
try {
if (isdelete) {
(new File(finalname)).delete();
logger.info("Received delete for file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + finalname);
} else {
InputStream is = req.getInputStream();
OutputStream os = new FileOutputStream(tmpname);
byte[] buf = new byte[65536];
int i;
while ((i = is.read(buf)) > 0) {
os.write(buf, 0, i);
}
is.close();
os.close();
(new File(tmpname)).renameTo(new File(finalname));
logger.info("Received file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + finalname);
resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
logger.info("Received file id " + fileid + " from " + req.getRemoteAddr() + " publish id " + publishid + " as " + finalname);
}
resp.setStatus(HttpServletResponse.SC_NO_CONTENT);
} catch (IOException ioe) {
(new File(tmpname)).delete();
logger.info("Failure to save file " + finalname + " from " + req.getRemoteAddr() + ": " + req.getPathInfo(), ioe);
throw ioe;
}
}
}