Skip to content

Commit 41cb695

Browse files
committed
Incorporate more review feedback
- default to SSLContext.getDefault() instead of built-in certificates in HttpClient - simplify Kotlin code using `with()` - add missing semicolon in documented User-Agent header - shorten comment (topic was discussed in PR, stops silly ktfmt formatting) - move built-in certificate file to new pkl-certs subproject - use java.net.URI instead of java.net.URL for certificate files (safer) - only allow jar: and file: certificate URIs
1 parent 9e62641 commit 41cb695

File tree

23 files changed

+145
-3678
lines changed

23 files changed

+145
-3678
lines changed

pkl-certs/pkl-certs.gradle.kts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
plugins {
2+
pklAllProjects
3+
pklJavaLibrary
4+
}

pkl-cli/pkl-cli.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -156,7 +156,7 @@ fun Exec.configureExecutable(isEnabled: Boolean, outputFile: File, extraArgs: Li
156156
,"--no-fallback"
157157
,"-H:IncludeResources=org/pkl/core/stdlib/.*\\.pkl"
158158
,"-H:IncludeResources=org/jline/utils/.*"
159-
,"-H:IncludeResources=org/pkl/core/http/IncludedCARoots.pem"
159+
,"-H:IncludeResources=org/pkl/certs/PklCARoots.pem"
160160
//,"-H:IncludeResources=org/pkl/core/Release.properties"
161161
,"-H:IncludeResourceBundles=org.pkl.core.errorMessages"
162162
,"--macro:truffle"

pkl-commons-cli/pkl-commons-cli.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ dependencies {
1414

1515
implementation(projects.pklCommons)
1616
testImplementation(projects.pklCommonsTest)
17+
runtimeOnly(projects.pklCerts)
1718
}
1819

1920
publishing {

pkl-commons-cli/src/main/kotlin/org/pkl/commons/cli/CliBaseOptions.kt

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -178,16 +178,16 @@ data class CliBaseOptions(
178178
* To release the resources held by the HTTP client in a timely manner, call its `close()` method.
179179
*/
180180
val httpClient: HttpClient by lazy {
181-
val builder = HttpClient.builder()
182-
if (normalizedCaCertificates.isEmpty()) {
183-
builder.addDefaultCliCertificates()
184-
} else {
185-
for (file in normalizedCaCertificates) builder.addCertificates(file)
181+
with(HttpClient.builder()) {
182+
if (normalizedCaCertificates.isEmpty()) {
183+
addDefaultCliCertificates()
184+
} else {
185+
for (file in normalizedCaCertificates) addCertificates(file)
186+
}
187+
// Lazy building significantly reduces execution time of commands that do minimal work.
188+
// However, it means that HTTP client initialization errors won't surface until an HTTP
189+
// request is made.
190+
buildLazily()
186191
}
187-
// Lazy building significantly reduces execution time of commands that do minimal work.
188-
// However, it means that HTTP client initialization errors won't surface until an HTTP request
189-
// is
190-
// made. A middleground would be to only build lazily if built-in certificates are used.
191-
builder.buildLazily()
192192
}
193193
}

pkl-commons-test/pkl-commons-test.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ dependencies {
1313
api(libs.junitParams)
1414
api(projects.pklCommons) // for convenience
1515
implementation(libs.assertj)
16+
runtimeOnly(projects.pklCerts)
1617
}
1718

1819

pkl-commons-test/src/main/kotlin/org/pkl/commons/test/FileTestUtils.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,8 @@ object FileTestUtils {
4040
}
4141

4242
fun writePklBuiltInCertificates(dir: Path): Path {
43-
val text = javaClass.getResource("/org/pkl/core/http/IncludedCARoots.pem")!!.readText()
44-
return dir.resolve("IncludedCARoots.pem").apply { writeText(text) }
43+
val text = javaClass.getResource("/org/pkl/certs/PklCARoots.pem")!!.readText()
44+
return dir.resolve("PklCARoots.pem").apply { writeText(text) }
4545
}
4646
}
4747

pkl-core/pkl-core.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ dependencies {
5858
implementation(libs.snakeYaml)
5959

6060
testImplementation(projects.pklCommonsTest)
61-
61+
6262
add("generatorImplementation", libs.javaPoet)
6363
add("generatorImplementation", libs.truffleApi)
6464
add("generatorImplementation", libs.kotlinStdLib)

pkl-core/src/main/java/org/pkl/core/PklException.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,4 +23,8 @@ public PklException(String message, Throwable cause) {
2323
public PklException(String message) {
2424
super(message);
2525
}
26+
27+
public PklException(Throwable cause) {
28+
super(cause);
29+
}
2630
}

pkl-core/src/main/java/org/pkl/core/http/HttpClient.java

Lines changed: 25 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
package org.pkl.core.http;
1717

1818
import java.io.IOException;
19-
import java.net.URL;
19+
import java.net.URI;
2020
import java.net.http.HttpRequest;
2121
import java.net.http.HttpResponse;
2222
import java.net.http.HttpTimeoutException;
@@ -40,7 +40,7 @@ interface Builder {
4040
/**
4141
* Sets the {@code User-Agent} header.
4242
*
43-
* <p>Defaults to {@code "Pkl/$version ($os $flavor)"}.
43+
* <p>Defaults to {@code "Pkl/$version ($os; $flavor)"}.
4444
*/
4545
Builder setUserAgent(String userAgent);
4646

@@ -73,10 +73,13 @@ interface Builder {
7373
* <p>The given file must contain <a href="https://en.wikipedia.org/wiki/X.509">X.509</a>
7474
* certificates in PEM format.
7575
*
76-
* <p>This method can be used to add certificate files located on the JVM class path. To add
77-
* certificate files located on the file system, use {@link #addCertificates(Path)}.
76+
* <p>This method is intended to be used for adding certificate files located on the class path.
77+
* To add certificate files located on the file system, use {@link #addCertificates(Path)}.
78+
*
79+
* @throws HttpClientInitException if the given URI has a scheme other than {@code jar:} or
80+
* {@code file:}
7881
*/
79-
Builder addCertificates(URL file);
82+
Builder addCertificates(URI file);
8083

8184
/**
8285
* Adds the CA certificate files in {@code ~/.pkl/cacerts/} to the client's trust store.
@@ -86,10 +89,23 @@ interface Builder {
8689
* {@link #addBuiltInCertificates() built-in certificates} are added instead.
8790
*
8891
* <p>This method implements the default behavior of Pkl CLIs.
92+
*
93+
* <p>NOTE: This method requires the optional {@code pkl-certs} JAR to be present on the class
94+
* path.
95+
*
96+
* @throws HttpClientInitException if an I/O error occurs while scanning {@code ~/.pkl/cacerts/}
97+
* or the {@code pkl-certs} JAR is not found on the class path
8998
*/
90-
Builder addDefaultCliCertificates() throws IOException;
99+
Builder addDefaultCliCertificates();
91100

92-
/** Adds Pkl's built-in CA certificates to the client's trust store. */
101+
/**
102+
* Adds Pkl's built-in CA certificates to the client's trust store.
103+
*
104+
* <p>NOTE: This method requires the optional {@code pkl-certs} JAR to be present on the class
105+
* path.
106+
*
107+
* @throws HttpClientInitException if the {@code pkl-certs} JAR is not found on the class path
108+
*/
93109
Builder addBuiltInCertificates();
94110

95111
/**
@@ -117,7 +133,8 @@ interface Builder {
117133
* <ul>
118134
* <li>Connect timeout: 60 seconds
119135
* <li>Request timeout: 60 seconds
120-
* <li>CA certificates: none (falls back to {@link Builder#addBuiltInCertificates})
136+
* <li>CA certificates: none (falls back to the JVM's {@linkplain SSLContext#getDefault()
137+
* default SSL context})
121138
* </ul>
122139
*/
123140
static Builder builder() {

0 commit comments

Comments
 (0)