/* =======================================================
Copyright 2014 - ePortfolium - Licensed under the
Educational Community 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.osedu.org/licenses/ECL-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.
======================================================= */
package com.portfolio.data.attachment;
import java.io.DataInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.StringReader;
import java.io.StringWriter;
import java.net.HttpURLConnection;
import java.net.Inet4Address;
import java.net.InetAddress;
import java.net.MalformedURLException;
import java.net.NetworkInterface;
import java.net.URL;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import java.util.Enumeration;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.naming.InitialContext;
import javax.servlet.ServletConfig;
import javax.servlet.ServletContext;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.Cookie;
import javax.servlet.http.HttpServlet;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpSession;
import javax.sql.DataSource;
import javax.ws.rs.core.Response.Status;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.xpath.XPath;
import javax.xml.xpath.XPathConstants;
import javax.xml.xpath.XPathFactory;
import org.apache.commons.fileupload.FileItem;
import org.apache.commons.fileupload.FileUploadException;
import org.apache.commons.fileupload.disk.DiskFileItemFactory;
import org.apache.commons.fileupload.servlet.ServletFileUpload;
import org.apache.commons.httpclient.Header;
import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.GetMethod;
import org.apache.commons.io.IOUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.NodeList;
import org.w3c.dom.ls.DOMImplementationLS;
import org.w3c.dom.ls.LSSerializer;
import org.xml.sax.InputSource;
import com.google.gson.stream.JsonWriter;
import com.portfolio.data.provider.DataProvider;
import com.portfolio.data.utils.ConfigUtils;
import com.portfolio.data.utils.SqlUtils;
import com.portfolio.rest.RestWebApplicationException;
import com.portfolio.security.Credential;
public class FileServlet extends HttpServlet
{
final Logger logger = LoggerFactory.getLogger(FileServlet.class);
// DataProvider dataProvider = null;
boolean hasNodeReadRight = false;
boolean hasNodeWriteRight = false;
final Credential credential = new Credential();
private String server = "";
private String backend = "";
private String dataProviderName = "";
ServletContext servContext;
DataSource ds;
ArrayList<String> ourIPs = new ArrayList<String>();
DataProvider dataProvider;
@Override
public void init( ServletConfig config )
{
/// List possible local address
try
{
super.init(config);
dataProvider = SqlUtils.initProvider(config.getServletContext(), logger);
Enumeration<NetworkInterface> interfaces = NetworkInterface.getNetworkInterfaces();
while (interfaces.hasMoreElements()){
NetworkInterface current = interfaces.nextElement();
if ( !current.isUp() ) continue;
Enumeration<InetAddress> addresses = current.getInetAddresses();
while (addresses.hasMoreElements()){
InetAddress current_addr = addresses.nextElement();
if (current_addr instanceof Inet4Address)
{
String ip = current_addr.getHostAddress();
// System.out.println("USED IP: "+ip);
ourIPs.add(ip);
}
}
}
// Force localhost ip to be set, sometime it isn't listed
// ourIPs.add("127.0.0.1");
}
catch( Exception e )
{
}
// servContext = config.getServletContext();
servContext = config.getServletContext();
try
{
ConfigUtils.loadConfigFile(config.getServletContext());
}
catch( Exception e1 )
{
e1.printStackTrace();
}
backend = ConfigUtils.get("backendserver");
server = ConfigUtils.get("fileserver");
dataProviderName = ConfigUtils.get("dataProviderClass");
try
{
InitialContext cxt = new InitialContext();
if ( cxt == null ) {
throw new Exception("no context found!");
}
/// Init this here, might fail depending on server hosting
ds = (DataSource) cxt.lookup( "java:/comp/env/jdbc/portfolio-backend" );
if ( ds == null ) {
throw new Exception("Data jdbc/portfolio-backend source not found!");
}
}
catch( Exception e )
{
logger.error(e.getMessage());
e.printStackTrace();
}
}
public void initialize(HttpServletRequest httpServletRequest)
{
// checkCredential(httpServletRequest);
}
@Override
protected void doPut(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// =====================================================================================
initialize(request);
String useragent = request.getHeader("User-Agent");
logger.error("Agent: "+useragent);
// DataProvider dataProvider = null;
Connection c = null;
try
{
// dataProvider = SqlUtils.initProvider(getServletContext(), logger);
// dataProvider = (DataProvider) Class.forName(dataProviderName).newInstance();
//On initialise le dataProvider
/*
if( ds == null ) // Case where we can't deploy context.xml
{ c = SqlUtils.getConnection(servContext); }
else
{ c = ds.getConnection(); }
dataProvider.setConnection(c);
//*/
c = SqlUtils.getConnection(getServletContext());
int userId = 0;
int groupId = 0;
String user = "";
boolean fromSakai = false;
String doCopy = request.getParameter("copy");
if( doCopy != null )
doCopy = "?copy";
else
doCopy = "";
HttpSession session = request.getSession(false);
if( session != null )
{
String srceType = request.getParameter("srce");
if( "sakai".equals(srceType) )
{
fromSakai = true;
}
Integer val = (Integer) session.getAttribute("uid");
if( val != null )
userId = val;
val = (Integer) session.getAttribute("gid");
if( val != null )
groupId = val;
user = (String) session.getAttribute("user");
}
else
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
/// uuid: celui de la ressource
/// /resources/resource/file/{uuid}[?size=[S|L]&lang=[fr|en]]
String origin = request.getRequestURL().toString();
/// R�cup�ration des param�tres
String url = request.getPathInfo();
String[] token = url.split("/");
String uuid = token[1];
String size = request.getParameter("size");
if(size == null)
size = "S";
String lang = request.getParameter("lang");
if (lang==null){
lang = "fr";
}
/// V�rification des droits d'acc�s
if(!credential.hasNodeRight(c, userId, groupId, uuid, Credential.WRITE))
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
//throw new Exception("L'utilisateur userId="+userId+" n'a pas le droit WRITE sur le noeud "+nodeUuid);
}
String data;
String fileid = "";
data = dataProvider.getResNode(c, uuid, userId, groupId);
/// Parse les donn�es
DocumentBuilderFactory documentBuilderFactory =DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader("<node>"+data+"</node>"));
Document doc = documentBuilder.parse(is);
DOMImplementationLS impl = (DOMImplementationLS)doc.getImplementation().getFeature("LS", "3.0");
LSSerializer serial = impl.createLSSerializer();
serial.getDomConfig().setParameter("xml-declaration", false);
/// Cherche si on a d�j� envoy� quelque chose
XPath xPath = XPathFactory.newInstance().newXPath();
// String filterRes = "//filename[@lang=\""+lang+"\"]";
String filterRes = "//*[local-name()='filename' and @lang='"+lang+"']";
NodeList nodelist = (NodeList) xPath.compile(filterRes).evaluate(doc, XPathConstants.NODESET);
String filename = "";
if( nodelist.getLength() > 0 )
filename = nodelist.item(0).getTextContent();
/// Ignore replacing file, just consider them all new one
// /*
if( !"".equals(filename) )
{
/// Already have one, per language
// String filterId = "//fileid[@lang='"+lang+"']";
String filterId = "//*[local-name()='fileid' and @lang='"+lang+"']";
NodeList idlist = (NodeList) xPath.compile(filterId).evaluate(doc, XPathConstants.NODESET);
if( idlist.getLength() != 0 )
{
Element fileNode = (Element) idlist.item(0);
fileid = fileNode.getTextContent();
}
}
int last = fileid.lastIndexOf("/") +1; // FIXME temp patch
if( last < 0 )
last = 0;
fileid = fileid.substring(last);
//*/
/// �criture des donn�es
String urlTarget = server + "/" + fileid+doCopy;
// String urlTarget = "http://"+ server + "/user/" + user +"/file/" + uuid +"/"+ lang+ "/ptype/fs";
// Unpack form, fetch binary data and send
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
String json = "";
HttpURLConnection connection=null;
// Parse the request
InputStream inputData = null;
String fileName = "";
long filesize = 0;
String contentType = "";
if( fromSakai )
{
String sakai_session = (String) session.getAttribute("sakai_session");
String sakai_server = (String) session.getAttribute("sakai_server"); // Base server http://localhost:9090
String srceUrl = request.getParameter("srceurl");
HttpClient client = new HttpClient();
// Create connection to url
GetMethod get = new GetMethod(sakai_server+"/"+srceUrl);
// Set headers
Header header = new Header();
header.setName("JSESSIONID");
header.setValue(sakai_session);
get.setRequestHeader(header);
int status = client.executeMethod(get);
if (status != HttpStatus.SC_OK) {
System.err.println("Method failed: " + get.getStatusLine());
}
// Retrieve inputData
inputData = get.getResponseBodyAsStream();
// File detail
Header nameHeader = get.getResponseHeader("Content-Disposition");
Header sizeHeader = get.getResponseHeader("Content-Length");
Header typeHeader = get.getResponseHeader("Content-Type");
filesize = Integer.parseInt(sizeHeader.getValue());
contentType = typeHeader.getValue();
fileName = nameHeader.getValue().split("=")[1];
if( fileName.startsWith("\"") )
fileName = fileName.substring(1, fileName.length()-1);
}
else
{
// if( ServletFileUpload.isMultipartContent(request) )
if( true )
{
List<FileItem> items = upload.parseRequest(request);
// Process the uploaded items
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext())
{
FileItem item = iter.next();
if ("uploadfile".equals(item.getFieldName()))
{
// Send raw data
inputData = item.getInputStream();
fileName = item.getName();
filesize = item.getSize();
contentType = item.getContentType();
break;
}
}
}
else
{
// List headers
Enumeration attributes = request.getAttributeNames();
while( attributes.hasMoreElements() )
{
Object elem = attributes.nextElement();
logger.error("Object: "+elem.toString());
}
logger.error("Not multipart");
}
}
if( inputData != null )
{
connection = CreateConnection( urlTarget, request );
connection.setRequestProperty("filename",uuid);
connection.setRequestProperty("content-type", "application/octet-stream");
connection.setRequestProperty("content-length", Long.toString(filesize));
connection.connect();
/// Send data to fileserver
OutputStream outputData = connection.getOutputStream();
IOUtils.copy(inputData, outputData);
/// Those 2 lines are needed, otherwise, no request sent
int code = connection.getResponseCode();
String msg = connection.getResponseMessage();
/// Retrieving info
InputStream objReturn = connection.getInputStream();
StringWriter idResponse = new StringWriter();
IOUtils.copy(objReturn, idResponse);
fileid = idResponse.toString();
connection.disconnect();
/// Construct Json
StringWriter StringOutput = new StringWriter();
JsonWriter writer = new JsonWriter(StringOutput);
writer.beginObject();
writer.name("files");
writer.beginArray();
writer.beginObject();
writer.name("name").value(fileName);
writer.name("size").value(filesize);
writer.name("type").value(contentType);
writer.name("url").value(origin);
writer.name("fileid").value(fileid);
// writer.name("deleteUrl").value(ref);
// writer.name("deleteType").value("DELETE");
writer.endObject();
writer.endArray();
writer.endObject();
writer.close();
json = StringOutput.toString();
}
connection.disconnect();
/// Renvoie le JSON au client
if( useragent.contains("MSIE 9.0") || useragent.contains("MSIE 8.0") || useragent.contains("MSIE 7.0") )
response.setContentType("text/html");
else // The normal type
response.setContentType("application/json");
PrintWriter respWriter = response.getWriter();
respWriter.write(json);
// RetrieveAnswer(connection, response, ref);
// dataProvider.disconnect();
}
catch(Exception e)
{
logger.error("Binary transfer error: "+e.getMessage()+"");
e.printStackTrace();
}
finally
{
try
{
if( c != null ) c.close();
}
catch( SQLException e ){ e.printStackTrace(); }
}
}
// =====================================================================================
@Override
protected void doPost(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
// =====================================================================================
initialize(request);
String useragent = request.getHeader("User-Agent");
logger.error("Agent: "+useragent);
// DataProvider dataProvider = null;
Connection c = null;
try
{
// dataProvider = SqlUtils.initProvider(getServletContext(), logger);
// dataProvider = (DataProvider) Class.forName(dataProviderName).newInstance();
//On initialise le dataProvider
/*
if( ds == null ) // Case where we can't deploy context.xml
{ c = SqlUtils.getConnection(servContext); }
else
{ c = ds.getConnection(); }
dataProvider.setConnection(c);
//*/
c = SqlUtils.getConnection(getServletContext());
int userId = 0;
int groupId = 0;
String user = "";
boolean fromSakai = false;
String doCopy = request.getParameter("copy");
if( doCopy != null )
doCopy = "?copy";
else
doCopy = "";
HttpSession session = request.getSession(false);
if( session != null )
{
String srceType = request.getParameter("srce");
if( "sakai".equals(srceType) )
{
fromSakai = true;
}
Integer val = (Integer) session.getAttribute("uid");
if( val != null )
userId = val;
val = (Integer) session.getAttribute("gid");
if( val != null )
groupId = val;
user = (String) session.getAttribute("user");
}
else
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
return;
}
/// uuid: celui de la ressource
/// /resources/resource/file/{uuid}[?size=[S|L]&lang=[fr|en]]
String origin = request.getRequestURL().toString();
/// R�cup�ration des param�tres
String url = request.getPathInfo();
String[] token = url.split("/");
String uuid = token[1];
String size = request.getParameter("size");
if(size == null)
size = "S";
String lang = request.getParameter("lang");
if (lang==null){
lang = "fr";
}
/// V�rification des droits d'acc�s
if(!credential.hasNodeRight(c, userId, groupId, uuid, Credential.WRITE))
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
//throw new Exception("L'utilisateur userId="+userId+" n'a pas le droit WRITE sur le noeud "+nodeUuid);
}
String data;
String fileid = "";
data = dataProvider.getResNode(c, uuid, userId, groupId);
/// Parse les donn�es
DocumentBuilderFactory documentBuilderFactory =DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader("<node>"+data+"</node>"));
Document doc = documentBuilder.parse(is);
DOMImplementationLS impl = (DOMImplementationLS)doc.getImplementation().getFeature("LS", "3.0");
LSSerializer serial = impl.createLSSerializer();
serial.getDomConfig().setParameter("xml-declaration", false);
/// Cherche si on a d�j� envoy� quelque chose
XPath xPath = XPathFactory.newInstance().newXPath();
// String filterRes = "//filename[@lang=\""+lang+"\"]";
String filterRes = "//*[local-name()='filename' and @lang='"+lang+"']";
NodeList nodelist = (NodeList) xPath.compile(filterRes).evaluate(doc, XPathConstants.NODESET);
String filename = "";
if( nodelist.getLength() > 0 )
filename = nodelist.item(0).getTextContent();
/// Ignore replacing file, just consider them all new one
/*
if( !"".equals(filename) )
{
/// Already have one, per language
// String filterId = "//fileid[@lang='"+lang+"']";
String filterId = "//*[local-name()='fileid' and @lang='"+lang+"']";
NodeList idlist = (NodeList) xPath.compile(filterId).evaluate(doc, XPathConstants.NODESET);
if( idlist.getLength() != 0 )
{
Element fileNode = (Element) idlist.item(0);
fileid = fileNode.getTextContent();
}
}
int last = fileid.lastIndexOf("/") +1; // FIXME temp patch
if( last < 0 )
last = 0;
fileid = fileid.substring(last);
//*/
/// �criture des donn�es
String urlTarget = server + "/" + fileid+doCopy;
// String urlTarget = "http://"+ server + "/user/" + user +"/file/" + uuid +"/"+ lang+ "/ptype/fs";
// Unpack form, fetch binary data and send
// Create a factory for disk-based file items
DiskFileItemFactory factory = new DiskFileItemFactory();
// Create a new file upload handler
ServletFileUpload upload = new ServletFileUpload(factory);
String json = "";
HttpURLConnection connection=null;
// Parse the request
InputStream inputData = null;
String fileName = "";
long filesize = 0;
String contentType = "";
if( fromSakai )
{
String sakai_session = (String) session.getAttribute("sakai_session");
String sakai_server = (String) session.getAttribute("sakai_server"); // Base server http://localhost:9090
String srceUrl = request.getParameter("srceurl");
HttpClient client = new HttpClient();
// Create connection to url
GetMethod get = new GetMethod(sakai_server+"/"+srceUrl);
// Set headers
Header header = new Header();
header.setName("JSESSIONID");
header.setValue(sakai_session);
get.setRequestHeader(header);
int status = client.executeMethod(get);
if (status != HttpStatus.SC_OK) {
System.err.println("Method failed: " + get.getStatusLine());
}
// Retrieve inputData
inputData = get.getResponseBodyAsStream();
// File detail
Header nameHeader = get.getResponseHeader("Content-Disposition");
Header sizeHeader = get.getResponseHeader("Content-Length");
Header typeHeader = get.getResponseHeader("Content-Type");
filesize = Integer.parseInt(sizeHeader.getValue());
contentType = typeHeader.getValue();
fileName = nameHeader.getValue().split("=")[1];
if( fileName.startsWith("\"") )
fileName = fileName.substring(1, fileName.length()-1);
}
else
{
// if( ServletFileUpload.isMultipartContent(request) )
if( true )
{
List<FileItem> items = upload.parseRequest(request);
// Process the uploaded items
Iterator<FileItem> iter = items.iterator();
while (iter.hasNext())
{
FileItem item = iter.next();
if ("uploadfile".equals(item.getFieldName()))
{
// Send raw data
inputData = item.getInputStream();
fileName = item.getName();
filesize = item.getSize();
contentType = item.getContentType();
break;
}
}
}
else
{
// List headers
Enumeration attributes = request.getAttributeNames();
while( attributes.hasMoreElements() )
{
Object elem = attributes.nextElement();
logger.error("Object: "+elem.toString());
}
logger.error("Not multipart");
}
}
if( inputData != null )
{
connection = CreateConnection( urlTarget, request );
connection.setRequestProperty("filename",uuid);
connection.setRequestProperty("content-type", "application/octet-stream");
connection.setRequestProperty("content-length", Long.toString(filesize));
connection.connect();
/// Send data to fileserver
OutputStream outputData = connection.getOutputStream();
IOUtils.copy(inputData, outputData);
/// Those 2 lines are needed, otherwise, no request sent
int code = connection.getResponseCode();
String msg = connection.getResponseMessage();
/// Retrieving info
InputStream objReturn = connection.getInputStream();
StringWriter idResponse = new StringWriter();
IOUtils.copy(objReturn, idResponse);
fileid = idResponse.toString();
connection.disconnect();
/// Construct Json
StringWriter StringOutput = new StringWriter();
JsonWriter writer = new JsonWriter(StringOutput);
writer.beginObject();
writer.name("files");
writer.beginArray();
writer.beginObject();
writer.name("name").value(fileName);
writer.name("size").value(filesize);
writer.name("type").value(contentType);
writer.name("url").value(origin);
writer.name("fileid").value(fileid);
// writer.name("deleteUrl").value(ref);
// writer.name("deleteType").value("DELETE");
writer.endObject();
writer.endArray();
writer.endObject();
writer.close();
json = StringOutput.toString();
}
connection.disconnect();
/// Renvoie le JSON au client
if( useragent.contains("MSIE 9.0") || useragent.contains("MSIE 8.0") || useragent.contains("MSIE 7.0") )
response.setContentType("text/html");
else // The normal type
response.setContentType("application/json");
PrintWriter respWriter = response.getWriter();
respWriter.write(json);
// RetrieveAnswer(connection, response, ref);
// dataProvider.disconnect();
}
catch(Exception e)
{
logger.error("Binary transfer error: "+e.getMessage()+"");
e.printStackTrace();
}
finally
{
try
{
if( c != null ) c.close();
}
catch( SQLException e ){ e.printStackTrace(); }
}
}
// =====================================================================================
@Override
protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException
{
initialize(request);
// DataProvider dataProvider = null;
Connection c = null;
try{
// dataProvider = SqlUtils.initProvider(getServletContext(), logger);
c = SqlUtils.getConnection(getServletContext());
/*
dataProvider = (DataProvider) Class.forName(dataProviderName).newInstance();
//On initialise le dataProvider
if( ds == null ) // Case where we can't deploy context.xml
{ c = SqlUtils.getConnection(servContext); }
else
{ c = ds.getConnection(); }
dataProvider.setConnection(c);
//*/
int userId = 0;
int groupId = 0;
String user = "";
String context = request.getContextPath();
String url = request.getPathInfo();
HttpSession session = request.getSession(true);
if( session != null )
{
Integer val = (Integer) session.getAttribute("uid");
if( val != null )
userId = val;
val = (Integer) session.getAttribute("gid");
if( val != null )
groupId = val;
user = (String) session.getAttribute("user");
}
/*
Credential credential = null;
try
{
//On initialise le dataProvider
Connection c = null;
if( ds == null ) // Case where we can't deploy context.xml
{ c = SqlUtils.getConnection(servContext); }
else
{ c = ds.getConnection(); }
dataProvider.setConnection(c);
credential = new Credential(c);
}
catch(Exception e)
{
e.printStackTrace();
}
//*/
// =====================================================================================
boolean trace = false;
StringBuffer outTrace = new StringBuffer();
StringBuffer outPrint = new StringBuffer();
String logFName = null;
response.setCharacterEncoding("UTF-8");
System.out.println("FileServlet::doGet: "+url+" from user: "+userId );
// ====== URI : /resources/file[/{lang}]/{context-id}
// ====== PathInfo: /resources/file[/{uuid}?lang={fr|en}&size={S|L}] pathInfo
// String uri = request.getRequestURI();
String[] token = url.split("/");
String uuid = token[1];
//wadbackend.WadUtilities.appendlogfile(logFName, "GETfile:"+request.getRemoteAddr()+":"+uri);
/// FIXME: Passe la s�curit� si la source provient de localhost, il faudrait un �change afin de s'assurer que n'importe quel servlet ne puisse y acc�der
String sourceip = request.getRemoteAddr();
// System.out.println("IP: "+sourceip);
// System.out.println(ourIPs);
/// V�rification des droits d'acc�s
// TODO: Might be something special with proxy and export/PDF, to investigate
if( !ourIPs.contains(sourceip) )
{
if( userId == 0 )
throw new RestWebApplicationException(Status.FORBIDDEN, "");
if(!credential.hasNodeRight(c, userId, groupId, uuid, Credential.READ))
{
response.sendError(HttpServletResponse.SC_FORBIDDEN);
//throw new Exception("L'utilisateur userId="+userId+" n'a pas le droit READ sur le noeud "+nodeUuid);
}
}
else // Si la requ�te est locale et qu'il n'y a pas de session, on ignore la v�rification
{
System.out.println("IP OK: bypass");
logger.error("IP OK: bypass");
}
/// On r�cup�re le noeud de la ressource pour retrouver le lien
String data = dataProvider.getResNode(c, uuid, userId, groupId);
// javax.servlet.http.HttpSession session = request.getSession(true);
//====================================================
//String ppath = session.getServletContext().getRealPath("/");
//logFName = ppath +"logs/logNode.txt";
//====================================================
String size = request.getParameter("size");
if(size == null)
size = "";
String lang = request.getParameter("lang");
if (lang==null){
lang = "fr";
}
/*
String nodeUuid = uri.substring(uri.lastIndexOf("/")+1);
if (uri.lastIndexOf("/")>uri.indexOf("file/")+6) { // -- file/ = 5 carac. --
lang = uri.substring(uri.indexOf("file/")+5,uri.lastIndexOf("/"));
}
//*/
String ref = request.getHeader("referer");
/// Parse les donn�es
DocumentBuilderFactory documentBuilderFactory =DocumentBuilderFactory.newInstance();
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
InputSource is = new InputSource(new StringReader("<node>"+data+"</node>"));
Document doc = documentBuilder.parse(is);
DOMImplementationLS impl = (DOMImplementationLS)doc.getImplementation().getFeature("LS", "3.0");
LSSerializer serial = impl.createLSSerializer();
serial.getDomConfig().setParameter("xml-declaration", false);
/// Trouve le bon noeud
XPath xPath = XPathFactory.newInstance().newXPath();
/// Either we have a fileid per language
// String filterRes = "//fileid[@lang='"+lang+"']";
String filterRes = "//*[local-name()='fileid' and @lang='"+lang+"']";
NodeList nodelist = (NodeList) xPath.compile(filterRes).evaluate(doc, XPathConstants.NODESET);
String resolve = "";
if( nodelist.getLength() != 0 )
{
Element fileNode = (Element) nodelist.item(0);
resolve = fileNode.getTextContent();
}
/// Or just a single one shared
if( "".equals(resolve) )
{
response.setStatus(404);
response.getOutputStream().close();
return;
}
// String filterName = "//filename[@lang='"+lang+"']";
String filterName = "//*[local-name()='filename' and @lang='"+lang+"']";
NodeList textList = (NodeList) xPath.compile(filterName).evaluate(doc, XPathConstants.NODESET);
String filename = "";
if( textList.getLength() != 0 )
{
Element fileNode = (Element) textList.item(0);
filename = fileNode.getTextContent();
}
// String filterType = "//type[@lang='"+lang+"']";
String filterType = "//*[local-name()='type' and @lang='"+lang+"']";
textList = (NodeList) xPath.compile(filterType).evaluate(doc, XPathConstants.NODESET);
String type = "";
if( textList.getLength() != 0 )
{
Element fileNode = (Element) textList.item(0);
type = fileNode.getTextContent();
}
/*
String filterSize = "//size[@lang='"+lang+"']";
textList = (NodeList) xPath.compile(filterName).evaluate(doc, XPathConstants.NODESET);
String filesize = "";
if( textList.getLength() != 0 )
{
Element fileNode = (Element) textList.item(0);
filesize = fileNode.getTextContent();
}
//*/
System.out.println("!!! RESOLVE: "+resolve);
/// Envoie de la requ�te au servlet de fichiers
// http://localhost:8080/MiniRestFileServer/user/claudecoulombe/file/a8e0f07f-671c-4f6a-be6c-9dba12c519cf/ptype/sql
/// TODO: Ne plus avoir besoin du switch
String urlTarget = server + "/" + resolve;
if( "T".equals(size) )
urlTarget = urlTarget + "/thumb";
// String urlTarget = "http://"+ server + "/user/" + resolve +"/"+ lang + "/ptype/fs";
HttpURLConnection connection = CreateConnection( urlTarget, request );
connection.connect();
InputStream input = connection.getInputStream();
String sizeComplete = connection.getHeaderField("Content-Length");
int completeSize = Integer.parseInt(sizeComplete);
response.setContentLength(completeSize);
response.setContentType(type);
response.setHeader("Content-Disposition", "attachment; filename=\"" + filename + "\"");
ServletOutputStream output = response.getOutputStream();
byte[] buffer = new byte[0x100000];
int totalRead = 0;
int bytesRead = -1;
while ((bytesRead = input.read(buffer,0,0x100000)) != -1 || totalRead < completeSize) {
output.write(buffer, 0, bytesRead);
totalRead += bytesRead;
}
// IOUtils.copy(input, output);
// IOUtils.closeQuietly(output);
output.flush();
output.close();
input.close();
connection.disconnect();
}
catch( RestWebApplicationException e )
{
logger.error(e.getMessage());
e.printStackTrace();
}
catch(Exception e){
logger.error(e.getMessage());
logger.error(e.toString()+" -> "+e.getLocalizedMessage());
e.printStackTrace();
//wadbackend.WadUtilities.appendlogfile(logFName, "GETfile: error"+e);
}
finally
{
try
{
if( c != null ) c.close();
}
catch(Exception e){
ServletOutputStream out = response.getOutputStream();
out.println("Erreur dans doGet: " +e);
out.close();
}
// dataProvider.disconnect();
request.getInputStream().close();
response.getOutputStream().close();
}
}
HttpURLConnection CreateConnection( String url, HttpServletRequest request ) throws MalformedURLException, IOException
{
/// Create connection
URL urlConn = new URL(url);
HttpURLConnection connection = (HttpURLConnection) urlConn.openConnection();
connection.setDoOutput(true);
connection.setUseCaches(false); /// We don't want to cache data
connection.setInstanceFollowRedirects(false); /// Let client follow any redirection
String method = request.getMethod();
connection.setRequestMethod(method);
String context = request.getContextPath();
connection.setRequestProperty("app", context);
/// Transfer headers
String key = "";
String value = "";
Enumeration<String> header = request.getHeaderNames();
while( header.hasMoreElements() )
{
key = header.nextElement();
value = request.getHeader(key);
connection.setRequestProperty(key, value);
}
return connection;
}
void InitAnswer( HttpURLConnection connection, HttpServletResponse response, String referer ) throws MalformedURLException, IOException
{
String ref = null;
if( referer != null )
{
int first = referer.indexOf('/', 7);
int last = referer.lastIndexOf('/');
ref = referer.substring(first, last);
}
response.setContentType(connection.getContentType());
response.setStatus(connection.getResponseCode());
response.setContentLength(connection.getContentLength());
/// Transfer headers
Map<String, List<String>> headers = connection.getHeaderFields();
int size=headers.size();
for( int i=1; i<size; ++i )
{
String key = connection.getHeaderFieldKey(i);
String value = connection.getHeaderField(i);
// response.setHeader(key, value);
response.addHeader(key, value);
}
/// Deal with correct path with set cookie
List<String> setValues = headers.get("Set-Cookie");
if( setValues != null )
{
String setVal = setValues.get(0);
int pathPlace = setVal.indexOf("Path=");
if( pathPlace > 0 )
{
setVal = setVal.substring(0, pathPlace+5); // Some assumption, may break
setVal = setVal+ref;
response.setHeader("Set-Cookie", setVal);
}
}
}
void RetrieveAnswer( HttpURLConnection connection, HttpServletResponse response, String referer ) throws MalformedURLException, IOException
{
/// Receive answer
InputStream in;
try
{
in = connection.getInputStream();
}
catch (Exception e)
{
System.out.println(e.toString());
in = connection.getErrorStream();
}
InitAnswer(connection, response, referer);
/// Write back data
DataInputStream stream = new DataInputStream(in);
byte[] buffer = new byte[1024];
int size;
ServletOutputStream out=null;
try
{
out = response.getOutputStream();
while( (size = stream.read(buffer,0,buffer.length)) != -1 )
out.write(buffer, 0, size);
}
catch (Exception e)
{
System.out.println(e.toString());
System.out.println("Writing messed up!");
}
finally
{
in.close();
out.flush(); // close() should flush already, but Tomcat 5.5 doesn't
out.close();
}
}
// [username, ?]
String[] processCookie( Cookie[] cookies )
{
String login=null;
String[] ret = {login};
if( cookies == null ) return ret;
for( int i=0; i<cookies.length; ++i )
{
Cookie cookie = cookies[i];
String name = cookie.getName();
if( "user".equals(name) || "useridentifier".equals(name) )
login = cookie.getValue();
}
ret[0] = login;
return ret;
}
}