diff --git a/lib/jetty-servlet-7.3.0.v20110203.jar b/lib/jetty-servlet-7.3.0.v20110203.jar new file mode 100644 index 000000000..0097f0039 Binary files /dev/null and b/lib/jetty-servlet-7.3.0.v20110203.jar differ diff --git a/lib/jetty-servlets-7.3.0.v20110203.jar b/lib/jetty-servlets-7.3.0.v20110203.jar new file mode 100644 index 000000000..6ea9b31aa Binary files /dev/null and b/lib/jetty-servlets-7.3.0.v20110203.jar differ diff --git a/source/net/yacy/http/HttpServer.java b/source/net/yacy/http/HttpServer.java index 920343c23..d9a057845 100644 --- a/source/net/yacy/http/HttpServer.java +++ b/source/net/yacy/http/HttpServer.java @@ -74,7 +74,7 @@ public class HttpServer { HandlerList handlers = new HandlerList(); handlers.setHandlers(new Handler[] - { domainHandler, new RewriteHandler(), + { domainHandler, new ProxyHandler(), new RewriteHandler(), new SSIHandler(new TemplateHandler()), resource_handler, new DefaultHandler() }); diff --git a/source/net/yacy/http/ProxyHandler.java b/source/net/yacy/http/ProxyHandler.java index d64fe425e..b47425f5a 100644 --- a/source/net/yacy/http/ProxyHandler.java +++ b/source/net/yacy/http/ProxyHandler.java @@ -26,27 +26,113 @@ package net.yacy.http; import java.io.IOException; +import java.io.OutputStream; +import java.net.SocketException; +import java.util.Enumeration; +import java.util.LinkedList; +import java.util.List; import javax.servlet.ServletException; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; +import net.yacy.cora.protocol.HeaderFramework; +import net.yacy.cora.protocol.RequestHeader; import net.yacy.cora.protocol.http.HTTPClient; +import net.yacy.kelondro.util.FileUtils; +import org.apache.http.Header; +import org.apache.http.HttpResponse; 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; public class ProxyHandler extends AbstractHandler implements Handler { + + private List localVirtualHostNames; + + protected void doStart() { + localVirtualHostNames = new LinkedList(); + localVirtualHostNames.add("localpeer"); + localVirtualHostNames.add("localhost"); + } + + private RequestHeader convertHeaderFromJetty(HttpServletRequest request) { + RequestHeader result = new RequestHeader(); + @SuppressWarnings("unchecked") + Enumeration headerNames = request.getHeaderNames(); + while(headerNames.hasMoreElements()) { + String headerName = headerNames.nextElement(); + @SuppressWarnings("unchecked") + Enumeration headers = request.getHeaders(headerName); + while(headers.hasMoreElements()) { + String header = headers.nextElement(); + result.add(headerName, header); + } + } + return result; + } + + private void convertHeaderToJetty(HttpResponse in, HttpServletResponse out) { + for(Header h: in.getAllHeaders()) { + out.addHeader(h.getName(), h.getValue()); + } + } + + private void cleanResponseHeader(HttpResponse headers) { + headers.removeHeaders("Content-Encoding"); + headers.removeHeaders("Content-Length"); + } @Override public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException { - final HTTPClient client = new HTTPClient(); - int timeout = 10; + String host = request.getHeader("Host"); + if(host == null) return; // no proxy request, continue processing by handlers + int hostSplitPos = host.indexOf(':'); + String hostOnly = hostSplitPos<0 ? host : host.substring(0, hostSplitPos); + + if(localVirtualHostNames.contains(hostOnly)) return; // no proxy request, continue processing by handlers + + RequestHeader proxyHeaders = convertHeaderFromJetty(request); + proxyHeaders.add(RequestHeader.VIA, "YaCy"); + proxyHeaders.remove(RequestHeader.KEEP_ALIVE); + proxyHeaders.remove(RequestHeader.CONTENT_LENGTH); + + final HTTPClient client = new HTTPClient(); + int timeout = 60000; client.setTimout(timeout); - //client.setHeader(); - client.setRedirecting(false); + client.setHeader(proxyHeaders.entrySet()); + client.setRedirecting(false); + // send request + try { + String queryString = request.getQueryString()!=null ? "?" + request.getQueryString() : ""; + if (request.getMethod().equals("GET")) { + client.GET(request.getRequestURL().toString() + queryString); + } else if (request.getMethod().equals("POST")) { + client.POST(request.getRequestURL().toString() + queryString, request.getInputStream(), request.getContentLength()); + } else if (request.getMethod().equals("HEAD")) { + client.HEADResponse(request.getRequestURL().toString() + queryString); + } else { + throw new ServletException("Unsupported Request Method"); + } + HttpResponse responseHeader = client.getHttpResponse(); + cleanResponseHeader(responseHeader); + convertHeaderToJetty(responseHeader, response); + //response.setContentType(responseHeader.getFirstHeader(HeaderFramework.CONTENT_TYPE).getValue()); + response.setStatus(responseHeader.getStatusLine().getStatusCode()); + + client.writeTo(response.getOutputStream()); + } catch(SocketException se) { + throw new ServletException("Socket Exception: " + se.getMessage()); + } finally { + client.finish(); + } + + // we handled this request, break out of handler chain + Request base_request = (request instanceof Request) ? (Request)request:HttpConnection.getCurrentConnection().getRequest(); + base_request.setHandled(true); } } diff --git a/source/net/yacy/http/YacyDomainHandler.java b/source/net/yacy/http/YacyDomainHandler.java index 27fc8c6be..90790893e 100644 --- a/source/net/yacy/http/YacyDomainHandler.java +++ b/source/net/yacy/http/YacyDomainHandler.java @@ -26,6 +26,8 @@ package net.yacy.http; import java.io.IOException; +import java.util.Enumeration; +import java.util.Vector; import javax.servlet.RequestDispatcher; import javax.servlet.ServletException; @@ -82,10 +84,30 @@ public class YacyDomainHandler extends AbstractHandler implements Handler { return newServerName; } + @Override public int getServerPort() { return newServerPort; } + @Override + public String getHeader(String name) { + if(name.equals("Host")) { + return newServerName + (newServerPort!=80 ? ":"+newServerPort : ""); + } + return super.getHeader(name); + } + + @SuppressWarnings("unchecked") + @Override + public Enumeration getHeaders(String name) { + if(name.equals("Host")) { + Vector header = new Vector(); + header.add(newServerName + (newServerPort!=80 ? ":"+newServerPort : "")); + return header.elements(); + } + return super.getHeaders(name); + } + } }