* SSI work with jetty, it's pretty usable now

pull/1/head
Florian Richter 14 years ago
parent 2d2df64870
commit ed3bcfaf71

@ -0,0 +1,87 @@
package net.yacy.http;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import javax.servlet.ServletException;
import javax.servlet.ServletOutputStream;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import javax.servlet.http.HttpServletResponseWrapper;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.HandlerWrapper;
/**
* jetty http handler:
* Handles Server-side Includes, used for trickling display of search results
*/
public abstract class ContentModHandler extends HandlerWrapper implements Handler, HandlerContainer {
public ContentModHandler() {
super();
}
public ContentModHandler(Handler h) {
super();
this.setHandler(h);
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
// wrap response
ContentModResponseWrapper wrapped_response = new ContentModResponseWrapper(response);
super.handle(target, baseRequest, request, wrapped_response);
wrapped_response.commit(this, request, response);
}
protected abstract void doContentMod(byte[] in, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException ;
private class ContentModResponseWrapper extends HttpServletResponseWrapper {
private HttpServletResponse wrappedResponse;
private ByteArrayServletOutputStream wrappedOutputStream = new ByteArrayServletOutputStream();
public ContentModResponseWrapper(HttpServletResponse response) {
super(response);
wrappedResponse = response;
}
@Override
public ServletOutputStream getOutputStream() throws IOException {
return wrappedOutputStream;
}
public void commit(ContentModHandler cmh, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
cmh.doContentMod(wrappedOutputStream.getBuffer(), request, response);
}
}
private class ByteArrayServletOutputStream extends ServletOutputStream {
private ByteArrayOutputStream buffer = new ByteArrayOutputStream();
public ByteArrayServletOutputStream() {
super();
}
@Override
public void write(int b) throws IOException {
buffer.write(b);
}
public void write(byte[] b) throws IOException {
buffer.write(b);
}
public byte[] getBuffer() {
return buffer.toByteArray();
}
}
}

@ -2,11 +2,15 @@ package net.yacy.http;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Server;
import org.eclipse.jetty.server.handler.ContextHandler;
import org.eclipse.jetty.server.handler.DefaultHandler;
import org.eclipse.jetty.server.handler.HandlerList;
import org.eclipse.jetty.server.handler.ResourceHandler;
import org.eclipse.jetty.server.nio.SelectChannelConnector;
/**
* interface to embedded jetty http server
*/
public class HttpServer {
private Server server = new Server();
@ -27,8 +31,12 @@ public class HttpServer {
resource_handler.setResourceBase("htroot/");
ContextHandler context = new ContextHandler();
context.setContextPath("/");
context.setHandler(new SSIHandler(new TemplateHandler()));
HandlerList handlers = new HandlerList();
handlers.setHandlers(new Handler[] { new TemplateHandler(), resource_handler, new DefaultHandler() });
handlers.setHandlers(new Handler[] { context, resource_handler, new DefaultHandler() });
server.setHandler(handlers);
}

@ -0,0 +1,81 @@
/**
* SSIHandler
* Copyright 2011 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
* First released 13.04.2011 at http://yacy.net
*
* $LastChangedDate$
* $LastChangedRevision$
* $LastChangedBy$
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2.1 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public License
* along with this program in the file lgpl21.txt
* If not, see <http://www.gnu.org/licenses/>.
*/
package net.yacy.http;
import java.io.IOException;
import java.io.OutputStream;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HandlerContainer;
import net.yacy.kelondro.util.ByteBuffer;
public class SSIHandler extends ContentModHandler implements Handler, HandlerContainer {
public SSIHandler(Handler h) {
super(h);
}
@Override
protected void doContentMod(final byte[] in, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException {
ByteBuffer buffer = new ByteBuffer(in);
OutputStream out = response.getOutputStream();
int off = 0; // starting offset
int p = buffer.indexOf("<!--#".getBytes(), off);
int q;
while (p >= 0) {
q = buffer.indexOf("-->".getBytes(), p + 10);
out.write(in, off, p - off);
out.flush();
parseSSI(buffer, p, request, response);
off = q + 3;
p = buffer.indexOf("<!--#".getBytes(), off);
}
out.write(in, off, in.length - off);
out.flush();
}
private static void parseSSI(final ByteBuffer in, final int off, HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
if (in.startsWith("<!--#include virtual=\"".getBytes(), off)) {
final int q = in.indexOf("\"".getBytes(), off + 22);
if (q > 0) {
final String path = in.toString(off + 22, q - off - 22);
try {
RequestDispatcher dispatcher = request.getRequestDispatcher("/"+path);
dispatcher.include(request, response);
} catch (Exception e) {
e.printStackTrace();
throw new ServletException();
}
}
}
}
}

@ -28,13 +28,12 @@ import net.yacy.kelondro.util.FileUtils;
import net.yacy.kelondro.util.MemoryControl;
import net.yacy.visualization.RasterPlotter;
import org.eclipse.jetty.http.MimeTypes;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.HttpConnection;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
import de.anomic.data.MimeTable;
import de.anomic.http.server.HTTPDemon;
import de.anomic.http.server.TemplateEngine;
import de.anomic.search.Switchboard;
import de.anomic.server.serverClassLoader;
@ -44,8 +43,14 @@ import de.anomic.server.serverSwitch;
import de.anomic.server.servletProperties;
import de.anomic.yacy.yacyBuildProperties;
import de.anomic.yacy.yacySeed;
import de.anomic.yacy.graphics.EncodedImage;
public class TemplateHandler extends AbstractHandler {
/**
* jetty http handler:
*
* Handles classic yacy servlets with templates
*/
public class TemplateHandler extends AbstractHandler implements Handler {
private String htLocalePath = "DATA/LOCALE/htroot";
private String htDefaultPath = "htroot";
@ -57,8 +62,6 @@ public class TemplateHandler extends AbstractHandler {
private ConcurrentHashMap<File, SoftReference<TemplateCacheEntry>> templateCache = null;
private ConcurrentHashMap<File, SoftReference<Method>> templateMethodCache = null;
private MimeTypes mimeTypes = new MimeTypes();
@Override
protected void doStart() throws Exception {
super.doStart();
@ -132,10 +135,10 @@ public class TemplateHandler extends AbstractHandler {
}
} catch (final ClassNotFoundException e) {
Log.logSevere("HTTPDFileHandler", "class " + classFile + " is missing:" + e.getMessage());
Log.logSevere("TemplateHandler", "class " + classFile + " is missing:" + e.getMessage());
throw new InvocationTargetException(e, "class " + classFile + " is missing:" + e.getMessage());
} catch (final NoSuchMethodException e) {
Log.logSevere("HTTPDFileHandler", "method 'respond' not found in class " + classFile + ": " + e.getMessage());
Log.logSevere("TemplateHandler", "method 'respond' not found in class " + classFile + ": " + e.getMessage());
throw new InvocationTargetException(e, "method 'respond' not found in class " + classFile + ": " + e.getMessage());
}
return m;
@ -177,7 +180,6 @@ public class TemplateHandler extends AbstractHandler {
String targetExt = target.substring(target.lastIndexOf('.') + 1, target.length());
if ((targetClass != null)) {
@SuppressWarnings("unchecked")
serverObjects args = new serverObjects();
@SuppressWarnings("unchecked")
Enumeration<String> argNames = request.getParameterNames();
@ -204,36 +206,32 @@ public class TemplateHandler extends AbstractHandler {
throw new ServletException();
}
if ( tmp instanceof RasterPlotter || tmp instanceof EncodedImage || tmp instanceof Image) {
ByteBuffer result = null;
if (tmp instanceof RasterPlotter) {
final RasterPlotter yp = (RasterPlotter) tmp;
// send an image to client
final String mimeType = MimeTable.ext2mime(targetExt, "text/html");
final ByteBuffer result = RasterPlotter.exportImage(yp.getImage(), "png");
response.setContentType(mimeType);
response.setContentLength(result.length());
response.setStatus(HttpServletResponse.SC_OK);
result.writeTo(response.getOutputStream());
// we handled this request, break out of handler chain
Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest();
base_request.setHandled(true);
return;
result = RasterPlotter.exportImage(yp.getImage(), "png");
}
if (tmp instanceof EncodedImage) {
final EncodedImage yp = (EncodedImage) tmp;
result = yp.getImage();
}
if (tmp instanceof Image) {
final Image i = (Image) tmp;
final String mimeType = MimeTable.ext2mime(targetExt, "text/html");
// generate an byte array from the generated image
int width = i.getWidth(null); if (width < 0) width = 96; // bad hack
int height = i.getHeight(null); if (height < 0) height = 96; // bad hack
final BufferedImage bi = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
bi.createGraphics().drawImage(i, 0, 0, width, height, null);
final ByteBuffer result = RasterPlotter.exportImage(bi, targetExt);
result = RasterPlotter.exportImage(bi, targetExt);
}
final String mimeType = MimeTable.ext2mime(targetExt, "text/html");
response.setContentType(targetExt);
response.setContentLength(result.length());
response.setStatus(HttpServletResponse.SC_OK);

Loading…
Cancel
Save