From c94230da4011d3b996ee0520aa209932040f0d51 Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Sat, 29 Jun 2019 10:04:01 +0200 Subject: [PATCH 1/2] Issue #3832 Test for proxy protocol v2 Signed-off-by: Greg Wilkins --- .../jetty/server/ProxyProtocolTest.java | 84 ++++++++++++++++++- 1 file changed, 83 insertions(+), 1 deletion(-) diff --git a/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyProtocolTest.java b/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyProtocolTest.java index 9c3a18b183a..69889e4bd56 100644 --- a/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyProtocolTest.java +++ b/jetty-server/src/test/java/org/eclipse/jetty/server/ProxyProtocolTest.java @@ -30,6 +30,7 @@ import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import org.eclipse.jetty.server.handler.AbstractHandler; +import org.eclipse.jetty.util.TypeUtil; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.Test; @@ -57,7 +58,7 @@ public class ProxyProtocolTest } @Test - public void testProxyProtocol() throws Exception + public void testProxyProtocolV1() throws Exception { final String remoteAddr = "192.168.0.0"; final int remotePort = 12345; @@ -111,4 +112,85 @@ public class ProxyProtocolTest } } } + + @Test + public void testProxyProtocolV2() throws Exception + { + final String remoteAddr = "192.168.0.1"; + final int remotePort = 12345; + start(new AbstractHandler() + { + @Override + public void handle(String target, Request baseRequest, HttpServletRequest request, HttpServletResponse response) throws IOException, ServletException + { + if (remoteAddr.equals(request.getRemoteAddr()) && + remotePort == request.getRemotePort()) + baseRequest.setHandled(true); + } + }); + + try (Socket socket = new Socket("localhost", connector.getLocalPort())) + { + String proxy = + // Preamble + "0D0A0D0A000D0A515549540A" + + + // V2, PROXY + "21" + + + // 0x1 : AF_INET 0x1 : STREAM. Address length is 2*4 + 2*2 = 12 bytes. + "11" + + + // length of remaining header (4+4+2+2+6+3 = 21) + "0015" + + + // uint32_t src_addr; uint32_t dst_addr; uint16_t src_port; uint16_t dst_port; + "C0A80001" + + "7f000001" + + "3039" + + "1F90" + + + // NOOP value 0 + "040000" + + + // NOOP value ABCDEF + "040003ABCDEF"; + + String request1 = + "GET /1 HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "\r\n"; + OutputStream output = socket.getOutputStream(); + output.write(TypeUtil.fromHexString(proxy)); + output.write(request1.getBytes(StandardCharsets.UTF_8)); + output.flush(); + + InputStream input = socket.getInputStream(); + BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8)); + String response1 = reader.readLine(); + assertTrue(response1.startsWith("HTTP/1.1 200 ")); + while (true) + { + if (reader.readLine().isEmpty()) + break; + } + + // Send a second request to verify that the proxied IP is retained. + String request2 = + "GET /2 HTTP/1.1\r\n" + + "Host: localhost\r\n" + + "Connection: close\r\n" + + "\r\n"; + output.write(request2.getBytes(StandardCharsets.UTF_8)); + output.flush(); + + String response2 = reader.readLine(); + assertTrue(response2.startsWith("HTTP/1.1 200 ")); + while (true) + { + if (reader.readLine() == null) + break; + } + } + } } From 1a6ceb2fa8f45d915bbce12132c9f29d6483bbbe Mon Sep 17 00:00:00 2001 From: Greg Wilkins Date: Mon, 1 Jul 2019 09:32:00 +0200 Subject: [PATCH 2/2] Issue #3805 Trim space on around XmlConfiguration fields (#3820) Issue #3805 Trim space on around XmlConfiguration fields (#3820) --- .../eclipse/jetty/xml/XmlConfiguration.java | 104 +++++++++++------- .../jetty/xml/XmlConfigurationTest.java | 95 ++++++++++++---- 2 files changed, 137 insertions(+), 62 deletions(-) diff --git a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java index 3a90e6597e2..46d38a08e1e 100644 --- a/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java +++ b/jetty-xml/src/main/java/org/eclipse/jetty/xml/XmlConfiguration.java @@ -617,8 +617,29 @@ public class XmlConfiguration Field field = oClass.getField(attr); if (Modifier.isPublic(field.getModifiers())) { - setField(field, obj, value); - return; + try + { + setField(field, obj, value); + return; + } + catch (IllegalArgumentException e) + { + // try to convert String value to field value + if (value instanceof String) + { + try + { + value = TypeUtil.valueOf(field.getType(), ((String)value).trim()); + setField(field, obj, value); + return; + } + catch (Exception e2) + { + e.addSuppressed(e2); + throw e; + } + } + } } } catch (NoSuchFieldException e) @@ -1405,62 +1426,70 @@ public class XmlConfiguration return null; } - // Trim values int first = 0; int last = node.size() - 1; - // Handle default trim type - if (!"String".equals(type)) + // If it is String, just append all the nodes including whitespace + if ("String".equals(type)) { - // Skip leading white - Object item; + if (first == last) + value = itemValue(obj, node.get(first)); + else + { + StringBuilder buf = new StringBuilder(); + for (int i = first; i <= last; i++) + { + Object item = node.get(i); + buf.append(itemValue(obj, item)); + } + value = buf.toString(); + } + } + else // Skip leading/trailing nodes that are all white space + { + // Skip leading nodes that are all white space while (first <= last) { - item = node.get(first); - if (!(item instanceof String)) - break; - item = ((String)item).trim(); - if (((String)item).length() > 0) + Object item = node.get(first); + if (!(item instanceof String) || ((String)item).trim().length() > 0) break; first++; } - // Skip trailing white + // Skip trailing nodes that are all white space while (first < last) { - item = node.get(last); - if (!(item instanceof String)) - break; - item = ((String)item).trim(); - if (((String)item).length() > 0) + Object item = node.get(last); + if (!(item instanceof String) || ((String)item).trim().length() > 0) break; last--; } - // All white, so return null + // No non whitespace nodes, so return null if (first > last) return null; - } - if (first == last) - { - // Single Item value - value = itemValue(obj, node.get(first)); - } - else - { - // Get the multiple items as a single string - StringBuilder buf = new StringBuilder(); - for (int i = first; i <= last; i++) + if (first == last) { - Object item = node.get(i); - buf.append(itemValue(obj, item)); + // Single Item value + value = itemValue(obj, node.get(first)); + if (value instanceof String) + value = ((String)value).trim(); + } + else + { + // Get the multiple items as a single string + StringBuilder buf = new StringBuilder(); + for (int i = first; i <= last; i++) + { + buf.append(itemValue(obj, node.get(i))); + } + value = buf.toString().trim(); } - value = buf.toString(); } } - // Untyped or unknown + // No value if (value == null) { if ("String".equals(type)) @@ -1468,14 +1497,11 @@ public class XmlConfiguration return null; } - // Try to type the object + // Untyped if (type == null) - { - if (value instanceof String) - return ((String)value).trim(); return value; - } + // Try to type the object if (isTypeMatchingClass(type, String.class)) return value.toString(); diff --git a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java index 8eb6480b915..d0316eeaf55 100644 --- a/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java +++ b/jetty-xml/src/test/java/org/eclipse/jetty/xml/XmlConfigurationTest.java @@ -727,9 +727,9 @@ public class XmlConfigurationTest public static class NativeHolder { - private boolean _boolean; - private int _integer; - private float _float; + public boolean _boolean; + public int _integer; + public float _float; public boolean getBoolean() { @@ -807,10 +807,7 @@ public class XmlConfigurationTest " bad" + ""); - assertThrows(InvocationTargetException.class, () -> - { - xmlConfiguration.configure(); - }); + assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure()); } @Test @@ -821,10 +818,63 @@ public class XmlConfigurationTest " 100 bas" + ""); - assertThrows(InvocationTargetException.class, () -> - { - xmlConfiguration.configure(); - }); + assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure()); + } + + @Test + public void testSetTrimmedSetterInt() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " 42 " + + " " + + ""); + + NativeHolder holder = (NativeHolder)xmlConfiguration.configure(); + assertThat(holder._integer, is(42)); + } + + @Test + public void testSetTrimmedIntSetterWithType() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " 42 " + + " " + + ""); + + NativeHolder holder = (NativeHolder)xmlConfiguration.configure(); + assertThat(holder._integer, is(42)); + } + + @Test + public void testSetTrimmedFieldInt() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " 42 " + + " " + + ""); + + NativeHolder holder = (NativeHolder)xmlConfiguration.configure(); + assertThat(holder._integer, is(42)); + } + + @Test + public void testSetTrimmedIntFieldWithType() throws Exception + { + XmlConfiguration xmlConfiguration = asXmlConfiguration( + "" + + " " + + " 42 " + + " " + + ""); + + NativeHolder holder = (NativeHolder)xmlConfiguration.configure(); + assertThat(holder._integer, is(42)); } @Test @@ -835,10 +885,7 @@ public class XmlConfigurationTest " 1.5" + ""); - assertThrows(InvocationTargetException.class, () -> - { - xmlConfiguration.configure(); - }); + assertThrows(InvocationTargetException.class, () -> xmlConfiguration.configure()); } @Test @@ -957,10 +1004,11 @@ public class XmlConfigurationTest @Test public void testJettyStandardIdsAndProperties_JettyHome_JettyBase() throws Exception { - String propNames[] = new String[]{ - "jetty.base", - "jetty.home" - }; + String propNames[] = new String[] + { + "jetty.base", + "jetty.home" + }; for (String propName : propNames) { @@ -985,10 +1033,11 @@ public class XmlConfigurationTest @Test public void testJettyStandardIdsAndProperties_JettyHomeUri_JettyBaseUri() throws Exception { - String propNames[] = new String[]{ - "jetty.base.uri", - "jetty.home.uri" - }; + String propNames[] = new String[] + { + "jetty.base.uri", + "jetty.home.uri" + }; for (String propName : propNames) {