Skip to content
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

Feature: Add sysproxy to fyne-proxy example #214

Draft
wants to merge 8 commits into
base: main
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from 7 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 3 additions & 0 deletions x/examples/fyne-proxy/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,9 @@
# Local Proxy with Fyne

This folder has a graphical application that runs a local proxy given a address and configuration.

It also automatically configures system-wide web proxy settings using [sysproxy package](https://github.com/Jigsaw-Code/outline-sdk/tree/main/x/sysproxy) to tunnel web traffic (specially web browser traffic) through the local proxy server.

It uses [Fyne](https://fyne.io/) for the UI.


Expand Down
10 changes: 5 additions & 5 deletions x/examples/fyne-proxy/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ go 1.20

require (
fyne.io/fyne/v2 v2.4.3
github.com/Jigsaw-Code/outline-sdk v0.0.12-0.20240117212231-233d1898e1db
github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20240117212231-233d1898e1db
github.com/Jigsaw-Code/outline-sdk v0.0.15
github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20240403194323-6f484982dd29
)

require (
Expand Down Expand Up @@ -45,12 +45,12 @@ require (
github.com/urfave/cli/v2 v2.11.1 // indirect
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 // indirect
github.com/yuin/goldmark v1.5.5 // indirect
golang.org/x/crypto v0.17.0 // indirect
golang.org/x/crypto v0.18.0 // indirect
golang.org/x/image v0.14.0 // indirect
golang.org/x/mobile v0.0.0-20231127183840-76ac6878050a // indirect
golang.org/x/mod v0.14.0 // indirect
golang.org/x/net v0.19.0 // indirect
golang.org/x/sys v0.15.0 // indirect
golang.org/x/net v0.20.0 // indirect
golang.org/x/sys v0.16.0 // indirect
golang.org/x/text v0.14.0 // indirect
golang.org/x/tools v0.16.0 // indirect
gopkg.in/check.v1 v1.0.0-20200227125254-8fa46927fb4f // indirect
Expand Down
21 changes: 11 additions & 10 deletions x/examples/fyne-proxy/go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -45,10 +45,10 @@ github.com/BurntSushi/toml v0.3.1/go.mod h1:xHWCNGjB5oqiDr8zfno3MHue2Ht5sIBksp03
github.com/BurntSushi/toml v1.3.2 h1:o7IhLm0Msx3BaB+n3Ag7L8EVlByGnpq14C4YWiu/gL8=
github.com/BurntSushi/toml v1.3.2/go.mod h1:CxXYINrC8qIiEnFrOxCa7Jy5BFHlXnUU2pbicEuybxQ=
github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym/WlBOVXweHU+Q+/VP0lqqI8lqeDx9IjBqo=
github.com/Jigsaw-Code/outline-sdk v0.0.12-0.20240117212231-233d1898e1db h1:I1guGrgFXY/w+YWt7QNcb3nrTNts5opuPO44XlRF0xI=
github.com/Jigsaw-Code/outline-sdk v0.0.12-0.20240117212231-233d1898e1db/go.mod h1:FtzQwsbvAT55lpc4kmOaHyvfX8MFW8y7yOHL81wHOVQ=
github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20240117212231-233d1898e1db h1:pVN7fcEihOgzIUVBn92y84HsXrZlaHRkUgnm7Rn7lUo=
github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20240117212231-233d1898e1db/go.mod h1:VVVqAev7l5HwkQVZfs79UrXWtmU3rq76+PLAhkSvFRs=
github.com/Jigsaw-Code/outline-sdk v0.0.15 h1:2OfYum4vllfIgoDa/X9drA2I57knXFPREv4kMZkjTuI=
github.com/Jigsaw-Code/outline-sdk v0.0.15/go.mod h1:e1oQZbSdLJBBuHgfeQsgEkvkuyIePPwstUeZRGq0KO8=
github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20240403194323-6f484982dd29 h1:5OBgxtktCAAv3pVl0DmoyqI9YBAl1+6rcu9wR9VFYCQ=
github.com/Jigsaw-Code/outline-sdk/x v0.0.0-20240403194323-6f484982dd29/go.mod h1:T5tJAyU0t+RIgWBvHkEzxHAgLAkCanEy8N7L4HY9Nhs=
github.com/akavel/rsrc v0.10.2 h1:Zxm8V5eI1hW4gGaYsJQUhxpjkENuG91ki8B4zCrvEsw=
github.com/akavel/rsrc v0.10.2/go.mod h1:uLoCtb9J+EyAqh+26kdrTgmzRBFPGOolLWKpdxkKq+c=
github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY=
Expand Down Expand Up @@ -301,6 +301,7 @@ github.com/stretchr/testify v1.8.4/go.mod h1:sz/lmYIOXD/1dqDmKjjqLyZ2RngseejIcXl
github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw=
github.com/tevino/abool v1.2.0 h1:heAkClL8H6w+mK5md9dzsuohKeXHUpY7Vw0ZCKW+huA=
github.com/tevino/abool v1.2.0/go.mod h1:qc66Pna1RiIsPa7O4Egxxs9OqkuxDX55zznh9K07Tzg=
github.com/things-go/go-socks5 v0.0.5 h1:qvKaGcBkfDrUL33SchHN93srAmYGzb4CxSM2DPYufe8=
github.com/urfave/cli/v2 v2.11.1 h1:UKK6SP7fV3eKOefbS87iT9YHefv7iB/53ih6e+GNAsE=
github.com/urfave/cli/v2 v2.11.1/go.mod h1:f8iq5LtQ/bLxafbdBSLPPNsgaW0l/2fYYEHhAyPlwvo=
github.com/xrash/smetrics v0.0.0-20201216005158-039620a65673 h1:bAn7/zixMGCfxrRTfdpNzjtPYqr8smhKouy9mxVdGPU=
Expand Down Expand Up @@ -335,8 +336,8 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U
golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I=
golang.org/x/crypto v0.0.0-20210711020723-a769d52b0f97/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
golang.org/x/crypto v0.17.0 h1:r8bRNjWL3GshPW3gkd+RpvzWrZAwPS49OmTGZ/uhM4k=
golang.org/x/crypto v0.17.0/go.mod h1:gCAAfMLgwOJRpTjQ2zCCt2OcSfYMTeZVSRtQlPC7Nq4=
golang.org/x/crypto v0.18.0 h1:PGVlW0xEltQnzFZ55hkuX5+KLyrMYhHld1YHO4AKcdc=
golang.org/x/crypto v0.18.0/go.mod h1:R0j02AL6hcrfOiy9T4ZYp/rcWeMxM3L6QYxlOuEG1mg=
golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA=
golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8=
Expand Down Expand Up @@ -417,8 +418,8 @@ golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v
golang.org/x/net v0.0.0-20210316092652-d523dce5a7f4/go.mod h1:RBQZq4jEuRlivfhVLdyRGr576XBO4/greRjx4P4O3yc=
golang.org/x/net v0.0.0-20210405180319-a5a99cb37ef4/go.mod h1:p54w0d4576C0XHj96bSt6lcn1PtDYWL6XObtHCRCNQM=
golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
golang.org/x/net v0.19.0 h1:zTwKpTd2XuCqf8huc7Fo2iSy+4RHPd10s4KzeTnVr1c=
golang.org/x/net v0.19.0/go.mod h1:CfAk/cbD4CthTvqiEl8NpboMuiuOYsAr/7NOjZJtv1U=
golang.org/x/net v0.20.0 h1:aCL9BSgETF1k+blQaYUBx9hJ9LOGP3gAVemcZlf1Kpo=
golang.org/x/net v0.20.0/go.mod h1:z8BVo6PvndSri0LbOE3hAn0apkU+1YvI6E70E9jsnvY=
golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
Expand Down Expand Up @@ -492,8 +493,8 @@ golang.org/x/sys v0.0.0-20210630005230-0f9fa26af87c/go.mod h1:oPkhp1MJrh7nUepCBc
golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
golang.org/x/sys v0.15.0 h1:h48lPFYpsTvQJZF4EKyI4aLHaev3CxivZmv7yZig9pc=
golang.org/x/sys v0.15.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/sys v0.16.0 h1:xWw16ngr6ZMtmxDyKyIgsE93KNKz5HKmMa3b8ALHidU=
golang.org/x/sys v0.16.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA=
golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw=
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
Expand Down
19 changes: 19 additions & 0 deletions x/examples/fyne-proxy/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@ import (
"github.com/Jigsaw-Code/outline-sdk/transport"
"github.com/Jigsaw-Code/outline-sdk/x/config"
"github.com/Jigsaw-Code/outline-sdk/x/httpproxy"
"github.com/Jigsaw-Code/outline-sdk/x/sysproxy"
)

type runningProxy struct {
Expand Down Expand Up @@ -126,6 +127,7 @@ func makeAppHeader(title string) *fyne.Container {
}

func main() {
defer sysproxy.DisableWebProxy()
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Disable on runningProxy.Close() instead.

Perhaps have a defer that checks if proxy != nil and closes it.

Move it to where the proxy variable is defined.

fyneApp := app.New()
if meta := fyneApp.Metadata(); meta.Name == "" {
// App not packaged, probably from `go run`.
Expand Down Expand Up @@ -176,7 +178,24 @@ func main() {
if proxy == nil {
// Start proxy.
proxy, err = runServer(addressEntry.Text, configEntry.Text)
if err != nil {
log.Printf("Failed to start local proxy server: %v\n", err)
}
host, port, err := net.SplitHostPort(addressEntry.Text)
if err != nil {
log.Printf("Failed to parse address: %v\n", err)
}
// Set system-wide proxy settings
err = sysproxy.SetWebProxy(host, port)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Move the logic into runServer. And you need to check if you are on Linux, Windows or macOS in order to set the system proxy. We should output something in the status saying we set the system proxy.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna I will move this to runserver. the built system will automatically uses GOOS in the go build flags and picks the right platform.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I know, but we should not be calling those methods on the unsupported platforms.
And we should probably report an error if the system proxy fails to be set.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

when the platform is not supported (ios and android for example) sysproxy_other.go file in the sysproxy package runs, and it returns an error: https://github.com/Jigsaw-Code/outline-sdk/blob/main/x/sysproxy/sysproxy_other.go

Thinking a bit more about moving SetWebProxy() logic into runServer, I believe it's better if we keep this logic separate since it essentially starts a local server listening on a port.

SetWebProxy is a separate logic. In the current code, I start the server and then set system settings to point to it. If you run this on Android for example, the local server still keeps listening (as long as on foreground) but SetWenProxy() returns a not supported platform error. This is just a PoC and the blazer proxy fork will improve on error handling UI.

Others can also use the port exposed by the proxy server locally. I can see cases where setting system proxy is not needed. Keeping these logics separate provides extra decoupling.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For this application, the runServer function is the logic of the start button. I'd like to keep it that way, so UI and business logic a more clearly defined.

Running the proxy commands when it's not supported is a bad practice. In real apps they need to know the support, in order to adapt the UI and application logic.

We need a function that tells us whether the System Proxy can be configured.
If it can be configured, we should indicate success or failure in the status line.
If it cannot, we show nothing else other than the current status.

Copy link
Contributor Author

@amircybersec amircybersec Apr 8, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna I created a new logic called startProxy and endProxy to ensure UI and proxy logic are decoupled. startProxy encapsulate runServer and SetWebProxy logic.

I like your suggestion on having aIsSupported method to check if System Proxy can be configured before even attempting it. This should be added to sysproxy package and I can do that via a separate PR.

As a short-term solution I use error.Is to check if the SetWebProxy is returning platform is not supported error.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@fortuna Not sure if you saw the latest changes here. I appreciate your feedback on this whenever you have a moment to review the changes.

if err != nil {
log.Printf("Failed to set system wide web proxy settings: %v\n", err)
}
} else {
// Disable system-wide proxy
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do this in Close() instead.

err := sysproxy.DisableWebProxy()
if err != nil {
log.Printf("Failed to disable system-wide web proxy: %v\n", err)
}
// Stop proxy
proxy.Close()
proxy = nil
Expand Down
Loading