From a0ec58acb2d89bc39b36e546b9513b4dd2c32965 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Mon, 4 Sep 2023 22:49:10 -0400 Subject: [PATCH 01/14] Create appproxy --- x/appproxy/appproxy.go | 71 +++++++++++++++++++++++++++++++ x/examples/fetch-proxy/main.go | 56 ++++++++++++++++++++++++ x/examples/mobileproxy/.gitignore | 1 + x/examples/mobileproxy/README.md | 24 +++++++++++ x/examples/mobileproxy/tools.go | 27 ++++++++++++ x/go.mod | 12 +++--- x/go.sum | 25 ++++++----- x/httpproxy/connect_handler.go | 61 ++++++++++++++++++++------ 8 files changed, 248 insertions(+), 29 deletions(-) create mode 100644 x/appproxy/appproxy.go create mode 100644 x/examples/fetch-proxy/main.go create mode 100644 x/examples/mobileproxy/.gitignore create mode 100644 x/examples/mobileproxy/README.md create mode 100644 x/examples/mobileproxy/tools.go diff --git a/x/appproxy/appproxy.go b/x/appproxy/appproxy.go new file mode 100644 index 00000000..e4dea1a9 --- /dev/null +++ b/x/appproxy/appproxy.go @@ -0,0 +1,71 @@ +// Copyright 2023 Jigsaw Operations LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +// Package appproxy provides convenience utilities to help applications run a local proxy +// and use that to configure their networking libraries. +// +// This package is suitable for use with Go Mobile, making it a convenient way to integrate with mobile apps. +package appproxy + +import ( + "context" + "fmt" + "log" + "net" + "net/http" + "time" + + "github.com/Jigsaw-Code/outline-sdk/x/config" + "github.com/Jigsaw-Code/outline-sdk/x/httpproxy" +) + +// Proxy enables you to get the actual address bound by the server and stop the service when no longer needed. +type Proxy struct { + address string + server *http.Server +} + +// Address returns the actual IP and port the server is bound to. +func (p *Proxy) Address() string { + return p.address +} + +// Stops gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. +func (p *Proxy) Stop(timeoutSeconds int) { + ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSeconds)*time.Second) + defer cancel() + if err := p.server.Shutdown(ctx); err != nil { + log.Fatalf("Failed to shutdown gracefully: %v", err) + p.server.Close() + } +} + +// RunProxy runs a local web proxy that listens on localAddress, and uses the transportConfig to +// create the [transport.StreamDialer] to use to connect to the destination from the proxy requests. +func RunProxy(localAddress string, transportConfig string) (*Proxy, error) { + dialer, err := config.NewStreamDialer(transportConfig) + if err != nil { + return nil, fmt.Errorf("could not create dialer: %w", err) + } + + listener, err := net.Listen("tcp", localAddress) + if err != nil { + return nil, fmt.Errorf("could not listen on address %v: %v", localAddress, err) + } + + server := &http.Server{Handler: httpproxy.NewConnectHandler(dialer)} + go server.Serve(listener) + + return &Proxy{address: listener.Addr().String(), server: server}, nil +} diff --git a/x/examples/fetch-proxy/main.go b/x/examples/fetch-proxy/main.go new file mode 100644 index 00000000..f0006545 --- /dev/null +++ b/x/examples/fetch-proxy/main.go @@ -0,0 +1,56 @@ +// Copyright 2023 Jigsaw Operations LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// https://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package main + +import ( + "flag" + "io" + "log" + "net/http" + "net/url" + "os" + + "github.com/Jigsaw-Code/outline-sdk/x/appproxy" +) + +func main() { + transportFlag := flag.String("transport", "", "Transport config") + flag.Parse() + + urlToFetch := flag.Arg(0) + if urlToFetch == "" { + log.Fatal("Need to pass the URL to fetch in the command-line") + } + + proxy, err := appproxy.RunProxy("localhost:0", *transportFlag) + if err != nil { + log.Fatalf("Could not start proxy: %v", err) + } + + httpClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: proxy.Address})}} + + resp, err := httpClient.Get(urlToFetch) + if err != nil { + log.Fatalf("URL GET failed: %v", err) + } + defer resp.Body.Close() + + _, err = io.Copy(os.Stdout, resp.Body) + if err != nil { + log.Fatalf("Read of page body failed: %v", err) + } + + proxy.Stop(5) +} diff --git a/x/examples/mobileproxy/.gitignore b/x/examples/mobileproxy/.gitignore new file mode 100644 index 00000000..6a3417b8 --- /dev/null +++ b/x/examples/mobileproxy/.gitignore @@ -0,0 +1 @@ +/out/ diff --git a/x/examples/mobileproxy/README.md b/x/examples/mobileproxy/README.md new file mode 100644 index 00000000..dd4cf014 --- /dev/null +++ b/x/examples/mobileproxy/README.md @@ -0,0 +1,24 @@ +# App Proxy Library + +This package illustrates the use Go Mobile to generarate a mobile library to run a local proxy and configure your app networking libraries. + +1. Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) + +```bash +go build -o ./out/ golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind +``` + +2. Build the iOS and Android libraries with [`gomobile bind`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile#hdr-Build_a_library_for_Android_and_iOS) + +```bash +PATH="$PATH:$(pwd)/out" $(pwd)/out/gomobile bind -target=ios -o "$(pwd)/out/LocalProxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/appproxy +PATH="$PATH:$(pwd)/out" $(pwd)/out/gomobile bind -target=android -o "$(pwd)/out/LocalProxy.aar" github.com/Jigsaw-Code/outline-sdk/x/appproxy +``` + +Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild it, and set up the PATH accordingly. + +3. To clean up: + +```bash +rm -rf ./out/ +``` diff --git a/x/examples/mobileproxy/tools.go b/x/examples/mobileproxy/tools.go new file mode 100644 index 00000000..1ce91d69 --- /dev/null +++ b/x/examples/mobileproxy/tools.go @@ -0,0 +1,27 @@ +// Copyright 2023 Jigsaw Operations LLC +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +//go:build tools +// +build tools + +// See https://github.com/golang/go/wiki/Modules#how-can-i-track-tool-dependencies-for-a-module +// and https://github.com/go-modules-by-example/index/blob/master/010_tools/README.md + +package tools + +import ( + _ "github.com/Jigsaw-Code/outline-sdk/x/appproxy" + _ "golang.org/x/mobile/cmd/gobind" + _ "golang.org/x/mobile/cmd/gomobile" +) diff --git a/x/go.mod b/x/go.mod index 1b1058c9..c1aa3551 100644 --- a/x/go.mod +++ b/x/go.mod @@ -6,7 +6,8 @@ require ( github.com/Jigsaw-Code/outline-sdk v0.0.6 github.com/miekg/dns v1.1.54 github.com/stretchr/testify v1.8.2 - golang.org/x/sys v0.8.0 + golang.org/x/mobile v0.0.0-20230905140555-fbe1c053b6a9 + golang.org/x/sys v0.11.0 ) require ( @@ -14,9 +15,10 @@ require ( github.com/kr/text v0.2.0 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect - golang.org/x/crypto v0.9.0 // indirect - golang.org/x/mod v0.10.0 // indirect - golang.org/x/net v0.10.0 // indirect - golang.org/x/tools v0.9.1 // indirect + golang.org/x/crypto v0.12.0 // indirect + golang.org/x/mod v0.12.0 // indirect + golang.org/x/net v0.14.0 // indirect + golang.org/x/sync v0.3.0 // indirect + golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect ) diff --git a/x/go.sum b/x/go.sum index 5f6e66a1..28b219ad 100644 --- a/x/go.sum +++ b/x/go.sum @@ -24,22 +24,25 @@ github.com/stretchr/testify v1.8.2 h1:+h33VjcLVPDHtOdpUCuF+7gSuG3yGIftsP1YvFihtJ github.com/stretchr/testify v1.8.2/go.mod h1:w2LPCIKwWwSfY2zedu0+kehJoqGctiVI29o6fzry7u4= golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= -golang.org/x/crypto v0.9.0 h1:LF6fAI+IutBocDJ2OT0Q1g8plpYljMZ4+lty+dsqw3g= -golang.org/x/crypto v0.9.0/go.mod h1:yrmDGqONDYtNj3tH8X9dzUun2m2lzPa9ngI6/RUPGR0= -golang.org/x/mod v0.10.0 h1:lFO9qtOdlre5W1jxS3r/4szv2/6iXxScdzjoBMXNhYk= -golang.org/x/mod v0.10.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= +golang.org/x/crypto v0.12.0 h1:tFM/ta59kqch6LlvYnPa0yx5a83cL2nHflFhYKvv9Yk= +golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw= +golang.org/x/mobile v0.0.0-20230905140555-fbe1c053b6a9 h1:LaLfQUz4L1tfuOlrtEouZLZ0qHDwKn87E1NKoiudP/o= +golang.org/x/mobile v0.0.0-20230905140555-fbe1c053b6a9/go.mod h1:2jxcxt/JNJik+N+QcB8q308+SyrE3bu43+sGZDmJ02M= +golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc= +golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs= golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= -golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M= -golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg= -golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI= +golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14= +golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI= +golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E= +golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU= -golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM= +golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= -golang.org/x/tools v0.9.1 h1:8WMNJAz3zrtPmnYC7ISf5dEn3MT0gY7jBJfw27yrrLo= -golang.org/x/tools v0.9.1/go.mod h1:owI94Op576fPu3cIGQeHs3joujW/2Oc6MtlxbF5dfNc= +golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 h1:o4bs4seAAlSiZQAZbO6/RP5XBCZCooQS3Pgc0AUjWts= +golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM= gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0= gopkg.in/check.v1 v1.0.0-20190902080502-41f04d3bba15 h1:YR8cESwS4TdDjEe65xsg0ogRM/Nc3DYOhEAlW+xobZo= gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM= diff --git a/x/httpproxy/connect_handler.go b/x/httpproxy/connect_handler.go index db25d453..f994a40b 100644 --- a/x/httpproxy/connect_handler.go +++ b/x/httpproxy/connect_handler.go @@ -15,7 +15,6 @@ package httpproxy import ( - "fmt" "io" "net" "net/http" @@ -25,47 +24,83 @@ import ( type handler struct { dialer transport.StreamDialer + client http.Client } var _ http.Handler = (*handler)(nil) // ServeHTTP implements [http.Handler].ServeHTTP for CONNECT requests, using the internal [transport.StreamDialer]. -func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { +func (h *handler) ServeHTTP(proxyResp http.ResponseWriter, proxyReq *http.Request) { // TODO(fortuna): For public services (not local), we need authentication and drain on failures to avoid fingerprinting. - if r.Method != http.MethodConnect { - http.Error(w, fmt.Sprintf("Method %v is not supported", r.Method), http.StatusMethodNotAllowed) + if proxyReq.Method == http.MethodConnect { + h.handleConnect(proxyResp, proxyReq) return + } else if proxyReq.URL.Host != "" { + h.handleHTTPProxyRequest(proxyResp, proxyReq) + } else { + http.Error(proxyResp, "Not Found", http.StatusNotFound) } +} + +func (h *handler) handleHTTPProxyRequest(proxyResp http.ResponseWriter, proxyReq *http.Request) { + targetReq, err := http.NewRequestWithContext(proxyReq.Context(), proxyReq.Method, proxyReq.URL.String(), proxyReq.Body) + if err != nil { + http.Error(proxyResp, "Error creating target request", http.StatusInternalServerError) + return + } + for key, values := range proxyReq.Header { + for _, value := range values { + targetReq.Header.Add(key, value) + } + } + targetResp, err := h.client.Do(targetReq) + if err != nil { + http.Error(proxyResp, "Failed to fetch destination", http.StatusServiceUnavailable) + return + } + defer targetResp.Body.Close() + for key, values := range targetResp.Header { + for _, value := range values { + proxyResp.Header().Add(key, value) + } + } + _, err = io.Copy(proxyResp, targetResp.Body) + if err != nil { + http.Error(proxyResp, "Failed write response", http.StatusServiceUnavailable) + return + } +} +func (h *handler) handleConnect(proxyResp http.ResponseWriter, proxyReq *http.Request) { // Validate the target address. - _, portStr, err := net.SplitHostPort(r.Host) + _, portStr, err := net.SplitHostPort(proxyReq.Host) if err != nil { - http.Error(w, "Authority is not a valid host:port", http.StatusBadRequest) + http.Error(proxyResp, "Authority is not a valid host:port", http.StatusBadRequest) return } if portStr == "" { // As per https://httpwg.org/specs/rfc9110.html#CONNECT. - http.Error(w, "Port number must be specified", http.StatusBadRequest) + http.Error(proxyResp, "Port number must be specified", http.StatusBadRequest) return } // Dial the target. - targetConn, err := h.dialer.Dial(r.Context(), r.Host) + targetConn, err := h.dialer.Dial(proxyReq.Context(), proxyReq.Host) if err != nil { - http.Error(w, "Failed to connect to target", http.StatusServiceUnavailable) + http.Error(proxyResp, "Failed to connect to target", http.StatusServiceUnavailable) return } defer targetConn.Close() - hijacker, ok := w.(http.Hijacker) + hijacker, ok := proxyResp.(http.Hijacker) if !ok { - http.Error(w, "Webserver doesn't support hijacking", http.StatusInternalServerError) + http.Error(proxyResp, "Webserver doesn't support hijacking", http.StatusInternalServerError) return } httpConn, _, err := hijacker.Hijack() if err != nil { - http.Error(w, "Failed to hijack connection", http.StatusInternalServerError) + http.Error(proxyResp, "Failed to hijack connection", http.StatusInternalServerError) return } defer httpConn.Close() @@ -88,5 +123,5 @@ func (h *handler) ServeHTTP(w http.ResponseWriter, r *http.Request) { // The resulting handler is currently vulnerable to probing attacks. It's ok as a localhost proxy // but it may be vulnerable if used as a public proxy. func NewConnectHandler(dialer transport.StreamDialer) http.Handler { - return &handler{dialer} + return &handler{dialer, *http.DefaultClient} } From bbad12d3841d0797326595fca0b56a670674927b Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Tue, 5 Sep 2023 16:01:28 -0400 Subject: [PATCH 02/14] Fix transport --- x/examples/fetch-proxy/main.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/examples/fetch-proxy/main.go b/x/examples/fetch-proxy/main.go index f0006545..d1166cf7 100644 --- a/x/examples/fetch-proxy/main.go +++ b/x/examples/fetch-proxy/main.go @@ -39,7 +39,7 @@ func main() { log.Fatalf("Could not start proxy: %v", err) } - httpClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: proxy.Address})}} + httpClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: proxy.Address()})}} resp, err := httpClient.Get(urlToFetch) if err != nil { From e998ff729dd58744ffe16b4c6e8f6b9e31978483 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Tue, 5 Sep 2023 16:05:45 -0400 Subject: [PATCH 03/14] Update title --- x/examples/mobileproxy/README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/x/examples/mobileproxy/README.md b/x/examples/mobileproxy/README.md index dd4cf014..29e102bd 100644 --- a/x/examples/mobileproxy/README.md +++ b/x/examples/mobileproxy/README.md @@ -1,4 +1,4 @@ -# App Proxy Library +# Local Proxy Library for Mobile Apps This package illustrates the use Go Mobile to generarate a mobile library to run a local proxy and configure your app networking libraries. From 91d8e97178854785c9ef65859e3d050656bdff00 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Tue, 5 Sep 2023 16:56:00 -0400 Subject: [PATCH 04/14] Add generated code --- x/examples/mobileproxy/README.md | 157 ++++++++++++++++++++++++++++++- 1 file changed, 154 insertions(+), 3 deletions(-) diff --git a/x/examples/mobileproxy/README.md b/x/examples/mobileproxy/README.md index 29e102bd..f0fdbc01 100644 --- a/x/examples/mobileproxy/README.md +++ b/x/examples/mobileproxy/README.md @@ -2,13 +2,13 @@ This package illustrates the use Go Mobile to generarate a mobile library to run a local proxy and configure your app networking libraries. -1. Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) +### Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) ```bash go build -o ./out/ golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind ``` -2. Build the iOS and Android libraries with [`gomobile bind`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile#hdr-Build_a_library_for_Android_and_iOS) +### Build the iOS and Android libraries with [`gomobile bind`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile#hdr-Build_a_library_for_Android_and_iOS) ```bash PATH="$PATH:$(pwd)/out" $(pwd)/out/gomobile bind -target=ios -o "$(pwd)/out/LocalProxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/appproxy @@ -17,7 +17,158 @@ PATH="$PATH:$(pwd)/out" $(pwd)/out/gomobile bind -target=android -o "$(pwd)/out/ Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild it, and set up the PATH accordingly. -3. To clean up: +
+iOS generated Code + +`Appproxy.objc.h`: + +```objc +// Objective-C API for talking to github.com/Jigsaw-Code/outline-sdk/x/appproxy Go package. +// gobind -lang=objc github.com/Jigsaw-Code/outline-sdk/x/appproxy +// +// File is generated by gobind. Do not edit. + +#ifndef __Appproxy_H__ +#define __Appproxy_H__ + +@import Foundation; +#include "ref.h" +#include "Universe.objc.h" + + +@class AppproxyProxy; + +/** + * Proxy enables you to get the actual address bound by the server and stop the service when no longer needed. + */ +@interface AppproxyProxy : NSObject { +} +@property(strong, readonly) _Nonnull id _ref; + +- (nonnull instancetype)initWithRef:(_Nonnull id)ref; +- (nonnull instancetype)init; +/** + * Address returns the actual IP and port the server is bound to. + */ +- (NSString* _Nonnull)address; +/** + * Stops gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. + */ +- (void)stop:(long)timeoutSeconds; +@end + +/** + * RunProxy runs a local web proxy that listens on localAddress, and uses the transportConfig to +create the [transport.StreamDialer] to use to connect to the destination from the proxy requests. + */ +FOUNDATION_EXPORT AppproxyProxy* _Nullable AppproxyRunProxy(NSString* _Nullable localAddress, NSString* _Nullable transportConfig, NSError* _Nullable* _Nullable error); + +#endif +``` + +
+ +
+ Android generated Code + +`Appproxy.java`: + +```java +// Code generated by gobind. DO NOT EDIT. + +// Java class appproxy.Appproxy is a proxy for talking to a Go program. +// +// autogenerated by gobind -lang=java github.com/Jigsaw-Code/outline-sdk/x/appproxy +package appproxy; + +import go.Seq; + +public abstract class Appproxy { + static { + Seq.touch(); // for loading the native library + _init(); + } + + private Appproxy() {} // uninstantiable + + // touch is called from other bound packages to initialize this package + public static void touch() {} + + private static native void _init(); + + + + /** + * RunProxy runs a local web proxy that listens on localAddress, and uses the transportConfig to + create the [transport.StreamDialer] to use to connect to the destination from the proxy requests. + */ + public static native Proxy runProxy(String localAddress, String transportConfig) throws Exception; +} + +``` + +`Proxy.java`: + +```java +// Code generated by gobind. DO NOT EDIT. + +// Java class appproxy.Proxy is a proxy for talking to a Go program. +// +// autogenerated by gobind -lang=java github.com/Jigsaw-Code/outline-sdk/x/appproxy +package appproxy; + +import go.Seq; + +/** + * Proxy enables you to get the actual address bound by the server and stop the service when no longer needed. + */ +public final class Proxy implements Seq.Proxy { + static { Appproxy.touch(); } + + private final int refnum; + + @Override public final int incRefnum() { + Seq.incGoRef(refnum, this); + return refnum; + } + + Proxy(int refnum) { this.refnum = refnum; Seq.trackGoRef(refnum, this); } + + public Proxy() { this.refnum = __New(); Seq.trackGoRef(refnum, this); } + + private static native int __New(); + + /** + * Address returns the actual IP and port the server is bound to. + */ + public native String address(); + /** + * Stops gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. + */ + public native void stop(long timeoutSeconds); + @Override public boolean equals(Object o) { + if (o == null || !(o instanceof Proxy)) { + return false; + } + Proxy that = (Proxy)o; + return true; + } + + @Override public int hashCode() { + return java.util.Arrays.hashCode(new Object[] {}); + } + + @Override public String toString() { + StringBuilder b = new StringBuilder(); + b.append("Proxy").append("{"); + return b.append("}").toString(); + } +} +``` + +
+ +### Clean up ```bash rm -rf ./out/ From e63794398a65aabccf6118f00bb251480db366e3 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Tue, 5 Sep 2023 17:01:44 -0400 Subject: [PATCH 05/14] Update README --- README.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/README.md b/README.md index 0218b151..5e6bda88 100644 --- a/README.md +++ b/README.md @@ -119,15 +119,15 @@ Beta features: - Transport client strategies - Proxyless strategies - [ ] Encrypted DNS - - [x] Packet splitting + - [x] Packet splitting ([reference](https://pkg.go.dev/github.com/Jigsaw-Code/outline-sdk/transport/split)) - Proxy-based strategies - [ ] HTTP Connect - - [x] SOCKS5 StreamDialer + - [x] SOCKS5 StreamDialer ([reference](https://pkg.go.dev/github.com/Jigsaw-Code/outline-sdk/transport/socks5)) - [ ] SOCKS5 PacketDialer - Integration resources - For Mobile apps - - [ ] Library to run a local SOCKS5 or HTTP-Connect proxy + - [x] Library to run a local SOCKS5 or HTTP-Connect proxy ([source](./x/appproxy/), [example Go usage](./x/examples/fetch-proxy/), [example mobile usage](./x/examples/mobileproxy)). - [x] Documentation on how to integrate the SDK into mobile apps - [ ] Connectivity Test mobile app using [Capacitor](https://capacitorjs.com/) - For Go apps From 2c948131e530c6536548ade3104bb68654e2ebfd Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Tue, 5 Sep 2023 17:03:12 -0400 Subject: [PATCH 06/14] Fix links --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 5e6bda88..68ea3758 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ Beta features: - Integration resources - For Mobile apps - - [x] Library to run a local SOCKS5 or HTTP-Connect proxy ([source](./x/appproxy/), [example Go usage](./x/examples/fetch-proxy/), [example mobile usage](./x/examples/mobileproxy)). + - [x] Library to run a local SOCKS5 or HTTP-Connect proxy ([source](./x/appproxy/appproxy.go), [example Go usage](./x/examples/fetch-proxy/main.go), [example mobile usage](./x/examples/mobileproxy)). - [x] Documentation on how to integrate the SDK into mobile apps - [ ] Connectivity Test mobile app using [Capacitor](https://capacitorjs.com/) - For Go apps From 606a43c5c54c8511d96af5151f1d042fccddaf73 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 12:57:23 -0400 Subject: [PATCH 07/14] Address comments --- x/appproxy/appproxy.go | 5 +++-- x/examples/mobileproxy/README.md | 6 +++--- x/httpproxy/connect_handler.go | 1 + 3 files changed, 7 insertions(+), 5 deletions(-) diff --git a/x/appproxy/appproxy.go b/x/appproxy/appproxy.go index e4dea1a9..10526a47 100644 --- a/x/appproxy/appproxy.go +++ b/x/appproxy/appproxy.go @@ -41,7 +41,8 @@ func (p *Proxy) Address() string { return p.address } -// Stops gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. +// Stop gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. +// The function takes a timeoutSeconds number instead of a [time.Duration] so it's compatible with Go Mobile. func (p *Proxy) Stop(timeoutSeconds int) { ctx, cancel := context.WithTimeout(context.Background(), time.Duration(timeoutSeconds)*time.Second) defer cancel() @@ -52,7 +53,7 @@ func (p *Proxy) Stop(timeoutSeconds int) { } // RunProxy runs a local web proxy that listens on localAddress, and uses the transportConfig to -// create the [transport.StreamDialer] to use to connect to the destination from the proxy requests. +// create a [transport.StreamDialer] that is used to connect to the requested destination. func RunProxy(localAddress string, transportConfig string) (*Proxy, error) { dialer, err := config.NewStreamDialer(transportConfig) if err != nil { diff --git a/x/examples/mobileproxy/README.md b/x/examples/mobileproxy/README.md index f0fdbc01..ab30eb5e 100644 --- a/x/examples/mobileproxy/README.md +++ b/x/examples/mobileproxy/README.md @@ -1,6 +1,6 @@ # Local Proxy Library for Mobile Apps -This package illustrates the use Go Mobile to generarate a mobile library to run a local proxy and configure your app networking libraries. +This package illustrates the use Go Mobile to generate a mobile library to run a local proxy and configure your app networking libraries. ### Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) @@ -11,8 +11,8 @@ go build -o ./out/ golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobi ### Build the iOS and Android libraries with [`gomobile bind`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile#hdr-Build_a_library_for_Android_and_iOS) ```bash -PATH="$PATH:$(pwd)/out" $(pwd)/out/gomobile bind -target=ios -o "$(pwd)/out/LocalProxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/appproxy -PATH="$PATH:$(pwd)/out" $(pwd)/out/gomobile bind -target=android -o "$(pwd)/out/LocalProxy.aar" github.com/Jigsaw-Code/outline-sdk/x/appproxy +PATH="$(pwd)/out:$PATH" gomobile bind -target=ios -o "$(pwd)/out/LocalProxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/appproxy +PATH="$(pwd)/out:$PATH" gomobile bind -target=android -o "$(pwd)/out/LocalProxy.aar" github.com/Jigsaw-Code/outline-sdk/x/appproxy ``` Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild it, and set up the PATH accordingly. diff --git a/x/httpproxy/connect_handler.go b/x/httpproxy/connect_handler.go index f994a40b..cafbf964 100644 --- a/x/httpproxy/connect_handler.go +++ b/x/httpproxy/connect_handler.go @@ -43,6 +43,7 @@ func (h *handler) ServeHTTP(proxyResp http.ResponseWriter, proxyReq *http.Reques } func (h *handler) handleHTTPProxyRequest(proxyResp http.ResponseWriter, proxyReq *http.Request) { + // We create a new request that uses a relative path + Host header, instead of the absolute URL in the proxy request. targetReq, err := http.NewRequestWithContext(proxyReq.Context(), proxyReq.Method, proxyReq.URL.String(), proxyReq.Body) if err != nil { http.Error(proxyResp, "Error creating target request", http.StatusInternalServerError) From ec9229d7a8c78af2596249f7c91099f18fa70ca0 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 14:35:17 -0400 Subject: [PATCH 08/14] Merge mobileproxy --- README.md | 2 +- x/examples/fetch-proxy/main.go | 6 +-- x/examples/mobileproxy/.gitignore | 1 - x/{examples => }/mobileproxy/README.md | 47 ++++++++++--------- .../mobileproxy.go} | 4 +- x/{examples => }/mobileproxy/tools.go | 2 +- 6 files changed, 31 insertions(+), 31 deletions(-) delete mode 100644 x/examples/mobileproxy/.gitignore rename x/{examples => }/mobileproxy/README.md (71%) rename x/{appproxy/appproxy.go => mobileproxy/mobileproxy.go} (95%) rename x/{examples => }/mobileproxy/tools.go (94%) diff --git a/README.md b/README.md index 68ea3758..0f90e331 100644 --- a/README.md +++ b/README.md @@ -127,7 +127,7 @@ Beta features: - Integration resources - For Mobile apps - - [x] Library to run a local SOCKS5 or HTTP-Connect proxy ([source](./x/appproxy/appproxy.go), [example Go usage](./x/examples/fetch-proxy/main.go), [example mobile usage](./x/examples/mobileproxy)). + - [x] Library to run a local SOCKS5 or HTTP-Connect proxy ([source](./x/mobileproxy/mobileproxy.go), [example Go usage](./x/examples/fetch-proxy/main.go), [example mobile usage](./x/examples/mobileproxy)). - [x] Documentation on how to integrate the SDK into mobile apps - [ ] Connectivity Test mobile app using [Capacitor](https://capacitorjs.com/) - For Go apps diff --git a/x/examples/fetch-proxy/main.go b/x/examples/fetch-proxy/main.go index d1166cf7..e9b8c5c5 100644 --- a/x/examples/fetch-proxy/main.go +++ b/x/examples/fetch-proxy/main.go @@ -22,7 +22,7 @@ import ( "net/url" "os" - "github.com/Jigsaw-Code/outline-sdk/x/appproxy" + "github.com/Jigsaw-Code/outline-sdk/x/mobileproxy" ) func main() { @@ -34,9 +34,9 @@ func main() { log.Fatal("Need to pass the URL to fetch in the command-line") } - proxy, err := appproxy.RunProxy("localhost:0", *transportFlag) + proxy, err := mobileproxy.RunProxy("localhost:0", *transportFlag) if err != nil { - log.Fatalf("Could not start proxy: %v", err) + log.Fatalf("Cmobileproxy start proxy: %v", err) } httpClient := &http.Client{Transport: &http.Transport{Proxy: http.ProxyURL(&url.URL{Scheme: "http", Host: proxy.Address()})}} diff --git a/x/examples/mobileproxy/.gitignore b/x/examples/mobileproxy/.gitignore deleted file mode 100644 index 6a3417b8..00000000 --- a/x/examples/mobileproxy/.gitignore +++ /dev/null @@ -1 +0,0 @@ -/out/ diff --git a/x/examples/mobileproxy/README.md b/x/mobileproxy/README.md similarity index 71% rename from x/examples/mobileproxy/README.md rename to x/mobileproxy/README.md index ab30eb5e..c8e885c3 100644 --- a/x/examples/mobileproxy/README.md +++ b/x/mobileproxy/README.md @@ -1,6 +1,6 @@ # Local Proxy Library for Mobile Apps -This package illustrates the use Go Mobile to generate a mobile library to run a local proxy and configure your app networking libraries. +This package enabled the use Go Mobile to generate a mobile library to run a local proxy and configure your app networking libraries. ### Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) @@ -11,8 +11,8 @@ go build -o ./out/ golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobi ### Build the iOS and Android libraries with [`gomobile bind`](https://pkg.go.dev/golang.org/x/mobile/cmd/gomobile#hdr-Build_a_library_for_Android_and_iOS) ```bash -PATH="$(pwd)/out:$PATH" gomobile bind -target=ios -o "$(pwd)/out/LocalProxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/appproxy -PATH="$(pwd)/out:$PATH" gomobile bind -target=android -o "$(pwd)/out/LocalProxy.aar" github.com/Jigsaw-Code/outline-sdk/x/appproxy +PATH="$(pwd)/out:$PATH" gomobile bind -target=ios -o "$(pwd)/out/mobileproxy.xcframework" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy +PATH="$(pwd)/out:$PATH" gomobile bind -target=android -o "$(pwd)/out/mobileproxy.aar" github.com/Jigsaw-Code/outline-sdk/x/mobileproxy ``` Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild it, and set up the PATH accordingly. @@ -20,28 +20,28 @@ Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild
iOS generated Code -`Appproxy.objc.h`: +`Mobileproxy.objc.h`: ```objc -// Objective-C API for talking to github.com/Jigsaw-Code/outline-sdk/x/appproxy Go package. -// gobind -lang=objc github.com/Jigsaw-Code/outline-sdk/x/appproxy +// Objective-C API for talking to github.com/Jigsaw-Code/outline-sdk/x/mobileproxy Go package. +// gobind -lang=objc github.com/Jigsaw-Code/outline-sdk/x/mobileproxy // // File is generated by gobind. Do not edit. -#ifndef __Appproxy_H__ -#define __Appproxy_H__ +#ifndef __Mobileproxy_H__ +#define __Mobileproxy_H__ @import Foundation; #include "ref.h" #include "Universe.objc.h" -@class AppproxyProxy; +@class MobileproxyProxy; /** * Proxy enables you to get the actual address bound by the server and stop the service when no longer needed. */ -@interface AppproxyProxy : NSObject { +@interface MobileproxyProxy : NSObject { } @property(strong, readonly) _Nonnull id _ref; @@ -52,16 +52,17 @@ Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild */ - (NSString* _Nonnull)address; /** - * Stops gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. + * Stop gracefully stops the proxy service, waiting for at most timeout seconds before forcefully closing it. +The function takes a timeoutSeconds number instead of a [time.Duration] so it's compatible with Go Mobile. */ - (void)stop:(long)timeoutSeconds; @end /** * RunProxy runs a local web proxy that listens on localAddress, and uses the transportConfig to -create the [transport.StreamDialer] to use to connect to the destination from the proxy requests. +create a [transport.StreamDialer] that is used to connect to the requested destination. */ -FOUNDATION_EXPORT AppproxyProxy* _Nullable AppproxyRunProxy(NSString* _Nullable localAddress, NSString* _Nullable transportConfig, NSError* _Nullable* _Nullable error); +FOUNDATION_EXPORT MobileproxyProxy* _Nullable MobileproxyRunProxy(NSString* _Nullable localAddress, NSString* _Nullable transportConfig, NSError* _Nullable* _Nullable error); #endif ``` @@ -71,25 +72,25 @@ FOUNDATION_EXPORT AppproxyProxy* _Nullable AppproxyRunProxy(NSString* _Nullable
Android generated Code -`Appproxy.java`: +`mobileproxy.java`: ```java // Code generated by gobind. DO NOT EDIT. -// Java class appproxy.Appproxy is a proxy for talking to a Go program. +// Java class mobileproxy.mobileproxy is a proxy for talking to a Go program. // -// autogenerated by gobind -lang=java github.com/Jigsaw-Code/outline-sdk/x/appproxy -package appproxy; +// autogenerated by gobind -lang=java github.com/Jigsaw-Code/outline-sdk/x/mobileproxy +package mobileproxy; import go.Seq; -public abstract class Appproxy { +public abstract class mobileproxy { static { Seq.touch(); // for loading the native library _init(); } - private Appproxy() {} // uninstantiable + private mobileproxy() {} // uninstantiable // touch is called from other bound packages to initialize this package public static void touch() {} @@ -112,10 +113,10 @@ public abstract class Appproxy { ```java // Code generated by gobind. DO NOT EDIT. -// Java class appproxy.Proxy is a proxy for talking to a Go program. +// Java class mobileproxy.Proxy is a proxy for talking to a Go program. // -// autogenerated by gobind -lang=java github.com/Jigsaw-Code/outline-sdk/x/appproxy -package appproxy; +// autogenerated by gobind -lang=java github.com/Jigsaw-Code/outline-sdk/x/mobileproxy +package mobileproxy; import go.Seq; @@ -123,7 +124,7 @@ import go.Seq; * Proxy enables you to get the actual address bound by the server and stop the service when no longer needed. */ public final class Proxy implements Seq.Proxy { - static { Appproxy.touch(); } + static { mobileproxy.touch(); } private final int refnum; diff --git a/x/appproxy/appproxy.go b/x/mobileproxy/mobileproxy.go similarity index 95% rename from x/appproxy/appproxy.go rename to x/mobileproxy/mobileproxy.go index 10526a47..f413dd15 100644 --- a/x/appproxy/appproxy.go +++ b/x/mobileproxy/mobileproxy.go @@ -12,11 +12,11 @@ // See the License for the specific language governing permissions and // limitations under the License. -// Package appproxy provides convenience utilities to help applications run a local proxy +// Package mobileproxy provides convenience utilities to help applications run a local proxy // and use that to configure their networking libraries. // // This package is suitable for use with Go Mobile, making it a convenient way to integrate with mobile apps. -package appproxy +package mobileproxy import ( "context" diff --git a/x/examples/mobileproxy/tools.go b/x/mobileproxy/tools.go similarity index 94% rename from x/examples/mobileproxy/tools.go rename to x/mobileproxy/tools.go index 1ce91d69..4db3a2d0 100644 --- a/x/examples/mobileproxy/tools.go +++ b/x/mobileproxy/tools.go @@ -21,7 +21,7 @@ package tools import ( - _ "github.com/Jigsaw-Code/outline-sdk/x/appproxy" + _ "github.com/Jigsaw-Code/outline-sdk/x/mobileproxy" _ "golang.org/x/mobile/cmd/gobind" _ "golang.org/x/mobile/cmd/gomobile" ) From 3e83702ffd293d41bf565c5158833d8f46c1f8dd Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 14:37:24 -0400 Subject: [PATCH 09/14] Fix README --- x/mobileproxy/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/mobileproxy/README.md b/x/mobileproxy/README.md index c8e885c3..23a4b828 100644 --- a/x/mobileproxy/README.md +++ b/x/mobileproxy/README.md @@ -1,6 +1,6 @@ -# Local Proxy Library for Mobile Apps +# Mobileproxy: Local Proxy Library for Mobile Apps -This package enabled the use Go Mobile to generate a mobile library to run a local proxy and configure your app networking libraries. +This package enables the use Go Mobile to generate a mobile library to run a local proxy and configure your app networking libraries. ### Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) From 2bf68c58483195d5806e4a508e211b30ef285ae4 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 14:43:29 -0400 Subject: [PATCH 10/14] Add directory note --- x/mobileproxy/README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/x/mobileproxy/README.md b/x/mobileproxy/README.md index 23a4b828..65b94075 100644 --- a/x/mobileproxy/README.md +++ b/x/mobileproxy/README.md @@ -4,6 +4,8 @@ This package enables the use Go Mobile to generate a mobile library to run a loc ### Build the Go Mobile binaries with [`go build`](https://pkg.go.dev/cmd/go#hdr-Compile_packages_and_dependencies) +From the `x/` directory: + ```bash go build -o ./out/ golang.org/x/mobile/cmd/gomobile golang.org/x/mobile/cmd/gobind ``` From 161c5ff42f7477fa4a6b43d4afd9d255476e5c11 Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 15:05:45 -0400 Subject: [PATCH 11/14] Add integration comment --- x/mobileproxy/README.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/x/mobileproxy/README.md b/x/mobileproxy/README.md index 65b94075..f1a3b7fd 100644 --- a/x/mobileproxy/README.md +++ b/x/mobileproxy/README.md @@ -171,6 +171,11 @@ public final class Proxy implements Seq.Proxy {
+### Integrate into your mobile project + +To add the library to your mobile project, see Go Mobile's [Building and deploying to iOS](https://github.com/golang/go/wiki/Mobile#building-and-deploying-to-ios-1) and [Building and deploying to Android](https://github.com/golang/go/wiki/Mobile#building-and-deploying-to-android-1). + + ### Clean up ```bash From c2dd3d6769e463c1af440ad5d71e9a132b6bdf7c Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 15:09:47 -0400 Subject: [PATCH 12/14] Update README --- README.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/README.md b/README.md index 0f90e331..2eda3e2e 100644 --- a/README.md +++ b/README.md @@ -48,6 +48,8 @@ To integrate the SDK into a mobile app, follow these steps: > **Note**: You must use `gomobile bind` on a package you create, not directly on the SDK packages. +The easiest way to integrate with the SDK in a mobile app is by using the [`x/mobileproxy` library](./x/mobileproxy/) +to run a local web proxy that you can use to configure your app's networking libraries. ### Side Service From 03434d8c97e91de10710bc6ad35acdc7edbf781f Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 15:42:41 -0400 Subject: [PATCH 13/14] Add "Sample" --- x/mobileproxy/README.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/x/mobileproxy/README.md b/x/mobileproxy/README.md index f1a3b7fd..ae537845 100644 --- a/x/mobileproxy/README.md +++ b/x/mobileproxy/README.md @@ -20,7 +20,7 @@ PATH="$(pwd)/out:$PATH" gomobile bind -target=android -o "$(pwd)/out/mobileproxy Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild it, and set up the PATH accordingly.
-iOS generated Code +Sample iOS generated Code `Mobileproxy.objc.h`: @@ -72,7 +72,7 @@ FOUNDATION_EXPORT MobileproxyProxy* _Nullable MobileproxyRunProxy(NSString* _Nul
- Android generated Code + Sample Android generated Code `mobileproxy.java`: From c9f1c9ebb5127c3865404cee5c89590c1308a57e Mon Sep 17 00:00:00 2001 From: Vinicius Fortuna Date: Wed, 6 Sep 2023 16:58:27 -0400 Subject: [PATCH 14/14] Address comments --- README.md | 2 +- x/mobileproxy/README.md | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 2eda3e2e..e90a7351 100644 --- a/README.md +++ b/README.md @@ -48,7 +48,7 @@ To integrate the SDK into a mobile app, follow these steps: > **Note**: You must use `gomobile bind` on a package you create, not directly on the SDK packages. -The easiest way to integrate with the SDK in a mobile app is by using the [`x/mobileproxy` library](./x/mobileproxy/) +An easy way to integrate with the SDK in a mobile app is by using the [`x/mobileproxy` library](./x/mobileproxy/) to run a local web proxy that you can use to configure your app's networking libraries. ### Side Service diff --git a/x/mobileproxy/README.md b/x/mobileproxy/README.md index ae537845..f9a73eb3 100644 --- a/x/mobileproxy/README.md +++ b/x/mobileproxy/README.md @@ -22,6 +22,10 @@ Note: Gomobile expects gobind to be in the PATH, that's why we need to prebuild
Sample iOS generated Code +The header file below is an example of the Objective-C interface that Go Mobile generates. + +> **Warning**: this example may diverge from what is actually generated by the current code. Use the coed you generate instead. + `Mobileproxy.objc.h`: ```objc @@ -74,6 +78,10 @@ FOUNDATION_EXPORT MobileproxyProxy* _Nullable MobileproxyRunProxy(NSString* _Nul
Sample Android generated Code +The files below are examples of the Java interface that Go Mobile generates. + +> **Warning**: this example may diverge from what is actually generated by the current code. Use the coed you generate instead. + `mobileproxy.java`: ```java