//
// YacyDomainHandler
// Copyright 2005 by Michael Peter Christen; mc@yacy.net, Frankfurt a. M., Germany
// Copyright 2011 by Florian Richter
// 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 .
//
package net.yacy.http;
import java.io.IOException;
import java.util.Enumeration;
import java.util.Vector;
import javax.servlet.RequestDispatcher;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletRequestWrapper;
import javax.servlet.http.HttpServletResponse;
import net.yacy.cora.protocol.Domains;
import net.yacy.server.http.AlternativeDomainNames;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.handler.AbstractHandler;
/**
* handling of request to virtual ".yacy" domain determines public adress from
* seedlist and forwards modified/wrapped request to it
*/
public class YacyDomainHandler extends AbstractHandler implements Handler {
private AlternativeDomainNames alternativeResolvers;
public void setAlternativeResolver(AlternativeDomainNames resolver) {
this.alternativeResolvers = resolver;
}
@Override
public void handle(String target, Request baseRequest, HttpServletRequest request,
HttpServletResponse response) throws IOException, ServletException {
String host = request.getServerName();
String resolved = alternativeResolvers.resolve(host);
if (resolved != null) {
// split resolved into host, port and path
String path;
String hostPort;
int posPath = resolved.indexOf('/');
if (posPath >= 0) {
path = resolved.substring(posPath);
hostPort = resolved.substring(0, posPath);
} else {
path = "";
hostPort = resolved;
}
int newPort = Domains.stripToPort(hostPort);
String newHost = Domains.stripToHostName(hostPort);
if (alternativeResolvers.myIPs().contains(newHost)) return;
if (Domains.isLocal(newHost, null)) return;
RequestDispatcher dispatcher = request.getRequestDispatcher(path + target);
dispatcher.forward(new DomainRequestWrapper(request, newHost, newPort), response);
baseRequest.setHandled(true);
}
}
private class DomainRequestWrapper extends HttpServletRequestWrapper {
final private String newServerName;
final private int newServerPort;
public DomainRequestWrapper(HttpServletRequest request, String serverName, int serverPort) {
super(request);
this.newServerName = serverName;
this.newServerPort = serverPort;
}
@Override
public String getServerName() {
return newServerName;
}
@Override
public int getServerPort() {
return newServerPort;
}
@Override
public StringBuffer getRequestURL() {
StringBuffer buf = new StringBuffer(this.getScheme() + "://" + newServerName + ":" + newServerPort + this.getPathInfo());
return buf;
}
@Override
public String getHeader(String name) {
if (name.equals("Host")) {
return newServerName + (newServerPort != 80 ? ":" + newServerPort : "");
}
return super.getHeader(name);
}
@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);
}
}
}