uri-resolver/src/main/java/org/gcube/datatransfer/resolver/http/HttpResolver.java

288 lines
8.1 KiB
Java

package org.gcube.datatransfer.resolver.http;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.URL;
import java.net.URLConnection;
import java.net.URLStreamHandler;
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.io.IOUtils;
import org.gcube.contentmanager.storageclient.model.protocol.smp.Handler;
import org.gcube.contentmanager.storageclient.model.protocol.smp.SMPURLConnection;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
/**
* The Class HttpResolver.
*
* @author Andrea Manzi(CERN)
* updated by Francesco Mangiacrapa
*/
public class HttpResolver extends HttpServlet {
protected static final String SMP_URI = "smp-uri";
protected static final String VALIDATION = "validation";
protected static final String CONTENT_TYPE = "contentType";
protected static final String FILE_NAME = "fileName";
protected static final String SMP_PATH_SEPARATOR = "/";
private static final long serialVersionUID = 1L;
/** The logger. */
private static final Logger logger = LoggerFactory.getLogger(HttpResolver.class);
/* (non-Javadoc)
* @see javax.servlet.GenericServlet#init(javax.servlet.ServletConfig)
*/
public void init(ServletConfig conf) throws ServletException {
Handler.activateProtocol();
super.init(conf);
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doGet(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws IOException {
String uri =null;
String fileName =null;
String contentType =null;
boolean validatingURI = false;
// logger.info("The http session id is: " + request.getSession().getId());
uri = request.getParameter(SMP_URI);
if (uri == null || uri.equals("")) {
logger.warn("URI not found");
response.sendError(404);
return;
}
fileName = request.getParameter(FILE_NAME);
if (fileName == null || fileName.equals("")) {
logger.warn("fileName not found");
fileName = null;
}
contentType = request.getParameter(CONTENT_TYPE);
if (contentType == null || contentType.equals("")) {
logger.warn("contentType not found");
contentType = null;
}
String validation = request.getParameter(VALIDATION);
validatingURI = Boolean.parseBoolean(validation);
logger.info("validation? "+validatingURI);
//we should not unescape the filename with spaces
logger.debug("uri = "+uri);
int index= uri.indexOf("?");
if (index!= -1){
logger.debug("Found char ?");
String firsPart = uri.substring(0, index);
//PATCH TO FIX #2695
try {
firsPart = validateItemName(firsPart, fileName);
logger.trace("valid smp path is: "+firsPart);
}
catch (Exception e) {
logger.warn("An error occurred during check right filename into SMP PATH");
}
String secondPart= uri.substring( index+1);
logger.debug("replacing in smp-uri char space with char + ...");
//FIXED BY FRANCESCO M.
secondPart = secondPart.replace(" ","+");//the char + is removed when the servlet is doing unescaping of the query parameters, we just put it back
logger.debug("new secondPart: "+secondPart);
uri= firsPart+"?"+secondPart;
}else {
logger.debug("Not found char ?");
uri = uri.replace(" ","+");//the char + is removed when the servlet is doing unescaping of the query parameters, we just put it back
}
logger.info("URI = "+ uri);
InputStream in = null;
try {
OutputStream out = response.getOutputStream();
if (fileName != null){
//The filename should be a quoted string. (According to Section 19.5.1 of RFC 2616)
//http://www.w3.org/Protocols/rfc2616/rfc2616-sec19.html#sec19.5.1
response.setHeader(ConstantsHttpResolver.CONTENT_DISPOSITION, "attachment; filename=\"" + fileName + "\"");
// response.addHeader("content-disposition", "attachment; filename=" +fileName);
}else
response.addHeader("content-disposition", "attachment; filename="+ConstantsHttpResolver.DEFAULT_FILENAME_FROM_STORAGE_MANAGER);
if (contentType!= null)
response.setContentType(contentType);
else
response.setContentType(ConstantsHttpResolver.DEFAULT_CONTENTTYPE_UNKNOWN_UNKNOWN);
URL url = new URL(null, uri, new URLStreamHandler() {
@Override
protected URLConnection openConnection(URL u) throws IOException {
return new SMPURLConnection(u);
}
});
URLConnection uc = null;
try {
uc = url.openConnection();
in = uc.getInputStream();
}
catch(Exception e){
response.sendError(404);
logger.error("URLConnection Exception:", e);
return;
}
//CASE InputStream NULL
if(in==null){
logger.warn("Input stream is null, sending status error 404");
sendErrorQuietly(response, 404);
return;
}
//CASE VALIDATION
if(validatingURI){
byte[] bytes = new byte[1]; //1B
int c = in.read(bytes);
logger.info(c+" byte read from InputStream");
if(c>0){
logger.info("at least 1 byte read, returning status 200");
IOUtils.closeQuietly(in);
response.setStatus(200);
return;
}
}
//CHANGED BY FRANCESCO M.
try {
IOUtils.copy(in, out);
} catch (IOException e){
logger.warn("IOException class name: "+e.getClass().getSimpleName());
if (e.getClass().getSimpleName().equals("ClientAbortException"))
logger.warn("Skipping ClientAbortException: "+e.getMessage());
else
throw e; //Sending Exceptions
} catch (NullPointerException e) {
logger.warn("NullPointerException during copy, skipping printStrackTrace");
sendErrorQuietly(response, 404);
} finally {
IOUtils.closeQuietly(in);
IOUtils.closeQuietly(out);
}
} catch (Exception e) {
logger.error("Exception:", e);
IOUtils.closeQuietly(in);
sendErrorQuietly(response, 404);
return;
}
}
/**
* Validate item name.
* Since the right filename is in the URI (fileName=COL_Mammalia_taxa.taf.gz), if SMP path does't contain it the right file is overwritten into SMP PATH
*
* @param smpPath the smp path
* @param fileName the file name
* @return the string
* @throws Exception the exception
*/
protected static String validateItemName(String smpPath, String fileName) throws Exception{
logger.debug("Checking right filename into SMP path..");
if(smpPath==null)
throw new Exception("Invalid smp path: "+smpPath);
int lastSp = smpPath.lastIndexOf(SMP_PATH_SEPARATOR);
if(lastSp<0)
throw new Exception(SMP_PATH_SEPARATOR + " not found in "+smpPath);
String smpItemName = smpPath.substring(lastSp+1, smpPath.length());
if(smpItemName.compareTo(fileName)!=0){
logger.info("SMP PATH contains a different filename, overrinding with "+fileName);
return smpPath.substring(0, lastSp+1)+fileName;
}
logger.info("SMP PATH contains same filename, returning");
return smpPath;
}
/**
* Send error quietly.
*
* @param response the response
* @param code the code
*/
protected void sendErrorQuietly(HttpServletResponse response, int code){
if(response!=null){
try {
response.sendError(code);
logger.info("Response sent error: "+code);
} catch (IOException ioe) {
// ignore
}
}
}
/* (non-Javadoc)
* @see javax.servlet.http.HttpServlet#doPost(javax.servlet.http.HttpServletRequest, javax.servlet.http.HttpServletResponse)
*/
protected void doPost(HttpServletRequest request,
HttpServletResponse response) throws IOException {
doGet(request,response);
}
/**
* The main method.
*
* @param args the arguments
*/
public static void main(String[] args) {
String fileName = "COL_taxa.taf.gz";
String smpPath = "smp://Share/89971b8f-a993-4e7b-9a95-8d774cb68a99/Work+Packages/WP+6+-+Virtual+Research+Environments+Deployment+and+Operation/T6.2+Resources+and+Tools/COMET-Species-Matching-Engine/YASMEEN/1.2.0/Data/BiOnymTAF/COL_taxa.taf.gz";
try {
System.out.println(validateItemName(smpPath, fileName));
}
catch (Exception e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
}