-
Notifications
You must be signed in to change notification settings - Fork 2
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
SPICE-0004: HTTP Proxy Support #5
base: main
Are you sure you want to change the base?
Conversation
|
||
==== Environment Variables | ||
|
||
Proxies will _not_ be configured via environment variables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is a mistake. Env vars are the way to configure proxy settings for command-line tools. Nobody wants to configure each tool separately. I’m optimistic that the listed concerns have good enough solutions.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to the argument, but: another concern here is: how does this play with --env-var
? What happens if you do:
pkl eval --env-var http_proxy=http://some.proxy foo.pkl
It feels like this shouldn't affect proxy settings, because this is ostensibly just a way to configure what read("env:")
will return.
But if that doesn't affect the proxy, this is possibly a strange behavior:
# talk via the proxy
export http_proxy=http://some.proxy pkl eval foo.pkl
# does not talk via the proxy
pkl eval --env-var http_proxy=http://some.proxy foo.pkl
There's also plenty of languages/tools whose proxies aren't configured by env vars. Just some quick skimming (as far as I can tell):
- Node.js
- Java
- Rust, Cargo
- PHP
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Java supports OS proxy settings, and there are signs that env vars will be reconsidered. Honoring neither OS settings nor env vars will force users to script a solution specifically for Pkl.
Regarding --env-var
, the behavior you described seems fine to me.
It would be very helpful to get input from frequent proxy users. I haven't used a proxy in over a decade.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I'm sold on configuring proxies via env vars. Nothing else in Pkl in configured using them, also, It may lead to "works on my machine" problems where you have the right env vars set.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Supporting OS proxy settings sounds more enticing than supporting envvar-based configuration, if that's possible.
proxy: Proxy? | ||
---- | ||
|
||
==== `PklProject` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What’s the use case for this?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I am deploying into an environment that needs proxying. Instead of setting it up on my target machine, or setting it up via a script, I can just set it in my PklProject file.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have evidence that this is useful? Is it practical to only have per-project proxy settings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the rationale here is that settings.pkl
is a user specific configuration, which only leaves PklProject
and CLI/Evaluator options left for shared configs. Configuring your proxy every time via CLI doesn't seem ideal, so adding this settings to PklProject
allows for a project-wide proxy configuration.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Do you have evidence that this is useful? Is it practical to only have per-project proxy settings?
Yeah, this is something that was brought up as a desired use-case from some of our users.
* `--proxy` -- A proxy URL to connect to | ||
* `--noproxy` -- A comma-separated list of hosts to not proxy. | ||
|
||
==== pkl-gradle |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What’s the use case for Pkl proxy settings that differ from Gradle/JVM proxy settings?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I want to control pkl eval
through Gradle, but I want it to otherwise behave exactly like my CLI does.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The correct proxy settings depend on the network you’re on. Can you think of a use case where having different proxy settings for Gradle and the Gradle Pkl plugin is useful? I can’t.
|
||
To support this, `HttpClient#Builder` receives two new builder methods: | ||
|
||
* `setProxySelector(java.net.ProxySelector proxySelector)` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is exposing ProxySelector really necessary? (For certificates, we managed to avoid dependencies on java.net classes.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm open to ideas here!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
What motivated you to expose it?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The goal is to allow users to configure Pkl's proxy the same way their application's proxy is configured. setProxy(proxyAddress, List<URI> noProxy)
is our bespoke implementation. Having this method means that those that are already using ProxySelector
can configure our client the same way.
Some prior art; both java.net.HttpClient
and okhttp accept ProxySelector
.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Of course java.net.HttpClient accepts ProxySelector. But with every java.net type added, it becomes more difficult to ever have another implementation of org.pkl.util.http.HttpClient (say NettyHttpClient). It’s better to wait until there is a proven need for “those that are already using ProxySelector can configure our client the same way”, then make an informed decision. That’s why I didn’t expose HttpClient.sendAsync—it’s not yet needed, and with virtual threads added in Java 21, it may never be needed.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
But with every java.net type added, it becomes more difficult to ever have another implementation of org.pkl.util.http.HttpClient (say NettyHttpClient).
I'm not sure why this is desirable. Can you elaborate?
---- | ||
|
||
[[new-stdlib-module]] | ||
==== New stdlib module: `pkl.Proxy` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Having a stdlib module just for proxy settings feels strange.
Can’t this be part of pkl.settings, even if pkl.Project needs it too (which I’m not convinced of)?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Both pkl.settings
and pkl.Project
need this, and neither is a logical subset of the other, so it feels cleanest to put it in a separate module.
We can also put it in base.pkl
, but that affects the global namespace, which doesn't feel great.
We also possibly should put redirect rules in there, so maybe this intermediary module should be called HttpSettings
, with proxy and rewrite rules both being in there.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
If a new stdlib module is needed, its scope should definitely be wider than proxy settings.
Is any of the following attractive?
- pkl.Project extends pkl.settings
- pkl.Project has a property of type pkl.settings
- pkl.Project and pkl.settings have a common base module
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Out of those three, I think the third one might be a reasonable approach; will play around with that a little bit.
|
||
* HTTPS proxies | ||
* SOCKS proxies | ||
* Alternative authentication methods (e.g. setting the `Proxy-Authorization` header) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Alternative to what? As far as I can tell, this spice doesn’t propose any auth support. (I believe this is the right way to start given how little is offered by the JDK.)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Originally, I figured we would just use basic auth, but I'm backing off on that idea due to security concerns.
Co-authored-by: translatenix <119817707+translatenix@users.noreply.github.com>
Following design of SPICE-0004: apple/pkl-evolution#5
Following design of SPICE-0004: apple/pkl-evolution#5
|
||
==== Environment Variables | ||
|
||
Proxies will _not_ be configured via environment variables. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Not sure I'm sold on configuring proxies via env vars. Nothing else in Pkl in configured using them, also, It may lead to "works on my machine" problems where you have the right env vars set.
proxy: Proxy? | ||
---- | ||
|
||
==== `PklProject` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think the rationale here is that settings.pkl
is a user specific configuration, which only leaves PklProject
and CLI/Evaluator options left for shared configs. Configuring your proxy every time via CLI doesn't seem ideal, so adding this settings to PklProject
allows for a project-wide proxy configuration.
[[new-stdlib-module]] | ||
==== New stdlib module: `pkl.Proxy` | ||
|
||
A new stdlib module is added called `pkl.Proxy`, that is used by `pkl.settings` and `pkl.Project`. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Calling it pkl.HttpSettings
would future-proof if for when URL rewriting arrives, though this can be done in said SPICE.
|
||
== Alternatives considered | ||
|
||
TBD |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
URL rewriting was a considered alternative, but after some thought we found out they don't fully overlap and there may be a need for both.
This is a continuation of the design discussion started here: apple/pkl#309
Implementation: apple/pkl#472