Skip to content

Commit dd4c111

Browse files
Copilotlarohra
andauthored
refactor URI parsing and transport security selection
Agent-Logs-Url: https://github.com/larohra/azure-functions-java-worker/sessions/f12a179d-bf43-486b-b716-cf4f837012ff Co-authored-by: larohra <41490930+larohra@users.noreply.github.com>
1 parent f5ac9cc commit dd4c111

4 files changed

Lines changed: 77 additions & 50 deletions

File tree

src/main/java/com/microsoft/azure/functions/worker/Application.java

Lines changed: 35 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,8 @@
11
package com.microsoft.azure.functions.worker;
22

3-
import java.net.MalformedURLException;
3+
import java.net.URI;
44
import java.net.URISyntaxException;
5-
import java.net.URL;
5+
import java.util.Locale;
66
import java.util.logging.*;
77
import javax.annotation.*;
88

@@ -162,10 +162,6 @@ public String getFunctionsUri() {
162162
return this.uri;
163163
}
164164

165-
public String getUri() {
166-
return this.getFunctionsUri();
167-
}
168-
169165
@Override
170166
public boolean logToConsole() {
171167
return this.logToConsole;
@@ -190,17 +186,44 @@ private boolean isCommandlineValid() {
190186

191187
private String parseUri(String uri) throws ParseException {
192188
try {
193-
URL url = new URL(uri);
194-
url.toURI();
195-
this.host = url.getHost();
196-
this.port = url.getPort();
189+
URI parsedUri = new URI(uri);
190+
String host = parsedUri.getHost();
191+
String scheme = parsedUri.getScheme();
192+
int port = parsedUri.getPort();
193+
194+
if (scheme == null || scheme.isEmpty()) {
195+
throw new IllegalArgumentException("URI scheme is missing");
196+
}
197+
198+
switch (scheme.toLowerCase(Locale.ROOT)) {
199+
case "http":
200+
if (port == -1) {
201+
port = 80;
202+
}
203+
break;
204+
case "https":
205+
if (port == -1) {
206+
port = 443;
207+
}
208+
break;
209+
default:
210+
throw new IllegalArgumentException("Unsupported URI scheme");
211+
}
212+
213+
if (host == null || host.isEmpty()) {
214+
throw new IllegalArgumentException("URI host is missing");
215+
}
216+
197217
if (port < 1 || port > 65535) {
198218
throw new IndexOutOfBoundsException("port number out of range");
199219
}
220+
221+
this.host = host;
222+
this.port = port;
200223
return uri;
201-
} catch (MalformedURLException | URISyntaxException | IndexOutOfBoundsException e) {
224+
} catch (URISyntaxException | IllegalArgumentException | IndexOutOfBoundsException e) {
202225
throw new ParseException(String.format(
203-
"Error parsing URI \"%s\". Please provide a valid URI", uri));
226+
"Error parsing URI \"%s\". Please provide a valid http or https URI", uri));
204227
}
205228
}
206229

src/main/java/com/microsoft/azure/functions/worker/JavaWorkerClient.java

Lines changed: 2 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
package com.microsoft.azure.functions.worker;
22

3-
import java.net.URI;
4-
import java.net.URISyntaxException;
53
import java.util.*;
64
import java.util.concurrent.*;
75
import java.util.concurrent.atomic.*;
@@ -150,34 +148,7 @@ private synchronized void send(String requestId, MessageHandler<?, ?> marshaller
150148
* @param functionsUri Host endpoint URI, or null for legacy startup args that only provide host and port.
151149
*/
152150
static boolean useTransportSecurity(String functionsUri) {
153-
if (functionsUri == null) {
154-
return false;
155-
}
156-
157-
String scheme = parseFunctionsUriScheme(functionsUri);
158-
switch (scheme.toLowerCase(Locale.ROOT)) {
159-
case "http":
160-
return false;
161-
case "https":
162-
return true;
163-
default:
164-
throw new IllegalArgumentException(String.format(
165-
"Unsupported functions URI scheme \"%s\" in functions URI \"%s\". Only http and https are supported.",
166-
scheme, functionsUri));
167-
}
168-
}
169-
170-
private static String parseFunctionsUriScheme(String functionsUri) {
171-
try {
172-
String scheme = new URI(functionsUri).getScheme();
173-
if (scheme == null || scheme.isEmpty()) {
174-
throw new IllegalArgumentException(String.format(
175-
"Unsupported functions URI \"%s\". Only http and https are supported.", functionsUri));
176-
}
177-
return scheme;
178-
} catch (URISyntaxException ex) {
179-
throw new IllegalArgumentException(String.format(
180-
"Error parsing functions URI \"%s\". Please provide a valid http or https URI.", functionsUri), ex);
181-
}
151+
return functionsUri != null
152+
&& functionsUri.regionMatches(true, 0, "https://", 0, "https://".length());
182153
}
183154
}

