// // ProxyHandler // Copyright 2004 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany // Copyright 2011 by Florian Richter // First released 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 . // 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 { 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(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); } }