Refactored developer proxy, and modified IPv6 fallback so that it only occurs on a connection failure.

This commit is contained in:
CalDescent 2023-07-09 12:35:46 +01:00
parent fe999a11f4
commit 5f86ecafd9

View File

@ -16,7 +16,9 @@ import javax.ws.rs.core.Context;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.ConnectException;
import java.net.HttpURLConnection;
import java.net.ProtocolException;
import java.net.URL;
import java.util.Enumeration;
@ -44,7 +46,26 @@ public class DevProxyServerResource {
try {
String source = DevProxyManager.getInstance().getSourceHostAndPort();
// Convert localhost / 127.0.0.1 to IPv6 [::1]
if (!inPath.startsWith("/")) {
inPath = "/" + inPath;
}
String queryString = request.getQueryString() != null ? "?" + request.getQueryString() : "";
// Open URL
URL url = new URL(String.format("http://%s%s%s", source, inPath, queryString));
HttpURLConnection con = (HttpURLConnection) url.openConnection();
// Proxy the request data
this.proxyRequestToConnection(request, con);
try {
// Make the request and proxy the response code
response.setStatus(con.getResponseCode());
}
catch (ConnectException e) {
// Tey converting localhost / 127.0.0.1 to IPv6 [::1]
if (source.startsWith("localhost") || source.startsWith("127.0.0.1")) {
int port = 80;
String[] parts = source.split(":");
@ -54,16 +75,25 @@ public class DevProxyServerResource {
source = String.format("[::1]:%d", port);
}
if (!inPath.startsWith("/")) {
inPath = "/" + inPath;
// Retry connection
url = new URL(String.format("http://%s%s%s", source, inPath, queryString));
con = (HttpURLConnection) url.openConnection();
this.proxyRequestToConnection(request, con);
response.setStatus(con.getResponseCode());
}
String queryString = request.getQueryString() != null ? "?" + request.getQueryString() : "";
// Proxy the response data back to the caller
this.proxyConnectionToResponse(con, response, inPath);
// Open URL
String urlString = String.format("http://%s%s%s", source, inPath, queryString);
URL url = new URL(urlString);
HttpURLConnection con = (HttpURLConnection) url.openConnection();
} catch (IOException e) {
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, e.getMessage());
}
return response;
}
private void proxyRequestToConnection(HttpServletRequest request, HttpURLConnection con) throws ProtocolException {
// Proxy the request method
con.setRequestMethod(request.getMethod());
// Proxy the request headers
@ -75,11 +105,9 @@ public class DevProxyServerResource {
}
// TODO: proxy any POST parameters from "request" to "con"
}
// Proxy the response code
int responseCode = con.getResponseCode();
response.setStatus(responseCode);
private void proxyConnectionToResponse(HttpURLConnection con, HttpServletResponse response, String inPath) throws IOException {
// Proxy the response headers
for (int i = 0; ; i++) {
String headerKey = con.getHeaderFieldKey(i);
@ -131,12 +159,6 @@ public class DevProxyServerResource {
response.setContentLength(data.length);
response.getOutputStream().write(data);
}
} catch (IOException e) {
throw ApiExceptionFactory.INSTANCE.createCustomException(request, ApiError.INVALID_CRITERIA, e.getMessage());
}
return response;
}
}