Fix XI2PLocationFilter for Jetty 12

- Fix IPv6 address comparison
- Add port to header
- Log tweaks
- Cleanups
This commit is contained in:
zzz
2025-06-02 12:59:43 -04:00
parent 141d60046f
commit 162888e885
2 changed files with 50 additions and 53 deletions

View File

@ -183,8 +183,9 @@ public class JettyStart implements ClientApp {
if (!lc.isRunning()) {
if (lc instanceof Server) {
Server server = (Server) lc;
// FIXME
//server.insertHandler(new XI2PLocationFilter());
Handler.Wrapper filter = new XI2PLocationFilter();
filter.setHandler(server.getHandler());
server.setHandler(filter);
}
try {
lc.start();

View File

@ -2,27 +2,19 @@ package net.i2p.servlet.filters;
import java.io.IOException;
import java.io.File;
import java.net.URISyntaxException;
import java.net.URL;
import java.net.URI;
import java.net.URLEncoder;
import java.nio.charset.StandardCharsets;
import java.util.Properties;
import javax.servlet.ServletException;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import org.eclipse.jetty.ee8.nested.Request;
import org.eclipse.jetty.ee8.nested.HandlerWrapper;
import org.eclipse.jetty.http.HttpURI;
import org.eclipse.jetty.server.Request;
import org.eclipse.jetty.server.Response;
import org.eclipse.jetty.server.Handler;
import org.eclipse.jetty.util.Callback;
import net.i2p.I2PAppContext;
import net.i2p.I2PException;
import net.i2p.data.DataHelper;
import net.i2p.data.Destination;
import net.i2p.data.PrivateKeyFile;
import net.i2p.util.Log;
/**
@ -34,26 +26,25 @@ import net.i2p.util.Log;
*
* @since 0.9.51
*/
public class XI2PLocationFilter extends HandlerWrapper {
public class XI2PLocationFilter extends Handler.Wrapper {
private String X_I2P_Location = null;
private long lastFailure = -1;
private static final long failTimeout = 600000;
private static final String encodeUTF = StandardCharsets.UTF_8.toString();
private final Log _log = I2PAppContext.getGlobalContext().logManager().getLog(XI2PLocationFilter.class);
private synchronized void setLocation(String xi2plocation) {
if (_log.shouldInfo())
_log.info("Checking X-I2P-Location header prefix" + xi2plocation);
_log.info("Checking X-I2P-Location header prefix: " + xi2plocation);
if (X_I2P_Location != null)
return ;
return;
if (xi2plocation == null)
return ;
return;
if (xi2plocation.equals(""))
return ;
return;
X_I2P_Location = xi2plocation;
if (_log.shouldInfo())
_log.info("Caching X-I2P-Location header prefix" + X_I2P_Location);
_log.info("Caching X-I2P-Location header prefix: " + X_I2P_Location);
}
private synchronized boolean shouldRecheck(){
@ -81,6 +72,8 @@ public class XI2PLocationFilter extends HandlerWrapper {
File tunnelConfig = new File(configDir, "i2ptunnel.config");
boolean isSingleFile = tunnelConfig.exists();
if (!isSingleFile) {
if (host.startsWith("[") && host.endsWith("]"))
host = host.substring(1, host.length() - 1);
File tunnelConfigD = new File(configDir, "i2ptunnel.config.d");
File[] configFiles = tunnelConfigD.listFiles(new net.i2p.util.FileSuffixFilter(".config"));
if (configFiles == null)
@ -135,54 +128,57 @@ public class XI2PLocationFilter extends HandlerWrapper {
return null;
}
private synchronized String headerContents(final HttpServletRequest httpRequest) {
/**
* @return the value for the X-I2P-Location header, or null
*/
private synchronized String headerContents(final Request request) {
HttpURI uri = request.getHttpURI();
if (X_I2P_Location != null) {
String scheme = httpRequest.getScheme();
String scheme = uri.getScheme();
if (scheme == null)
scheme = "";
String path = httpRequest.getPathInfo();
if (path == null)
path = "";
String query = httpRequest.getQueryString();
if (query == null)
query = "";
try {
if (query.equals("")) {
URI uri = new URI(scheme, X_I2P_Location, path, null);
String encodedURL = uri.toASCIIString();
return encodedURL;
} else {
URI uri = new URI(scheme, X_I2P_Location, path, query, null);
String encodedURL = uri.toASCIIString();
return encodedURL;
}
}catch(URISyntaxException use){
return null;
}
// encoded
String path = uri.getPath();
if (path == null)
path = "/";
// encoded
String query = uri.getQuery();
int port = uri.getPort();
StringBuilder buf = new StringBuilder(256);
buf.append(scheme)
.append("://")
.append(X_I2P_Location);
if (port > 0)
buf.append(':').append(port);
buf.append(path);
if (query != null)
buf.append('?').append(query);
return buf.toString();
}
return null;
}
@Override
public void handle(final String target, final Request request, final HttpServletRequest httpRequest, HttpServletResponse httpResponse)
throws IOException, ServletException {
final String hashHeader = httpRequest.getHeader("X-I2P-DestHash");
public boolean handle(final Request request, final Response response, Callback callback)
throws Exception {
final String hashHeader = request.getHeaders().get("X-I2P-DestHash");
if (hashHeader == null) {
if (shouldRecheck()) {
String xi2plocation = getXI2PLocation(request.getLocalAddr(), String.valueOf(request.getLocalPort()));
String xi2plocation = getXI2PLocation(Request.getLocalAddr(request), String.valueOf(Request.getLocalPort(request)));
if (_log.shouldInfo())
_log.info("Checking X-I2P-Location header IP " + request.getLocalAddr() + " port " + request.getLocalPort() + " prefix " + xi2plocation);
setLocation(xi2plocation);
_log.info("Checking X-I2P-Location header: IP " + Request.getLocalAddr(request) + " port " + Request.getLocalPort(request) + " prefix " + xi2plocation);
if (xi2plocation != null)
setLocation(xi2plocation);
}
String headerURL = headerContents(httpRequest);
String headerURL = headerContents(request);
if (headerURL != null) {
if (_log.shouldInfo())
_log.info("Checking X-I2P-Location header" + headerURL);
httpResponse.addHeader("X-I2P-Location", headerURL);
_log.info("Setting X-I2P-Location header: " + headerURL);
response.getHeaders().put("X-I2P-Location", headerURL);
}
}
_handler.handle(target, request, httpRequest, httpResponse);
return super.handle(request, response, callback);
}
}