/////////////////////////////////////////////////////////////////////////////
// Copyright (c) 1998, California Institute of Technology.
// ALL RIGHTS RESERVED. U.S. Government Sponsorship acknowledged.
//
// Please read the full copyright notice in the file COPYRIGHT
// in this directory.
//
// Author: Jake Hamby, NASA/Jet Propulsion Laboratory
// Jake.Hamby@jpl.nasa.gov
/////////////////////////////////////////////////////////////////////////////
package dods.servlet.jake;
import dods.dap.*;
import java.io.*;
import javax.servlet.*;
import javax.servlet.http.*;
/**
* Proxy servlet. This servlet searches its parameter list for a server URL
* which matches the first component of the path, and if it finds one,
* acts as a proxy for DODS requests on the remote server. This can be used
* by DODS applet clients to bypass the default applet security restrictions,
* which only allow an applet to connect to the host from which they are
* downloaded.
* <P>
* Note: to use this servlet, you'll need to add servlet parameters of the form:
* <code>manta=http://manta.jpl.nasa.gov/cgi-bin/nph-hdf</code>
* <P>
* This will convert a URL of the form:
* <BR>
* <code>http://machine/servlets/proxy/manta/foo.hdf</code>
* <BR>
* to:
* <BR>
* <code>http://manta.jpl.nasa.gov/cgi-bin/nph-hdf/foo.hdf</code>
*
* @version $Revision: 1.2 $
* @author jehamby
* @see DispatchServlet
*/
public class ProxyServlet extends DispatchServlet {
/**
* Get the DODS DAS.
* @param req the HttpServletRequest to use
* @param res the HttpServletResponse to use
* @param path the DODS file path in the URL
* @param ce the DODS constraint expression in the URL
* @exception IOException if detected when handling the request
* @exception ServletException if the request could not be handled
*/
public void getDAS(HttpServletRequest req, HttpServletResponse res, String path, String ce)
throws ServletException, IOException
{
ServletOutputStream out = res.getOutputStream();
try {
DConnect con = proxyConnect(path, ce);
DAS das = con.getDAS();
das.print(out);
}
catch (DODSException e) {
res.setHeader("Content-Description", "dods_error");
e.print(out);
}
catch (Exception e) {
res.setHeader("Content-Description", "dods_error");
DODSException de = new DODSException(DODSException.UNKNOWN_ERROR, e.getMessage());
de.print(out);
}
}
/**
* Get the DODS DDS.
* @param req the HttpServletRequest to use
* @param res the HttpServletResponse to use
* @param path the DODS file path in the URL
* @param ce the DODS constraint expression in the URL
* @exception IOException if detected when handling the request
* @exception ServletException if the request could not be handled
*/
public void getDDS(HttpServletRequest req, HttpServletResponse res, String path, String ce)
throws ServletException, IOException
{
ServletOutputStream out = res.getOutputStream();
try {
DConnect con = proxyConnect(path, ce);
DDS dds = con.getDDS();
dds.print(out);
}
catch (DODSException e) {
res.setHeader("Content-Description", "dods_error");
e.print(out);
}
catch (Exception e) {
res.setHeader("Content-Description", "dods_error");
DODSException de = new DODSException(DODSException.UNKNOWN_ERROR, e.getMessage());
de.print(out);
}
}
/**
* Get the DODS Dataset.
* @param req the HttpServletRequest to use
* @param res the HttpServletResponse to use
* @param path the DODS file path in the URL
* @param ce the DODS constraint expression in the URL
* @param compress whether to compress the DODS output
* @exception IOException if detected when handling the request
* @exception ServletException if the request could not be handled
*/
public void getData(HttpServletRequest req, HttpServletResponse res, String path, String ce, boolean compress)
throws ServletException, IOException
{
ServletOutputStream out = res.getOutputStream();
try {
DConnect con = proxyConnect(path, ce);
// XXX in the future, we could use StatusUI to abort downloads which
// take too long
DataDDS dds = con.getData(null);
dds.externalize(out, compress, false);
}
catch (DODSException e) {
res.setContentType("text/plain");
res.setHeader("Content-Description", "dods_error");
res.setHeader("Content-Encoding", "none");
e.print(out);
}
catch (Exception e) {
res.setHeader("Content-Description", "dods_error");
DODSException de = new DODSException(DODSException.UNKNOWN_ERROR, e.getMessage());
de.print(out);
}
}
/**
* Establish a proxy connection to the remote server. Note: this
* implementation is naive and doesn't attempt to cache frequently accessed
* URL's. If you want to add this feature, this is the method in which to
* add it.
*
* @param path the DODS file path in the URL
* @param ce the DODS constraint expression in the URL
* @return a new DConnect object
*/
private DConnect proxyConnect(String path, String ce) throws DODSException {
// strip off first component of path and search for it in parameters
int secondSlashIndex = path.indexOf('/', 1);
String server = path.substring(1, secondSlashIndex);
String newPath = path.substring(secondSlashIndex); // include leading slash
java.util.Enumeration names = getInitParameterNames();
while(names.hasMoreElements()) {
String paramName = (String)names.nextElement();
if(paramName.equals(server)) {
// get initial part of URL (including http://) from parameter
String url = getInitParameter(paramName) + newPath + "?" + ce;
try {
DConnect con = new DConnect(url, true);
return con;
}
catch (FileNotFoundException e) {
throw new DODSException(DODSException.NO_SUCH_FILE, "file not found: " + url);
}
}
}
throw new DODSException(DODSException.NO_SUCH_FILE, "proxy path not found: " + path);
}
}