src/test/java/com/microsoft/azure/functions/worker/ApplicationTest.java

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import java.lang.reflect.Method;
77

88
import static org.junit.jupiter.api.Assertions.assertEquals;
9+
import static org.junit.jupiter.api.Assertions.assertFalse;
910
import static org.junit.jupiter.api.Assertions.assertNull;
1011
import static org.junit.jupiter.api.Assertions.assertTrue;
1112

@@ -32,7 +33,6 @@ public void prefixedStartupArgumentsTakePrecedenceOverLegacyValues() throws Exce
3233

3334
assertTrue(isCommandLineValid(application));
3435
assertEquals("https://functions.example:8443", application.getFunctionsUri());
35-
assertEquals("https://functions.example:8443", application.getUri());
3636
assertEquals("functions.example", application.getHost());
3737
assertEquals(8443, application.getPort());
3838
assertEquals(Integer.valueOf(2048), application.getMaxMessageSize());
@@ -56,6 +56,43 @@ public void legacyHostAndPortRemainAvailableWhenFunctionsUriIsAbsent() throws Ex
5656
assertEquals(Integer.valueOf(4096), application.getMaxMessageSize());
5757
}
5858

59+
@Test
60+
public void httpsFunctionsUriDefaultsToPort443WhenPortIsMissing() throws Exception {
61+
Application application = createApplication(
62+
"--functions-uri", "https://functions.example/path",
63+
"--functions-worker-id", "prefixed-worker",
64+
"--functions-request-id", "prefixed-request",
65+
"--functions-grpc-max-message-length", "2048");
66+
67+
assertTrue(isCommandLineValid(application));
68+
assertEquals("functions.example", application.getHost());
69+
assertEquals(443, application.getPort());
70+
}
71+
72+
@Test
73+
public void httpFunctionsUriDefaultsToPort80WhenPortIsMissing() throws Exception {
74+
Application application = createApplication(
75+
"--functions-uri", "http://functions.example/path",
76+
"--functions-worker-id", "prefixed-worker",
77+
"--functions-request-id", "prefixed-request",
78+
"--functions-grpc-max-message-length", "2048");
79+
80+
assertTrue(isCommandLineValid(application));
81+
assertEquals("functions.example", application.getHost());
82+
assertEquals(80, application.getPort());
83+
}
84+
85+
@Test
86+
public void unsupportedFunctionsUriSchemeFailsCommandLineValidation() throws Exception {
87+
Application application = createApplication(
88+
"--functions-uri", "unix:///tmp/functions.sock",
89+
"--functions-worker-id", "prefixed-worker",
90+
"--functions-request-id", "prefixed-request",
91+
"--functions-grpc-max-message-length", "2048");
92+
93+
assertFalse(isCommandLineValid(application));
94+
}
95+
5996
private static Application createApplication(String... args) throws Exception {
6097
Constructor<Application> constructor = Application.class.getDeclaredConstructor(String[].class);
6198
constructor.setAccessible(true);

src/test/java/com/microsoft/azure/functions/worker/JavaWorkerClientTest.java

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33
import org.junit.jupiter.api.Test;
44

55
import static org.junit.jupiter.api.Assertions.assertFalse;
6-
import static org.junit.jupiter.api.Assertions.assertThrows;
76
import static org.junit.jupiter.api.Assertions.assertTrue;
87

98
public class JavaWorkerClientTest {
@@ -23,10 +22,7 @@ public void httpsFunctionsUriUsesTransportSecurity() {
2322
}
2423

2524
@Test
26-
public void unsupportedFunctionsUriSchemeFailsFast() {
27-
IllegalArgumentException exception = assertThrows(IllegalArgumentException.class,
28-
() -> JavaWorkerClient.useTransportSecurity("unix:///tmp/functions.sock"));
29-
30-
assertTrue(exception.getMessage().contains("Only http and https are supported."));
25+
public void httpsFunctionsUriSchemeIsCaseInsensitive() {
26+
assertTrue(JavaWorkerClient.useTransportSecurity("HTTPS://functions.example:8443"));
3127
}
3228
}

0 commit comments

Comments
 (0)