blob: 5df86c3d9e27920f14c886a7b493d1fb746f011f [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2000, 2004 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
*******************************************************************************/
package org.eclipse.help.internal.webapp.servlet;
import java.io.*;
import java.net.*;
import java.util.*;
import javax.servlet.*;
import javax.servlet.http.*;
import org.eclipse.help.internal.base.*;
import org.eclipse.help.internal.protocols.*;
import org.eclipse.help.internal.webapp.data.*;
/**
* Performs transfer of data from eclipse to a jsp/servlet
*/
public class EclipseConnector {
//private ServletContext context;
private static final String errorPageBegin = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.0 Transitional//EN\">\n" //$NON-NLS-1$
+ "<html><head>\n" //$NON-NLS-1$
+ "<meta http-equiv=\"Content-Type\" content=\"text/html; charset=UTF-8\">\n" //$NON-NLS-1$
+ "</head>\n" //$NON-NLS-1$
+ "<body><p>\n"; //$NON-NLS-1$
private static final String errorPageEnd = "</p></body></html>"; //$NON-NLS-1$
private static final IFilter filters[] = new IFilter[]{
new HighlightFilter(), new FramesetFilter(), new InjectionFilter()};
/**
* Constructor.
*/
public EclipseConnector(ServletContext context) {
//this.context = context;
}
public void transfer(HttpServletRequest req, HttpServletResponse resp)
throws IOException {
try {
String url = getURL(req);
if (url == null)
return;
if (url.toLowerCase(Locale.ENGLISH).startsWith("file:/") //$NON-NLS-1$
|| url.toLowerCase(Locale.ENGLISH).startsWith("jar:file:/")) { //$NON-NLS-1$
int i = url.indexOf('?');
if (i != -1)
url = url.substring(0, i);
// ensure the file is only accessed from a local installation
if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER
|| !UrlUtil.isLocalRequest(req)) {
return;
}
} else {
// enable activities matching url
// HelpBasePlugin.getActivitySupport().enableActivities(url);
url = "help:" + url; //$NON-NLS-1$
}
URLConnection con = openConnection(url, req, resp);
resp.setContentType(con.getContentType());
long maxAge = 0;
try {
// getExpiration() throws NullPointerException when URL is
// jar:file:...
long expiration = con.getExpiration();
maxAge = (expiration - System.currentTimeMillis()) / 1000;
if (maxAge < 0)
maxAge = 0;
} catch (Exception e) {
}
resp.setHeader("Cache-Control", "max-age=" + maxAge); //$NON-NLS-1$ //$NON-NLS-2$
InputStream is;
try {
is = con.getInputStream();
} catch (IOException ioe) {
if (url.toLowerCase(Locale.ENGLISH).endsWith("htm") //$NON-NLS-1$
|| url.toLowerCase(Locale.ENGLISH).endsWith("html")) { //$NON-NLS-1$
String error = errorPageBegin
+ ServletResources.getString("noTopic", req) //$NON-NLS-1$
+ errorPageEnd;
is = new ByteArrayInputStream(error.getBytes("UTF8")); //$NON-NLS-1$
} else {
return;
}
}
OutputStream out = resp.getOutputStream();
for (int i = 0; i < filters.length; i++) {
out = filters[i].filter(req, out);
}
transferContent(is, out);
out.flush();
is.close();
} catch (Exception e) {
//e.printStackTrace();
}
}
/**
* Write the body to the response
*/
private void transferContent(InputStream inputStream, OutputStream out)
throws IOException {
try {
// Prepare the input stream for reading
BufferedInputStream dataStream = new BufferedInputStream(
inputStream);
// Create a fixed sized buffer for reading.
// We could create one with the size of availabe data...
byte[] buffer = new byte[4096];
int len = 0;
while (true) {
len = dataStream.read(buffer); // Read file into the byte array
if (len == -1)
break;
out.write(buffer, 0, len);
}
} catch (Exception e) {
// e.printStackTrace();
}
}
/**
* Gets content from the named url (this could be and eclipse defined url)
*/
private URLConnection openConnection(String url,
HttpServletRequest request, HttpServletResponse response)
throws Exception {
//System.out.println("help content for: " + url);
URLConnection con = null;
if (BaseHelpSystem.getMode() == BaseHelpSystem.MODE_INFOCENTER) {
// it is an infocentre, add client locale to url
String locale = UrlUtil.getLocale(request, response);
if (url.indexOf('?') >= 0) {
url = url + "&lang=" + locale; //$NON-NLS-1$
} else {
url = url + "?lang=" + locale; //$NON-NLS-1$
}
}
// URL helpURL = new URL(url);
URL helpURL;
if (url.startsWith("help:")) { //$NON-NLS-1$
helpURL = new URL("help", //$NON-NLS-1$
null, -1, url.substring("help:".length()), //$NON-NLS-1$
HelpURLStreamHandler.getDefault());
} else {
if (url.startsWith("jar:")) {
// fix for bug 83929
int excl = url.indexOf("!/");
String jar = url.substring(0, excl);
String path = url.length() > excl + 2 ? url.substring(excl + 2)
: "";
url = jar.replaceAll("!", "%21") + "!/"
+ path.replaceAll("!", "%21");
}
helpURL = new URL(url);
}
String protocol = helpURL.getProtocol();
if (!("help".equals(protocol) //$NON-NLS-1$
|| "file".equals(protocol) //$NON-NLS-1$
|| "jar".equals(protocol))) { //$NON-NLS-1$
throw new IOException();
}
con = helpURL.openConnection();
con.setAllowUserInteraction(false);
con.setDoInput(true);
con.connect();
return con;
}
/**
* Extracts the url from a request
*/
private String getURL(HttpServletRequest req) {
String query = ""; //$NON-NLS-1$
boolean firstParam = true;
for (Enumeration params = req.getParameterNames(); params
.hasMoreElements();) {
String param = (String) params.nextElement();
String[] values = req.getParameterValues(param);
if (values == null)
continue;
for (int i = 0; i < values.length; i++) {
if (firstParam) {
query += "?" + param + "=" + values[i]; //$NON-NLS-1$ //$NON-NLS-2$
firstParam = false;
} else
query += "&" + param + "=" + values[i]; //$NON-NLS-1$ //$NON-NLS-2$
}
}
// the request contains the eclipse url help: or search:
String url = req.getPathInfo() + query;
if (url.startsWith("/")) //$NON-NLS-1$
url = url.substring(1);
return url;
}
}