/**
* Copyright 2006 OCLC Online Computer Library Center 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.
*/
package gov.lanl.adore.djatoka.openurl;
import info.openurl.oom.OpenURLRequest;
import info.openurl.oom.OpenURLRequestProcessor;
import info.openurl.oom.OpenURLResponse;
import info.openurl.oom.Transport;
import info.openurl.oom.config.OpenURLConfig;
import gov.lanl.util.AccessManager;
import java.io.InputStream;
import java.io.OutputStream;
import java.net.SocketException;
import java.net.URL;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import javax.servlet.ServletConfig;
import javax.servlet.ServletException;
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 org.apache.log4j.Logger;
/**
* OpenURL Servlet - Added referrer and requester to Context Object
*
* @author Jeffrey A. Young
* @author Ryan Chute
*/
public class OpenURLServlet extends HttpServlet {
static Logger logger = Logger.getLogger(OpenURLServlet.class);
/**
* Initial version
*/
private static final long serialVersionUID = 1L;
private OpenURLConfig openURLConfig;
private OpenURLRequestProcessor processor;
private Transport[] transports;
private AccessManager am;
public void init(ServletConfig config) throws ServletException {
super.init(config);
try {
// load the configuration file from the classpath
openURLConfig = new org.oclc.oomRef.config.OpenURLConfig(config);
// Construct the configured transports
transports = openURLConfig.getTransports();
// Construct a processor
processor = openURLConfig.getProcessor();
ClassLoader cl = OpenURLServlet.class.getClassLoader();
java.net.URL url = cl.getResource("access.txt");
if (url != null)
am = new AccessManager(url.getFile());
} catch (Exception e) {
e.printStackTrace();
throw new ServletException(e.getMessage(), e);
}
}
/**
* Extends HttpServlet Request to build OpenURL Request and Context Objects.
* The req.getHeader("referer") is used to add an OpenURL ReferringEntities
* and req.getRemoteAddr() is used to add a Requester.
*/
protected void doGet(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
try {
// Try each Transport until someone takes responsibility
OpenURLRequest openURLRequest = null;
for (int i=0; openURLRequest == null && i<transports.length; ++i) {
openURLRequest = transports[i].toOpenURLRequest(processor, req);
}
if (openURLRequest == null) {
resp.sendError(HttpServletResponse.SC_BAD_REQUEST,
"Invalid Request");
return;
}
// 2009-05-06: rchute Add AccessManager Support
if (am != null) {
try {
String url = ((java.net.URI) openURLRequest.getContextObjects()[0].getReferent().getDescriptors()[0]).toASCIIString();
if (url.startsWith("http") || url.startsWith("ftp")) {
if (!am.checkAccess(new URL(url).getHost())){
int status = HttpServletResponse.SC_FORBIDDEN;
resp.sendError(status);
return;
}
}
} catch (Exception e) {
logger.error(e);
}
}
// rchute: Add referrer for possible extension processing
if (req.getHeader("referer") != null)
openURLRequest.getContextObjects()[0].getReferringEntities()[0].addDescriptor(req.getHeader("referer"));
// rchute: Add requester for possible extension processing
openURLRequest.getContextObjects()[0].getRequesters()[0].addDescriptor(req.getRemoteAddr());
// Process the ContextObjects
OpenURLResponse result = processor.resolve(openURLRequest);
// See if anyone handled the request
int status;
if (result == null) {
status = HttpServletResponse.SC_NOT_FOUND;
} else {
status = result.getStatus();
Cookie[] cookies = result.getCookies();
if (cookies != null) {
for (int i=0; i< cookies.length; ++i) {
resp.addCookie(cookies[i]);
}
}
Map sessionMap = result.getSessionMap();
if (sessionMap != null) {
HttpSession session = req.getSession(true);
Iterator iter = sessionMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Entry) iter.next();
session.setAttribute((String) entry.getKey(), entry.getValue());
}
}
Map headerMap = result.getHeaderMap();
if (headerMap != null) {
Iterator iter = headerMap.entrySet().iterator();
while (iter.hasNext()) {
Map.Entry entry = (Entry) iter.next();
resp.setHeader((String) entry.getKey(),
(String) entry.getValue());
}
}
}
// Allow the processor to generate a variety of response types
switch (status) {
case HttpServletResponse.SC_MOVED_TEMPORARILY:
resp.sendRedirect(
resp.encodeRedirectURL(
result.getRedirectURL()));
break;
case HttpServletResponse.SC_SEE_OTHER:
case HttpServletResponse.SC_MOVED_PERMANENTLY:
resp.setStatus(status);
resp.setHeader("Location", result.getRedirectURL());
break;
case HttpServletResponse.SC_NOT_FOUND:
resp.sendError(status);
break;
default:
OutputStream out = resp.getOutputStream();
resp.setStatus(status);
resp.setContentType(result.getContentType());
InputStream is = result.getInputStream();
byte[] bytes = new byte[1024];
int len;
while ((len = is.read(bytes)) != -1) {
out.write(bytes, 0, len);
}
out.close();
break;
}
} catch (SocketException e) {
logger.error(e);
} catch (Throwable e) {
logger.debug(e);
//throw new ServletException(e.getMessage(), e);
resp.setStatus(HttpServletResponse.SC_INTERNAL_SERVER_ERROR);
}
}
protected void doPost(HttpServletRequest req, HttpServletResponse resp)
throws ServletException {
doGet(req, resp);
}
}