From 1fd8d71e10cc1b2ca502ac8a5557da2acbdd6be2 Mon Sep 17 00:00:00 2001 From: atavism Date: Tue, 10 Sep 2024 15:46:51 -0700 Subject: [PATCH] Additional updates to ProClient (#1167) * clean-ups * Add comments, clean-ups * Add comments, clean-ups * disable use of ChainedNonPersistent for now * fix test * fix integration test * Update flashlight and run go mod tidy * fix test * use empty settings in test * try reverting go1.23 changes * Update tests * update dependencies * run go mod tidy * update argument passed to auth.NewClient * revert changes to integration test * update integration test * update integration test * formatting * update integration test --- desktop/lib.go | 12 +-- go.mod | 21 ++-- go.sum | 47 +++++---- internalsdk/auth/auth.go | 63 ++++++------ internalsdk/pro/http.go | 4 +- internalsdk/pro/pro.go | 55 ++++++----- internalsdk/pro/proxy.go | 4 +- internalsdk/session_model.go | 2 +- internalsdk/webclient/common.go | 12 --- .../webclient/defaultwebclient/rest.go | 83 ---------------- internalsdk/webclient/webclient.go | 97 ++++++++++++++++++- .../xcshareddata/swiftpm/Package.resolved | 14 --- macos/Podfile.lock | 2 +- pubspec.lock | 36 +++---- 14 files changed, 222 insertions(+), 230 deletions(-) delete mode 100644 internalsdk/webclient/defaultwebclient/rest.go delete mode 100644 ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved diff --git a/desktop/lib.go b/desktop/lib.go index c38f05907..dc04752cc 100644 --- a/desktop/lib.go +++ b/desktop/lib.go @@ -64,13 +64,13 @@ var issueMap = map[string]string{ func init() { cdir := configDir(&flags) ss := settings.LoadSettings(cdir) - webclientOpts := &webclient.Opts{ - UserConfig: func() common.UserConfig { - return settings.UserConfig(ss) - }, + userConfig := func() common.UserConfig { + return settings.UserConfig(ss) } - proClient = proclient.NewClient(fmt.Sprintf("https://%s", common.ProAPIHost), webclientOpts) - authClient = auth.NewClient(fmt.Sprintf("https://%s", common.V1BaseUrl), webclientOpts) + proClient = proclient.NewClient(fmt.Sprintf("https://%s", common.ProAPIHost), &webclient.Opts{ + UserConfig: userConfig, + }) + authClient = auth.NewClient(fmt.Sprintf("https://%s", common.V1BaseUrl), userConfig) a = app.NewApp(flags, cdir, proClient, ss) } diff --git a/go.mod b/go.mod index 3b41a306b..5343d8136 100644 --- a/go.mod +++ b/go.mod @@ -1,8 +1,6 @@ module github.com/getlantern/lantern-client -go 1.22.3 - -toolchain go1.22.4 +go 1.23.1 // replace github.com/getlantern/flashlight/v7 => ../flashlight // replace github.com/getlantern/fronted => ../fronted @@ -20,6 +18,8 @@ replace github.com/eycorsican/go-tun2socks => github.com/getlantern/go-tun2socks replace github.com/tetratelabs/wazero => github.com/refraction-networking/wazero v1.7.1-w +replace github.com/getlantern/replica => github.com/getlantern/replica v0.14.5-0.20240909174421-21691d4b40f8 + require ( github.com/1Password/srp v0.2.0 github.com/blang/semver v3.5.1+incompatible @@ -51,7 +51,7 @@ require ( github.com/getlantern/osversion v0.0.0-20240418205916-2e84a4a4e175 github.com/getlantern/pathdb v0.0.0-20231026090702-54ee1ddd99eb github.com/getlantern/profiling v0.0.0-20160317154340-2a15afbadcff - github.com/getlantern/replica v0.14.4 + github.com/getlantern/replica v0.14.5-0.20240909174421-21691d4b40f8 github.com/getlantern/safechannels v0.0.0-20201218194342-b4e5383e9627 github.com/getlantern/sysproxy v0.0.0-20230319110552-63a8cacb7b9b github.com/getlantern/timezone v0.0.0-20210901200113-3f9de9d360c9 @@ -82,6 +82,7 @@ require ( git.torproject.org/pluggable-transports/goptlib.git v1.2.0 // indirect github.com/Jigsaw-Code/outline-sdk v0.0.16 // indirect github.com/Jigsaw-Code/outline-ss-server v1.5.0 // indirect + github.com/OneOfOne/xxhash v1.2.8 // indirect github.com/OperatorFoundation/Replicant-go/Replicant/v3 v3.0.23 // indirect github.com/OperatorFoundation/Starbridge-go/Starbridge/v3 v3.0.17 // indirect github.com/OperatorFoundation/ghostwriter-go v1.0.6 // indirect @@ -91,6 +92,7 @@ require ( github.com/Yawning/chacha20 v0.0.0-20170904085104-e3b1f968fc63 // indirect github.com/aead/ecdh v0.2.0 // indirect github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 // indirect + github.com/alecthomas/assert/v2 v2.3.0 // indirect github.com/alecthomas/atomic v0.1.0-alpha2 // indirect github.com/alextanhongpin/go-bandit v0.0.0-20191125130111-30de60d69bae // indirect github.com/anacrolix/chansync v0.5.1 // indirect @@ -212,6 +214,7 @@ require ( github.com/google/btree v1.1.2 // indirect github.com/google/go-cmp v0.6.0 // indirect github.com/google/pprof v0.0.0-20240727154555-813a5fbdbec8 // indirect + github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 // indirect github.com/grpc-ecosystem/grpc-gateway/v2 v2.21.0 // indirect github.com/hashicorp/golang-lru v1.0.2 // indirect github.com/huandu/xstrings v1.5.0 // indirect @@ -225,8 +228,10 @@ require ( github.com/kr/binarydist v0.1.0 // indirect github.com/kr/pretty v0.3.1 // indirect github.com/kr/text v0.2.0 // indirect + github.com/lib/pq v1.10.7 // indirect github.com/libp2p/go-buffer-pool v0.1.0 // indirect github.com/mattn/go-isatty v0.0.20 // indirect + github.com/mattn/go-sqlite3 v2.0.2+incompatible // indirect github.com/mdlayher/netlink v1.1.0 // indirect github.com/mholt/archiver/v3 v3.5.1 // indirect github.com/miekg/dns v1.1.59 // indirect @@ -235,6 +240,7 @@ require ( github.com/mitchellh/go-ps v1.0.0 // indirect github.com/mitchellh/go-server-timing v1.0.1 // indirect github.com/mitchellh/mapstructure v1.5.0 // indirect + github.com/montanaflynn/stats v0.7.0 // indirect github.com/mr-tron/base58 v1.2.0 // indirect github.com/mschoch/smat v0.2.0 // indirect github.com/multiformats/go-multihash v0.2.3 // indirect @@ -247,7 +253,7 @@ require ( github.com/oschwald/geoip2-golang v1.9.0 // indirect github.com/oschwald/maxminddb-golang v1.12.0 // indirect github.com/oxtoacart/bpool v0.0.0-20190530202638-03653db5a59c // indirect - github.com/pierrec/lz4/v4 v4.1.15 // indirect + github.com/pierrec/lz4/v4 v4.1.18 // indirect github.com/pion/datachannel v1.5.8 // indirect github.com/pion/dtls/v2 v2.2.12 // indirect github.com/pion/ice/v2 v2.3.34 // indirect @@ -283,6 +289,7 @@ require ( github.com/shadowsocks/go-shadowsocks2 v0.1.5 // indirect github.com/siddontang/go v0.0.0-20180604090527-bdc77568d726 // indirect github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 // indirect + github.com/smartystreets/goconvey v1.7.2 // indirect github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 // indirect github.com/spaolacci/murmur3 v1.1.0 // indirect github.com/stretchr/objx v0.5.2 // indirect @@ -304,7 +311,7 @@ require ( gitlab.com/yawning/edwards25519-extra.git v0.0.0-20211229043746-2f91fcc9fbdb // indirect gitlab.com/yawning/obfs4.git v0.0.0-20220204003609-77af0cba934d // indirect go.etcd.io/bbolt v1.3.10 // indirect - go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 // indirect + go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 // indirect go.opentelemetry.io/otel v1.19.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 // indirect go.opentelemetry.io/otel/exporters/otlp/otlpmetric/otlpmetrichttp v0.42.0 // indirect @@ -314,7 +321,7 @@ require ( go.opentelemetry.io/otel/sdk v1.19.0 // indirect go.opentelemetry.io/otel/sdk/metric v1.19.0 // indirect go.opentelemetry.io/otel/trace v1.19.0 // indirect - go.opentelemetry.io/proto/otlp v1.3.1 // indirect + go.opentelemetry.io/proto/otlp v1.0.0 // indirect go.uber.org/atomic v1.11.0 // indirect go.uber.org/mock v0.4.0 // indirect go.uber.org/multierr v1.11.0 // indirect diff --git a/go.sum b/go.sum index 3c2415ae4..6b18b5943 100644 --- a/go.sum +++ b/go.sum @@ -16,8 +16,9 @@ github.com/Jigsaw-Code/outline-sdk v0.0.16 h1:WbHmv80FKDIpzEmR3GehTbq5CibYTLvcxI github.com/Jigsaw-Code/outline-sdk v0.0.16/go.mod h1:e1oQZbSdLJBBuHgfeQsgEkvkuyIePPwstUeZRGq0KO8= github.com/Jigsaw-Code/outline-ss-server v1.5.0 h1:Vz+iS0xR7i3PrLD82pzFFwZ9fsh6zrNawMeYERR8VTc= github.com/Jigsaw-Code/outline-ss-server v1.5.0/go.mod h1:KaebwBiCWDSkgsJrJIbGH0szON8CZq4LgQaFV8v3RM4= -github.com/OneOfOne/xxhash v1.2.2 h1:KMrpdQIwFcEqXDklaen+P1axHaj9BSKzvpUUfnHldSE= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= +github.com/OneOfOne/xxhash v1.2.8 h1:31czK/TI9sNkxIKfaUfGlU47BAxQ0ztGgd9vPyqimf8= +github.com/OneOfOne/xxhash v1.2.8/go.mod h1:eZbhyaAYD41SGSSsnmcpxVoRiQ/MPUTjUdIIOT9Um7Q= github.com/OperatorFoundation/Replicant-go/Replicant/v3 v3.0.23 h1:g0kC1BDonLwNse78HRsudElKEDfXHusLQ9Nfekl/l0o= github.com/OperatorFoundation/Replicant-go/Replicant/v3 v3.0.23/go.mod h1:QVlygHzbNc/fX+OHurCRC0AFwISJAUQbPaqdEfAkUio= github.com/OperatorFoundation/Starbridge-go/Starbridge/v3 v3.0.17 h1:F7IpGVx5URu+s1v9JqioSz+1AE2O+QvQZ8Vl0q6JH8w= @@ -41,12 +42,12 @@ github.com/aead/ecdh v0.2.0 h1:pYop54xVaq/CEREFEcukHRZfTdjiWvYIsZDXXrBapQQ= github.com/aead/ecdh v0.2.0/go.mod h1:a9HHtXuSo8J1Js1MwLQx2mBhkXMT6YwUmVVEY4tTB8U= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0 h1:byYvvbfSo3+9efR4IeReh77gVs4PnNDR3AMOE9NJ7a0= github.com/ajwerner/btree v0.0.0-20211221152037-f427b3e689c0/go.mod h1:q37NoqncT41qKc048STsifIt69LfUJ8SrWWcz/yam5k= -github.com/alecthomas/assert/v2 v2.0.0-alpha3 h1:pcHeMvQ3OMstAWgaeaXIAL8uzB9xMm2zlxt+/4ml8lk= -github.com/alecthomas/assert/v2 v2.0.0-alpha3/go.mod h1:+zD0lmDXTeQj7TgDgCt0ePWxb0hMC1G+PGTsTCv1B9o= +github.com/alecthomas/assert/v2 v2.3.0 h1:mAsH2wmvjsuvyBvAmCtm7zFsBlb8mIHx5ySLVdDZXL0= +github.com/alecthomas/assert/v2 v2.3.0/go.mod h1:pXcQ2Asjp247dahGEmsZ6ru0UVwnkhktn7S0bBDLxvQ= github.com/alecthomas/atomic v0.1.0-alpha2 h1:dqwXmax66gXvHhsOS4pGPZKqYOlTkapELkLb3MNdlH8= github.com/alecthomas/atomic v0.1.0-alpha2/go.mod h1:zD6QGEyw49HIq19caJDc2NMXAy8rNi9ROrxtMXATfyI= -github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142 h1:8Uy0oSf5co/NZXje7U1z8Mpep++QJOldL2hs/sBQf48= -github.com/alecthomas/repr v0.0.0-20210801044451-80ca428c5142/go.mod h1:2kn6fqh/zIyPLmm3ugklbEi5hg5wS435eygvNfaDQL8= +github.com/alecthomas/repr v0.2.0 h1:HAzS41CIzNW5syS8Mf9UwXhNH1J9aix/BvDRf1Ml2Yk= +github.com/alecthomas/repr v0.2.0/go.mod h1:Fr0507jx4eOXV7AlPV6AVZLYrLIuIeSOWtW57eE/O/4= github.com/alecthomas/template v0.0.0-20160405071501-a0175ee3bccc/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/template v0.0.0-20190718012654-fb15b899a751/go.mod h1:LOuyumcjzFXgccqObfd/Ljyb9UuFJ6TxHnclSeseNhc= github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= @@ -415,8 +416,8 @@ github.com/getlantern/quicwrapper v0.0.0-20240229232335-e6b4c3c30b2f h1:w/PNBtsq github.com/getlantern/quicwrapper v0.0.0-20240229232335-e6b4c3c30b2f/go.mod h1:V1d6sFYfulYYs07QS2pzBkpuQiF2Jj12KepiT3LFytY= github.com/getlantern/ratelimit v0.0.0-20220926192648-933ab81a6fc7 h1:47FJ5kTeXc3I1VPpi2hWW9I16/Y3K0cpUq/B7oWJGF8= github.com/getlantern/ratelimit v0.0.0-20220926192648-933ab81a6fc7/go.mod h1:OOqKCIkspqXtIWEex4uhH1H9l7NGekT9i3Hs591ZDk4= -github.com/getlantern/replica v0.14.4 h1:s7rxJHrOxWdw4iFILht0zIbub1pjn0sXx1eElDxICIA= -github.com/getlantern/replica v0.14.4/go.mod h1:F46ohChSKJ6vAuEvjFmIZMBh50Cc3zEJCPwjbOKzKwU= +github.com/getlantern/replica v0.14.5-0.20240909174421-21691d4b40f8 h1:K+zi+42bkdPfyE9ZoGpDWocUzLfIGajmHTIvbippeX8= +github.com/getlantern/replica v0.14.5-0.20240909174421-21691d4b40f8/go.mod h1:EGZQzNcxXFE6/C4hM6+91fDZz9hOQ0GZHdzNne3k/Oc= github.com/getlantern/rot13 v0.0.0-20220822172233-370767b2f782 h1:A1+qM0Dqm0no8A5qvWoTCFKME9Sa67xsJ1fcV13PvEY= github.com/getlantern/rot13 v0.0.0-20220822172233-370767b2f782/go.mod h1:O0dNqH9hbXlOa9OpVdbACmTBfDPD+ENjbY0cPkzBd9g= github.com/getlantern/rotator v0.0.0-20160829164113-013d4f8e36a2 h1:smFR/kESUKlcdyatoOO3HngBzzrUU6S0LRw2vCBYQPg= @@ -562,8 +563,9 @@ github.com/googleapis/gax-go v2.0.0+incompatible/go.mod h1:SFVmujtThgffbyetf+mdk github.com/gopherjs/gopherjs v0.0.0-20181017120253-0766667cb4d1/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20181103185306-d547d1d9531e/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gopherjs/gopherjs v0.0.0-20190309154008-847fc94819f9/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= -github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99 h1:twflg0XRTjwKpxb/jFExr4HGq6on2dEOmnL6FV+fgPw= github.com/gopherjs/gopherjs v0.0.0-20190910122728-9d188e94fb99/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00 h1:l5lAOZEym3oK3SQ2HBHWsJUfbNBiTXJDeW2QDxw9AQ0= +github.com/gopherjs/gopherjs v0.0.0-20200217142428-fce0ec30dd00/go.mod h1:wJfORRmW1u3UXTncJ5qlYoELFm8eSnnEO6hX4iZ3EWY= github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg= github.com/gorilla/mux v1.6.2/go.mod h1:1lud6UwP+6orDFRuTfBEV8e9/aOM/c4fVVCaMa2zaAs= github.com/gorilla/mux v1.8.1 h1:TuBL49tXwgrFYWhqrNgrUNEY92u81SPhu7sTdzQEiWY= @@ -646,8 +648,9 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/leekchan/accounting v1.0.0 h1:+Wd7dJ//dFPa28rc1hjyy+qzCbXPMR91Fb6F1VGTQHg= github.com/leekchan/accounting v1.0.0/go.mod h1:3timm6YPhY3YDaGxl0q3eaflX0eoSx3FXn7ckHe4tO0= -github.com/lib/pq v1.0.0 h1:X5PMW56eZitiTeO7tKzZxFCSpbFZJtkMMooicw2us9A= github.com/lib/pq v1.0.0/go.mod h1:5WUZQaWbwv1U+lTReE5YruASi9Al49XbQIvNi/34Woo= +github.com/lib/pq v1.10.7 h1:p7ZhMD+KsSRozJr34udlUrhboJwWAgCg34+/ZZNvZZw= +github.com/lib/pq v1.10.7/go.mod h1:AlVN5x4E4T544tWzH6hKfbfQvm3HdbOxrmggDNAPY9o= github.com/libp2p/go-buffer-pool v0.0.2/go.mod h1:MvaB6xw5vOrDl8rYZGLFdKAuk/hRoRZd1Vi32+RXyFM= github.com/libp2p/go-buffer-pool v0.1.0 h1:oK4mSFcQz7cTQIfqbe4MIj9gLW+mnanjyFtc6cdF0Y8= github.com/libp2p/go-buffer-pool v0.1.0/go.mod h1:N+vh8gMqimBzdKkSMVuydVDq+UV5QTWy5HSiZacSbPg= @@ -657,8 +660,8 @@ github.com/mattn/go-colorable v0.0.10-0.20170816031813-ad5389df28cd/go.mod h1:9v github.com/mattn/go-isatty v0.0.2/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= -github.com/mattn/go-sqlite3 v1.14.11 h1:gt+cp9c0XGqe9S/wAHTL3n/7MqY+siPWgWJgqdsFrzQ= -github.com/mattn/go-sqlite3 v1.14.11/go.mod h1:NyWgC/yNuGj7Q9rpYnZvas74GogHl5/Z4A/KQRfk6bU= +github.com/mattn/go-sqlite3 v2.0.2+incompatible h1:qzw9c2GNT8UFrgWNDhCTqRqYUSmu/Dav/9Z58LGpk7U= +github.com/mattn/go-sqlite3 v2.0.2+incompatible/go.mod h1:FPy6KqzDD04eiIsT53CuJW3U88zkxoIYsOqkbpncsNc= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= github.com/mdlayher/netlink v0.0.0-20190409211403-11939a169225/go.mod h1:eQB3mZE4aiYnlUsyGGCOpPETfdQq4Jhsgf1fk3cwQaA= github.com/mdlayher/netlink v1.0.0/go.mod h1:KxeJAFOFLG6AjpyDkQ/iIhxygIUKD+vcwqcnu43w/+M= @@ -684,8 +687,9 @@ github.com/modern-go/concurrent v0.0.0-20180228061459-e0a39a4cb421/go.mod h1:6dJ github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd/go.mod h1:6dJC0mAP4ikYIbvyc7fijjWJddQyLn8Ig3JB5CqoB9Q= github.com/modern-go/reflect2 v0.0.0-20180701023420-4b7aa43c6742/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= github.com/modern-go/reflect2 v1.0.1/go.mod h1:bx2lNnkwVCuqBIxFjflWJWanXIb3RllmbCylyMrvgv0= -github.com/montanaflynn/stats v0.5.0 h1:2EkzeTSqBB4V4bJwWrt5gIIrZmpJBcoIRGS2kWLgzmk= github.com/montanaflynn/stats v0.5.0/go.mod h1:wL8QJuTMNUDYhXwkmfOly8iTdp5TEcJFWZD2D7SIkUc= +github.com/montanaflynn/stats v0.7.0 h1:r3y12KyNxj/Sb/iOE46ws+3mS1+MZca1wlHQFPsY/JU= +github.com/montanaflynn/stats v0.7.0/go.mod h1:etXPPgVO6n31NxCd9KQUMvCM+ve0ruNzt6R8Bnaayow= github.com/moul/http2curl v1.0.0 h1:dRMWoAtb+ePxMlLkrCbAqh4TlPHXvoGUSQ323/9Zahs= github.com/moul/http2curl v1.0.0/go.mod h1:8UbvGypXm98wA/IqH45anm5Y2Z6ep6O31QGOAZ3H0fQ= github.com/mr-tron/base58 v1.2.0 h1:T/HDJBh4ZCPbU39/+c3rRvE0uKBQlU27+QI8LJ4t64o= @@ -733,8 +737,8 @@ github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/9 github.com/philhofer/fwd v1.0.0/go.mod h1:gk3iGcWd9+svBvR0sR+KPcfE+RNWozjowpeBVG3ZVNU= github.com/pierrec/lz4 v2.0.5+incompatible/go.mod h1:pdkljMzZIN41W+lC3N2tnIh5sFi+IEE17M5jbnwPHcY= github.com/pierrec/lz4/v4 v4.1.2/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= -github.com/pierrec/lz4/v4 v4.1.15 h1:MO0/ucJhngq7299dKLwIMtgTfbkoSPF6AoMYDd8Q4q0= -github.com/pierrec/lz4/v4 v4.1.15/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= +github.com/pierrec/lz4/v4 v4.1.18 h1:xaKrnTkyoqfh1YItXl56+6KJNVYWlEEPuAQW9xsplYQ= +github.com/pierrec/lz4/v4 v4.1.18/go.mod h1:gZWDp/Ze/IJXGXf23ltt2EXimqmTUXEy0GFuRQyBid4= github.com/pingcap/errors v0.11.4 h1:lFuQV/oaUMGcD2tqt+01ROSmJs75VG1ToEOkZIZ4nE4= github.com/pingcap/errors v0.11.4/go.mod h1:Oi8TUi2kEtXXLMJk9l1cGmz20kV3TaQ0usTwv5KuLY8= github.com/pion/datachannel v1.5.8 h1:ph1P1NsGkazkjrvyMfhRBUAWMxugJjq2HfQifaOoSNo= @@ -871,11 +875,13 @@ github.com/sirupsen/logrus v1.9.3/go.mod h1:naHLuLoDiP4jHNo9R0sCBMtWGeIprob74mVs github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966 h1:JIAuq3EEf9cgbU6AtGPK4CTG3Zf6CKMNqf0MHTggAUA= github.com/skratchdot/open-golang v0.0.0-20200116055534-eef842397966/go.mod h1:sUM3LWHvSMaG192sy56D9F7CNvL7jUJVXoqM1QKLnog= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= -github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac h1:wbW+Bybf9pXxnCFAOWZTqkRjAc7rAIwo2e1ArUhiHxg= github.com/smartystreets/assertions v0.0.0-20190215210624-980c5ac6f3ac/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= +github.com/smartystreets/assertions v1.2.0 h1:42S6lae5dvLc7BrLu/0ugRtcFVjoJNMC/N3yZFZkDFs= +github.com/smartystreets/assertions v1.2.0/go.mod h1:tcbTF8ujkAEcZ8TElKY+i30BzYlVhC/LOxJk7iOWnoo= github.com/smartystreets/goconvey v0.0.0-20181108003508-044398e4856c/go.mod h1:XDJAKZRPZ1CvBcN2aX5YOUTYGHki24fSF0Iv48Ibg0s= -github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff h1:86HlEv0yBCry9syNuylzqznKXDK11p6D0DT596yNMys= github.com/smartystreets/goconvey v0.0.0-20190306220146-200a235640ff/go.mod h1:KSQcGKpxUMHk3nbYzs/tIBAM2iDooCn0BmttHOJEbLs= +github.com/smartystreets/goconvey v1.7.2 h1:9RBaZCeXEQ3UselpuwUQHltGVXvdwm6cv1hgR6gDIPg= +github.com/smartystreets/goconvey v1.7.2/go.mod h1:Vw0tHAZW6lzCRk3xgdin6fKYcG+G3Pg9vgXWeJpQFMM= github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= github.com/songgao/water v0.0.0-20190725173103-fd331bda3f4b/go.mod h1:P5HUIBuIWKbyjl083/loAegFkfbFNx5i2qEP4CNbm7E= github.com/songgao/water v0.0.0-20200317203138-2b4b6d7c09d8 h1:TG/diQgUe0pntT/2D9tmUCz4VNwm9MfrtPr0SU2qSX8= @@ -976,8 +982,8 @@ go.etcd.io/bbolt v1.3.10/go.mod h1:bK3UQLPJZly7IlNmV7uVHJDxfe5aK9Ll93e/74Y9oEQ= go.opencensus.io v0.20.1/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.20.2/go.mod h1:6WKK9ahsWS3RSO+PY9ZHZUfv2irvY6gN279GOPZjmmk= go.opencensus.io v0.22.3/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0 h1:KfYpVmrjI7JuToy5k8XV3nkapjWx48k4E4JOtVstzQI= -go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.44.0/go.mod h1:SeQhzAEccGVZVEy7aH87Nh0km+utSpo1pTv6eMMop48= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0 h1:pginetY7+onl4qN1vl0xW/V/v6OBZ0vVdH+esuJgvmM= +go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.42.0/go.mod h1:XiYsayHc36K3EByOO6nbAXnAWbrUxdjUROCEeeROOH8= go.opentelemetry.io/otel v1.19.0 h1:MuS/TNf4/j4IXsZuJegVzI1cwut7Qc00344rgH7p8bs= go.opentelemetry.io/otel v1.19.0/go.mod h1:i0QyjOq3UPoTzff0PJB2N66fb4S0+rSbSB15/oyH9fY= go.opentelemetry.io/otel/exporters/otlp/otlpmetric v0.42.0 h1:ZtfnDL+tUrs1F0Pzfwbg2d59Gru9NCH3bgSHBM6LDwU= @@ -996,8 +1002,8 @@ go.opentelemetry.io/otel/sdk/metric v1.19.0 h1:EJoTO5qysMsYCa+w4UghwFV/ptQgqSL/8 go.opentelemetry.io/otel/sdk/metric v1.19.0/go.mod h1:XjG0jQyFJrv2PbMvwND7LwCEhsJzCzV5210euduKcKY= go.opentelemetry.io/otel/trace v1.19.0 h1:DFVQmlVbfVeOuBRrwdtaehRrWiL1JoVs9CPIQ1Dzxpg= go.opentelemetry.io/otel/trace v1.19.0/go.mod h1:mfaSyvGyEJEI0nyV2I4qhNQnbBOUUmYZpYojqMnX2vo= -go.opentelemetry.io/proto/otlp v1.3.1 h1:TrMUixzpM0yuc/znrFTP9MMRh8trP93mkCiDVeXrui0= -go.opentelemetry.io/proto/otlp v1.3.1/go.mod h1:0X1WI4de4ZsLrrJNLAQbFeLCm3T7yBkR0XqQ7niQU+8= +go.opentelemetry.io/proto/otlp v1.0.0 h1:T0TX0tmXU8a3CbNXzEKGeU5mIVOdf0oykP+u2lIVU/I= +go.opentelemetry.io/proto/otlp v1.0.0/go.mod h1:Sy6pihPLfYHkr3NkUbEhGHFhINUSI/v80hjKIs5JXpM= go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/atomic v1.11.0 h1:ZvwS0R+56ePWxUNi+Atn9dWONBPp/AUETXlHW0DxSjE= @@ -1196,6 +1202,7 @@ golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGm golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190312170243-e65039ee4138/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= +golang.org/x/tools v0.0.0-20190328211700-ab21143f2384/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= golang.org/x/tools v0.0.0-20190524140312-2c0ae7006135/go.mod h1:RgjU9mgBXZiqYHBnxXauZ1Gv1EHHAz9KjViQ78xBX0Q= golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo= golang.org/x/tools v0.1.5/go.mod h1:o0xws9oXOQQZyjljx8fwUC0k7L1pTE6eaCbjGeHmOkk= diff --git a/internalsdk/auth/auth.go b/internalsdk/auth/auth.go index 0c6a178e9..3dabc143f 100644 --- a/internalsdk/auth/auth.go +++ b/internalsdk/auth/auth.go @@ -4,6 +4,7 @@ import ( "context" "net/http" "strings" + "time" "github.com/getlantern/flashlight/v7/proxied" "github.com/getlantern/golog" @@ -12,7 +13,6 @@ import ( "github.com/getlantern/lantern-client/internalsdk/protos" "github.com/getlantern/lantern-client/internalsdk/webclient" - "github.com/getlantern/lantern-client/internalsdk/webclient/defaultwebclient" "github.com/go-resty/resty/v2" ) @@ -21,8 +21,7 @@ var ( ) type authClient struct { - webclient webclient.RESTClient - userConfig func() common.UserConfig + webclient.RESTClient } type AuthClient interface { @@ -30,7 +29,6 @@ type AuthClient interface { SignUp(email string, password string) ([]byte, error) SignupEmailResendCode(ctx context.Context, data *protos.SignupEmailResendRequest) (bool, error) SignupEmailConfirmation(ctx context.Context, data *protos.ConfirmSignupRequest) (bool, error) - //Login methods GetSalt(ctx context.Context, email string) (*protos.GetSaltResponse, error) LoginPrepare(ctx context.Context, loginData *protos.PrepareRequest) (*protos.PrepareResponse, error) @@ -44,31 +42,26 @@ type AuthClient interface { // Complete change email methods CompleteChangeEmail(ctx context.Context, loginData *protos.CompleteChangeEmailRequest) (bool, error) DeleteAccount(ctc context.Context, loginData *protos.DeleteUserRequest) (bool, error) - //Logout SignOut(ctx context.Context, logoutData *protos.LogoutRequest) (bool, error) } // NewClient creates a new instance of AuthClient -func NewClient(baseURL string, opts *webclient.Opts) AuthClient { - httpClient := opts.HttpClient - if httpClient == nil { - // The default http.RoundTripper is ChainedNonPersistent which proxies requests through chained servers - // and does not use keep alive connections. Since no root CA is specified, we do not need to check for an error. - rt, _ := proxied.ChainedNonPersistent("") - httpClient = pro.NewHTTPClient(rt, opts) - } - - wc := webclient.NewRESTClient(defaultwebclient.SendToURL(httpClient, baseURL, - func(client *resty.Client, req *http.Request) error { - prepareUserRequest(req, opts.UserConfig()) +func NewClient(baseURL string, userConfig func() common.UserConfig) AuthClient { + // The default http.RoundTripper is ChainedNonPersistent which proxies requests through chained servers + // and does not use keep alive connections. Since no root CA is specified, we do not need to check for an error. + rt, _ := proxied.ChainedNonPersistent("") + rc := webclient.NewRESTClient(&webclient.Opts{ + BaseURL: baseURL, + OnBeforeRequest: func(client *resty.Client, req *http.Request) error { + prepareUserRequest(req, userConfig()) return nil - }, nil)) + }, + HttpClient: pro.NewHTTPClient(rt, 30*time.Second), + UserConfig: userConfig, + }) - return &authClient{ - userConfig: opts.UserConfig, - webclient: wc, - } + return &authClient{rc} } func prepareUserRequest(r *http.Request, uc common.UserConfig) { @@ -90,7 +83,7 @@ func prepareUserRequest(r *http.Request, uc common.UserConfig) { // GetSalt is used to get the salt for a given email address func (c *authClient) GetSalt(ctx context.Context, email string) (*protos.GetSaltResponse, error) { var resp protos.GetSaltResponse - err := c.webclient.GetPROTOC(ctx, "/users/salt", map[string]interface{}{ + err := c.GetPROTOC(ctx, "/users/salt", map[string]interface{}{ "email": email, }, &resp) if err != nil { @@ -103,7 +96,7 @@ func (c *authClient) GetSalt(ctx context.Context, email string) (*protos.GetSalt // SignUp is used to sign up a new user with the SignupRequest func (c *authClient) signUp(ctx context.Context, signupData *protos.SignupRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/signup", nil, signupData, &resp) + err := c.PostPROTOC(ctx, "/users/signup", nil, signupData, &resp) if err != nil { return false, err } @@ -114,7 +107,7 @@ func (c *authClient) signUp(ctx context.Context, signupData *protos.SignupReques // Params: ctx context.Context, data *protos.SignupEmailResendRequest func (c *authClient) SignupEmailResendCode(ctx context.Context, data *protos.SignupEmailResendRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/signup/resend/email", nil, data, &resp) + err := c.PostPROTOC(ctx, "/users/signup/resend/email", nil, data, &resp) if err != nil { return false, err } @@ -125,7 +118,7 @@ func (c *authClient) SignupEmailResendCode(ctx context.Context, data *protos.Sig // Params: ctx context.Context, data *protos.ConfirmSignupRequest func (c *authClient) SignupEmailConfirmation(ctx context.Context, data *protos.ConfirmSignupRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/signup/complete/email", nil, data, &resp) + err := c.PostPROTOC(ctx, "/users/signup/complete/email", nil, data, &resp) if err != nil { return false, err } @@ -135,7 +128,7 @@ func (c *authClient) SignupEmailConfirmation(ctx context.Context, data *protos.C // LoginPrepare does the initial login preparation with come make sure the user exists and match user salt func (c *authClient) LoginPrepare(ctx context.Context, loginData *protos.PrepareRequest) (*protos.PrepareResponse, error) { var model protos.PrepareResponse - err := c.webclient.PostPROTOC(ctx, "/users/prepare", nil, loginData, &model) + err := c.PostPROTOC(ctx, "/users/prepare", nil, loginData, &model) if err != nil { // Send custom error to show error on client side return nil, log.Errorf("user_not_found %v", err) @@ -146,7 +139,7 @@ func (c *authClient) LoginPrepare(ctx context.Context, loginData *protos.Prepare // Login is used to login a user with the LoginRequest func (c *authClient) login(ctx context.Context, loginData *protos.LoginRequest) (*protos.LoginResponse, error) { var resp protos.LoginResponse - err := c.webclient.PostPROTOC(ctx, "/users/login", nil, loginData, &resp) + err := c.PostPROTOC(ctx, "/users/login", nil, loginData, &resp) if err != nil { return nil, err } @@ -157,7 +150,7 @@ func (c *authClient) login(ctx context.Context, loginData *protos.LoginRequest) // StartRecoveryByEmail is used to start the recovery process by sending a recovery code to the user's email func (c *authClient) StartRecoveryByEmail(ctx context.Context, loginData *protos.StartRecoveryByEmailRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/recovery/start/email", nil, loginData, &resp) + err := c.PostPROTOC(ctx, "/users/recovery/start/email", nil, loginData, &resp) if err != nil { return false, err } @@ -167,7 +160,7 @@ func (c *authClient) StartRecoveryByEmail(ctx context.Context, loginData *protos // CompleteRecoveryByEmail is used to complete the recovery process by validating the recovery code func (c *authClient) CompleteRecoveryByEmail(ctx context.Context, loginData *protos.CompleteRecoveryByEmailRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/recovery/complete/email", nil, loginData, &resp) + err := c.PostPROTOC(ctx, "/users/recovery/complete/email", nil, loginData, &resp) if err != nil { return false, err } @@ -178,7 +171,7 @@ func (c *authClient) CompleteRecoveryByEmail(ctx context.Context, loginData *pro func (c *authClient) ValidateEmailRecoveryCode(ctx context.Context, recoveryData *protos.ValidateRecoveryCodeRequest) (*protos.ValidateRecoveryCodeResponse, error) { var resp protos.ValidateRecoveryCodeResponse log.Debugf("ValidateEmailRecoveryCode request is %v", recoveryData) - err := c.webclient.PostPROTOC(ctx, "/users/recovery/validate/email", nil, recoveryData, &resp) + err := c.PostPROTOC(ctx, "/users/recovery/validate/email", nil, recoveryData, &resp) if err != nil { return nil, err } @@ -191,7 +184,7 @@ func (c *authClient) ValidateEmailRecoveryCode(ctx context.Context, recoveryData // ChangeEmail is used to change the email address of a user func (c *authClient) ChangeEmail(ctx context.Context, loginData *protos.ChangeEmailRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/change_email", nil, loginData, &resp) + err := c.PostPROTOC(ctx, "/users/change_email", nil, loginData, &resp) if err != nil { return false, err } @@ -201,7 +194,7 @@ func (c *authClient) ChangeEmail(ctx context.Context, loginData *protos.ChangeEm // CompleteChangeEmail is used to complete the email change process func (c *authClient) CompleteChangeEmail(ctx context.Context, loginData *protos.CompleteChangeEmailRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/change_email/complete/email", nil, loginData, &resp) + err := c.PostPROTOC(ctx, "/users/change_email/complete/email", nil, loginData, &resp) if err != nil { return false, err } @@ -212,7 +205,7 @@ func (c *authClient) CompleteChangeEmail(ctx context.Context, loginData *protos. // Once account is delete make sure to create new account func (c *authClient) DeleteAccount(ctx context.Context, accountData *protos.DeleteUserRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/delete", nil, accountData, &resp) + err := c.PostPROTOC(ctx, "/users/delete", nil, accountData, &resp) if err != nil { return false, err } @@ -223,7 +216,7 @@ func (c *authClient) DeleteAccount(ctx context.Context, accountData *protos.Dele // Once account is delete make sure to create new account func (c *authClient) SignOut(ctx context.Context, logoutData *protos.LogoutRequest) (bool, error) { var resp protos.EmptyResponse - err := c.webclient.PostPROTOC(ctx, "/users/logout", nil, logoutData, &resp) + err := c.PostPROTOC(ctx, "/users/logout", nil, logoutData, &resp) if err != nil { return false, err } diff --git a/internalsdk/pro/http.go b/internalsdk/pro/http.go index f896c9447..738f82abf 100644 --- a/internalsdk/pro/http.go +++ b/internalsdk/pro/http.go @@ -5,13 +5,11 @@ import ( "time" "github.com/getlantern/flashlight/v7/proxied" - "github.com/getlantern/lantern-client/internalsdk/webclient" ) // NewHTTPClient creates a new http.Client that is configured to use the given options and http.RoundTripper wrapped with // proxied.AsRoundTripper to process requests -func NewHTTPClient(rt http.RoundTripper, opts *webclient.Opts) *http.Client { - timeout := opts.Timeout +func NewHTTPClient(rt http.RoundTripper, timeout time.Duration) *http.Client { if timeout == 0 { timeout = 30 * time.Second } diff --git a/internalsdk/pro/pro.go b/internalsdk/pro/pro.go index c6e7b0bd2..5b04b1bda 100644 --- a/internalsdk/pro/pro.go +++ b/internalsdk/pro/pro.go @@ -13,7 +13,6 @@ import ( "github.com/getlantern/lantern-client/internalsdk/common" "github.com/getlantern/lantern-client/internalsdk/protos" "github.com/getlantern/lantern-client/internalsdk/webclient" - "github.com/getlantern/lantern-client/internalsdk/webclient/defaultwebclient" "github.com/go-resty/resty/v2" "github.com/leekchan/accounting" @@ -27,11 +26,12 @@ var ( ) type proClient struct { + webclient.RESTClient userConfig func() common.UserConfig - webclient webclient.RESTClient } type ProClient interface { + webclient.RESTClient EmailExists(ctx context.Context, email string) (*protos.BaseResponse, error) PaymentMethods(ctx context.Context) (*PaymentMethodsResponse, error) PaymentMethodsV4(ctx context.Context) (*PaymentMethodsResponse, error) @@ -54,26 +54,29 @@ type ProClient interface { // NewClient creates a new instance of ProClient func NewClient(baseURL string, opts *webclient.Opts) ProClient { - httpClient := opts.HttpClient - if httpClient == nil { + if opts.HttpClient == nil { // The default http.RoundTripper used by the ProClient is ParallelForIdempotent which // attempts to send requests through both chained and direct fronted routes in parallel // for HEAD and GET requests and ChainedThenFronted for all others. - httpClient = NewHTTPClient(proxied.ParallelForIdempotent(), opts) + opts.HttpClient = NewHTTPClient(proxied.ParallelForIdempotent(), opts.Timeout) } - wc := webclient.NewRESTClient(defaultwebclient.SendToURL(httpClient, baseURL, - func(client *resty.Client, req *http.Request) error { + if opts.OnBeforeRequest == nil { + opts.OnBeforeRequest = func(client *resty.Client, req *http.Request) error { prepareProRequest(req, common.ProAPIHost, opts.UserConfig()) return nil - }, nil)) + } + } return &proClient{ userConfig: opts.UserConfig, - webclient: wc, + RESTClient: webclient.NewRESTClient(opts), } } // prepareProRequest normalizes requests to the pro server with device ID, user ID, etc set. func prepareProRequest(r *http.Request, proAPIHost string, userConfig common.UserConfig) { + if r.URL.Scheme == "" { + r.URL.Scheme = "http" + } r.URL.Host = proAPIHost r.RequestURI = "" // http: Request.RequestURI can't be set in client requests. r.Header.Set("Access-Control-Allow-Headers", strings.Join([]string{ @@ -96,7 +99,7 @@ func (c *proClient) defaultParams() map[string]interface{} { // XXX Deprecated: See https://github.com/getlantern/lantern-internal/issues/4377 func (c *proClient) EmailExists(ctx context.Context, email string) (*protos.BaseResponse, error) { var resp protos.BaseResponse - err := c.webclient.GetJSON(ctx, "/email-exists", map[string]interface{}{ + err := c.GetJSON(ctx, "/email-exists", map[string]interface{}{ "email": email, }, &resp) if err != nil { @@ -113,7 +116,7 @@ func (c *proClient) PaymentRedirect(ctx context.Context, req *protos.PaymentRedi b, _ := protojson.Marshal(req) params := make(map[string]interface{}) json.Unmarshal(b, ¶ms) - err := c.webclient.GetJSON(ctx, "/payment-redirect", params, &resp) + err := c.GetJSON(ctx, "/payment-redirect", params, &resp) if err != nil { return nil, err } @@ -124,7 +127,7 @@ func (c *proClient) PaymentRedirect(ctx context.Context, req *protos.PaymentRedi // This methods has been deparacted in flavor of PaymentMethodsV4 func (c *proClient) PaymentMethods(ctx context.Context) (*PaymentMethodsResponse, error) { var resp PaymentMethodsResponse - err := c.webclient.GetJSON(ctx, "/plans-v3", c.defaultParams(), &resp) + err := c.GetJSON(ctx, "/plans-v3", c.defaultParams(), &resp) if err != nil { return nil, err } @@ -134,7 +137,7 @@ func (c *proClient) PaymentMethods(ctx context.Context) (*PaymentMethodsResponse // PaymentMethods returns a list of plans, payment providers and logo available payment methods func (c *proClient) PaymentMethodsV4(ctx context.Context) (*PaymentMethodsResponse, error) { var resp PaymentMethodsResponse - err := c.webclient.GetJSON(ctx, "/plans-v4", c.defaultParams(), &resp) + err := c.GetJSON(ctx, "/plans-v4", c.defaultParams(), &resp) if err != nil { return nil, err } @@ -167,7 +170,7 @@ func (c *proClient) PaymentMethodsV4(ctx context.Context) (*PaymentMethodsRespon // Plans is used to hit the legacy /plans endpoint. Deprecated. func (c *proClient) Plans(ctx context.Context) (*PlansResponse, error) { var resp PlansResponse - err := c.webclient.GetJSON(ctx, "/plans", c.defaultParams(), &resp) + err := c.GetJSON(ctx, "/plans", c.defaultParams(), &resp) if err != nil { return nil, err } @@ -191,7 +194,7 @@ func (c *proClient) Plans(ctx context.Context) (*PlansResponse, error) { // UserCreate creates a new user func (c *proClient) UserCreate(ctx context.Context) (*UserDataResponse, error) { var resp UserDataResponse - err := c.webclient.PostFormReadingJSON(ctx, "/user-create", nil, &resp) + err := c.PostFormReadingJSON(ctx, "/user-create", nil, &resp) if err != nil { return nil, errors.New("error fetching user data: %v", err) } @@ -205,7 +208,7 @@ func (c *proClient) UserCreate(ctx context.Context) (*UserDataResponse, error) { // UserData returns data associated with a user func (c *proClient) UserData(ctx context.Context) (*UserDataResponse, error) { var resp UserDataResponse - err := c.webclient.GetJSON(ctx, "/user-data", nil, &resp) + err := c.GetJSON(ctx, "/user-data", nil, &resp) if err != nil { log.Errorf("Failed to fetch user data: %v", err) return nil, errors.New("error fetching user data: %v", err) @@ -217,7 +220,7 @@ func (c *proClient) UserData(ctx context.Context) (*UserDataResponse, error) { // RedeemResellerCode redeems a reseller code for the given user func (c *proClient) RedeemResellerCode(ctx context.Context, req *protos.RedeemResellerCodeRequest) (*protos.BaseResponse, error) { var resp protos.BaseResponse - if err := c.webclient.PostFormReadingJSON(ctx, "/purchase", req, &resp); err != nil { + if err := c.PostFormReadingJSON(ctx, "/purchase", req, &resp); err != nil { log.Errorf("Failed to redeem reseller code: %v", err) return nil, err } @@ -232,7 +235,7 @@ func (c *proClient) DeviceRemove(ctx context.Context, deviceId string) (*LinkRes var resp LinkResponse params := c.defaultParams() params["deviceID"] = deviceId - err := c.webclient.PostJSONReadingJSON(ctx, "/user-link-remove", params, nil, &resp) + err := c.PostJSONReadingJSON(ctx, "/user-link-remove", params, nil, &resp) if err != nil { return nil, err } @@ -245,7 +248,7 @@ func (c *proClient) DeviceAdd(ctx context.Context, deviceName string) (bool, err var resp protos.BaseResponse params := c.defaultParams() params["deviceName"] = deviceName - err := c.webclient.PostJSONReadingJSON(ctx, "/device-add", params, nil, &resp) + err := c.PostJSONReadingJSON(ctx, "/device-add", params, nil, &resp) if err != nil { return false, err } @@ -260,7 +263,7 @@ func (c *proClient) LinkCodeApprove(ctx context.Context, code string) (*protos.B var resp protos.BaseResponse params := c.defaultParams() params["code"] = code - err := c.webclient.PostJSONReadingJSON(ctx, "/link-code-approve", params, nil, &resp) + err := c.PostJSONReadingJSON(ctx, "/link-code-approve", params, nil, &resp) if err != nil { return nil, err } @@ -278,7 +281,7 @@ func (c *proClient) LinkCodeRequest(ctx context.Context, deviceName string) (*Li } var resp LinkCodeResponse uc := c.userConfig() - err := c.webclient.PostJSONReadingJSON(ctx, "/link-code-request", map[string]interface{}{ + err := c.PostJSONReadingJSON(ctx, "/link-code-request", map[string]interface{}{ "deviceName": deviceName, "locale": uc.GetLanguage(), }, nil, &resp) @@ -291,7 +294,7 @@ func (c *proClient) LinkCodeRequest(ctx context.Context, deviceName string) (*Li // LinkCodeRequest returns a code that can be used to link a device to an existing Pro account func (c *proClient) LinkCodeRedeem(ctx context.Context, deviceName string, deviceCode string) (*LinkCodeRedeemResponse, error) { var resp LinkCodeRedeemResponse - err := c.webclient.PostJSONReadingJSON(ctx, "/link-code-redeem", map[string]interface{}{ + err := c.PostJSONReadingJSON(ctx, "/link-code-redeem", map[string]interface{}{ "deviceName": deviceName, "code": deviceCode, }, nil, &resp) @@ -311,7 +314,7 @@ func (c *proClient) UserLinkCodeRequest(ctx context.Context, deviceId string, em } var resp LinkCodeResponse uc := c.userConfig() - err := c.webclient.PostJSONReadingJSON(ctx, "/user-link-request", map[string]interface{}{ + err := c.PostJSONReadingJSON(ctx, "/user-link-request", map[string]interface{}{ "deviceName": deviceId, "locale": uc.GetLanguage(), "email": email, @@ -329,7 +332,7 @@ func (c *proClient) UserLinkCodeRequest(ctx context.Context, deviceId string, em func (c *proClient) UserLinkValidate(ctx context.Context, code string) (*UserRecovery, error) { var resp UserRecovery uc := c.userConfig() - err := c.webclient.PostJSONReadingJSON(ctx, "/user-link-validate", map[string]interface{}{ + err := c.PostJSONReadingJSON(ctx, "/user-link-validate", map[string]interface{}{ "code": code, "locale": uc.GetLanguage(), }, nil, &resp) @@ -346,7 +349,7 @@ func (c *proClient) UserLinkValidate(ctx context.Context, code string) (*UserRec // PurchaseRequest is used to request a purchase of a Pro plan is will be used for all most all the payment providers func (c *proClient) PurchaseRequest(ctx context.Context, req map[string]interface{}) (*PurchaseResponse, error) { var resp PurchaseResponse - err := c.webclient.PostFormReadingJSON(ctx, "/purchase", req, &resp) + err := c.PostFormReadingJSON(ctx, "/purchase", req, &resp) if err != nil { return nil, err } @@ -361,7 +364,7 @@ func (c *proClient) ReferralAttach(ctx context.Context, refCode string) (bool, e var resp protos.BaseResponse params := c.defaultParams() params["code"] = refCode - err := c.webclient.PostFormReadingJSON(ctx, "/referral-attach", params, &resp) + err := c.PostFormReadingJSON(ctx, "/referral-attach", params, &resp) if err != nil { return false, err } diff --git a/internalsdk/pro/proxy.go b/internalsdk/pro/proxy.go index d3e43fc80..61fb3f70c 100644 --- a/internalsdk/pro/proxy.go +++ b/internalsdk/pro/proxy.go @@ -10,10 +10,10 @@ import ( "net/http/httputil" "strconv" "strings" + "time" "github.com/getlantern/lantern-client/internalsdk/common" "github.com/getlantern/lantern-client/internalsdk/protos" - "github.com/getlantern/lantern-client/internalsdk/webclient" ) type proxyTransport struct { @@ -45,7 +45,7 @@ func (pt *proxyTransport) RoundTrip(req *http.Request) (resp *http.Response, err origin := req.Header.Get("Origin") // Workaround for https://github.com/getlantern/pro-server/issues/192 req.Header.Del("Origin") - resp, err = NewHTTPClient(http.DefaultTransport, &webclient.Opts{}).Do(req) + resp, err = NewHTTPClient(http.DefaultTransport, time.Duration(time.Second*30)).Do(req) if err != nil { log.Errorf("Could not issue HTTP request? %v", err) return diff --git a/internalsdk/session_model.go b/internalsdk/session_model.go index 742bce411..f5e4188a6 100644 --- a/internalsdk/session_model.go +++ b/internalsdk/session_model.go @@ -174,7 +174,7 @@ func NewSessionModel(mdb minisql.DB, opts *SessionModelOpts) (*SessionModel, err }, } m.proClient = pro.NewClient(fmt.Sprintf("https://%s", common.ProAPIHost), webclientOpts) - m.authClient = auth.NewClient(fmt.Sprintf("https://%s", common.V1BaseUrl), webclientOpts) + m.authClient = auth.NewClient(fmt.Sprintf("https://%s", common.V1BaseUrl), webclientOpts.UserConfig) m.baseModel.doInvokeMethod = m.doInvokeMethod go m.initSessionModel(context.Background(), opts) diff --git a/internalsdk/webclient/common.go b/internalsdk/webclient/common.go index acdf8b220..c11a9d601 100644 --- a/internalsdk/webclient/common.go +++ b/internalsdk/webclient/common.go @@ -1,24 +1,12 @@ package webclient import ( - "net/http" "strconv" - "time" "github.com/getlantern/lantern-client/internalsdk/common" "github.com/go-resty/resty/v2" ) -// Opts are common Opts that instances of RESTClient may be configured with -type Opts struct { - // HttpClient represents an http.Client that should be used by the resty client - HttpClient *http.Client - // UserConfig is a function that returns the user config associated with a Lantern user - UserConfig func() common.UserConfig - // Timeout represents a time limit for requests made by the web client - Timeout time.Duration -} - // AddCommonUserHeaders adds all common headers that are user or device specific. func AddCommonUserHeaders(uc common.UserConfig, req *resty.Request) { params := map[string]string{} diff --git a/internalsdk/webclient/defaultwebclient/rest.go b/internalsdk/webclient/defaultwebclient/rest.go deleted file mode 100644 index d131fe288..000000000 --- a/internalsdk/webclient/defaultwebclient/rest.go +++ /dev/null @@ -1,83 +0,0 @@ -package defaultwebclient - -import ( - "context" - "fmt" - "net/http" - "unicode" - - "github.com/getlantern/errors" - "github.com/getlantern/golog" - "github.com/getlantern/lantern-client/internalsdk/webclient" - "github.com/moul/http2curl" - - "github.com/go-resty/resty/v2" -) - -var ( - log = golog.LoggerFor("defaultwebclient") -) - -// Create function that sends requests to the given URL, optionally sending them through a proxy, -// optionally processing requests with the given beforeRequest middleware and/or responses with the given afterResponse middleware. -func SendToURL(httpClient *http.Client, baseURL string, beforeRequest resty.PreRequestHook, afterResponse resty.ResponseMiddleware) webclient.SendRequest { - c := resty.NewWithClient(httpClient) - if beforeRequest != nil { - c.SetPreRequestHook(beforeRequest) - } - if afterResponse != nil { - c.OnAfterResponse(afterResponse) - } - c.SetBaseURL(baseURL) - - return func(ctx context.Context, method string, path string, reqParams any, body []byte) ([]byte, error) { - req := c.R().SetContext(ctx) - if reqParams != nil { - switch reqParams.(type) { - case map[string]interface{}: - params := reqParams.(map[string]interface{}) - stringParams := make(map[string]string, len(params)) - for key, value := range params { - stringParams[key] = fmt.Sprint(value) - } - if method == http.MethodGet { - req.SetQueryParams(stringParams) - } else { - req.SetFormData(stringParams) - } - default: - req.SetBody(reqParams) - } - } else if body != nil { - req.Body = body - } - - resp, err := req.Execute(method, path) - if err != nil { - return nil, err - } - - command, _ := http2curl.GetCurlCommand(req.RawRequest) - log.Debugf("curl command: %v", command) - responseBody := resp.Body() - // on some cases, we are getting non-printable characters in the response body - cleanedResponseBody := sanitizeResponseBody(responseBody) - - log.Debugf("response body: %v status code %v", string(responseBody), resp.StatusCode()) - - if resp.StatusCode() < 200 || resp.StatusCode() >= 300 { - return nil, errors.New("%s status code %d", string(cleanedResponseBody), resp.StatusCode()) - } - return responseBody, nil - } -} - -func sanitizeResponseBody(data []byte) []byte { - var cleaned []byte - for _, b := range data { - if unicode.IsPrint(rune(b)) { - cleaned = append(cleaned, b) - } - } - return cleaned -} diff --git a/internalsdk/webclient/webclient.go b/internalsdk/webclient/webclient.go index 5b310f7e6..f6abe1666 100644 --- a/internalsdk/webclient/webclient.go +++ b/internalsdk/webclient/webclient.go @@ -3,9 +3,18 @@ package webclient import ( "context" "encoding/json" + "time" + + "fmt" "net/http" + "unicode" + "github.com/getlantern/errors" "github.com/getlantern/golog" + "github.com/getlantern/lantern-client/internalsdk/common" + "github.com/go-resty/resty/v2" + + "github.com/moul/http2curl" "google.golang.org/protobuf/proto" "google.golang.org/protobuf/reflect/protoreflect" ) @@ -14,6 +23,22 @@ var ( log = golog.LoggerFor("webclient") ) +// Opts are common options that RESTClient may be configured with +type Opts struct { + // The OnAfterResponse option sets response middleware + OnAfterResponse resty.ResponseMiddleware + // BaseURL is the primary URL the client is configured with + BaseURL string + // The OnBeforeRequest option appends the given request middleware into the before request chain. + OnBeforeRequest resty.PreRequestHook + // HttpClient represents an http.Client that should be used by the resty client + HttpClient *http.Client + // UserConfig is a function that returns the user config associated with a Lantern user + UserConfig func() common.UserConfig + // Timeout represents a time limit for requests made by the web client + Timeout time.Duration +} + type RESTClient interface { // Gets a JSON document from the given path with the given querystring parameters, reading the result into target. GetJSON(ctx context.Context, path string, params, target any) error @@ -38,12 +63,80 @@ type RESTClient interface { type SendRequest func(ctx context.Context, method string, path string, params any, body []byte) ([]byte, error) type restClient struct { + *resty.Client send SendRequest } // Construct a REST client using the given SendRequest function -func NewRESTClient(send SendRequest) RESTClient { - return &restClient{send} +func NewRESTClient(opts *Opts) RESTClient { + if opts.HttpClient == nil { + opts.HttpClient = &http.Client{} + } + c := resty.NewWithClient(opts.HttpClient) + return &restClient{c, sendToURL(c, opts)} +} + +// sendToURL is a function that sends requests to the given URL, optionally sending them through a proxy, optionally processing requests +// with the given beforeRequest middleware and/or responses with the given afterResponse middleware. +func sendToURL(c *resty.Client, opts *Opts) SendRequest { + if opts.OnBeforeRequest != nil { + c.SetPreRequestHook(opts.OnBeforeRequest) + } + if opts.OnAfterResponse != nil { + c.OnAfterResponse(opts.OnAfterResponse) + } + c.SetBaseURL(opts.BaseURL) + + return func(ctx context.Context, method string, path string, reqParams any, body []byte) ([]byte, error) { + req := c.R().SetContext(ctx) + if reqParams != nil { + switch reqParams.(type) { + case map[string]interface{}: + params := reqParams.(map[string]interface{}) + stringParams := make(map[string]string, len(params)) + for key, value := range params { + stringParams[key] = fmt.Sprint(value) + } + if method == http.MethodGet { + req.SetQueryParams(stringParams) + } else { + req.SetFormData(stringParams) + } + default: + req.SetBody(reqParams) + } + } else if body != nil { + req.Body = body + } + + resp, err := req.Execute(method, path) + if err != nil { + return nil, err + } + + command, _ := http2curl.GetCurlCommand(req.RawRequest) + log.Debugf("curl command: %v", command) + responseBody := resp.Body() + // on some cases, we are getting non-printable characters in the response body + cleanedResponseBody := sanitizeResponseBody(responseBody) + + log.Debugf("response body: %v status code %v", string(responseBody), resp.StatusCode()) + + if resp.StatusCode() < 200 || resp.StatusCode() >= 300 { + return nil, errors.New("%s status code %d", string(cleanedResponseBody), resp.StatusCode()) + } + return responseBody, nil + } +} + +func sanitizeResponseBody(data []byte) []byte { + var cleaned []byte + for _, b := range data { + if unicode.IsPrint(rune(b)) { + cleaned = append(cleaned, b) + } + } + return cleaned } func (c *restClient) GetJSON(ctx context.Context, path string, params, target any) error { diff --git a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved b/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved deleted file mode 100644 index cb4b75775..000000000 --- a/ios/Runner.xcworkspace/xcshareddata/swiftpm/Package.resolved +++ /dev/null @@ -1,14 +0,0 @@ -{ - "pins" : [ - { - "identity" : "sqlite.swift", - "kind" : "remoteSourceControl", - "location" : "https://github.com/stephencelis/SQLite.swift.git", - "state" : { - "revision" : "7a2e3cd27de56f6d396e84f63beefd0267b55ccb", - "version" : "0.14.1" - } - } - ], - "version" : 2 -} diff --git a/macos/Podfile.lock b/macos/Podfile.lock index 896eda6a9..832d891d1 100644 --- a/macos/Podfile.lock +++ b/macos/Podfile.lock @@ -151,4 +151,4 @@ SPEC CHECKSUMS: PODFILE CHECKSUM: b026caf428aef5db8f45e6734a110a98281273f6 -COCOAPODS: 1.14.3 +COCOAPODS: 1.15.2 diff --git a/pubspec.lock b/pubspec.lock index 44b50d585..78b51b8cf 100644 --- a/pubspec.lock +++ b/pubspec.lock @@ -1146,18 +1146,18 @@ packages: dependency: transitive description: name: leak_tracker - sha256: "7f0df31977cb2c0b88585095d168e689669a2cc9b97c309665e3386f3e9d341a" + sha256: "3f87a60e8c63aecc975dda1ceedbc8f24de75f09e4856ea27daf8958f2f0ce05" url: "https://pub.dev" source: hosted - version: "10.0.4" + version: "10.0.5" leak_tracker_flutter_testing: dependency: transitive description: name: leak_tracker_flutter_testing - sha256: "06e98f569d004c1315b991ded39924b21af84cf14cc94791b8aea337d25b57f8" + sha256: "932549fb305594d82d7183ecd9fa93463e9914e1b67cacc34bc40906594a1806" url: "https://pub.dev" source: hosted - version: "3.0.3" + version: "3.0.5" leak_tracker_testing: dependency: transitive description: @@ -1226,10 +1226,10 @@ packages: dependency: transitive description: name: material_color_utilities - sha256: "0e0a020085b65b6083975e499759762399b4475f766c21668c4ecca34ea74e5a" + sha256: f7142bb1154231d7ea5f96bc7bde4bda2a0945d2806bb11670e30b850d56bdec url: "https://pub.dev" source: hosted - version: "0.8.0" + version: "0.11.1" menu_base: dependency: transitive description: @@ -1242,10 +1242,10 @@ packages: dependency: transitive description: name: meta - sha256: "7687075e408b093f36e6bbf6c91878cc0d4cd10f409506f7bc996f68220b9136" + sha256: bdb68674043280c3428e9ec998512fb681678676b3c54e773629ffe74419f8c7 url: "https://pub.dev" source: hosted - version: "1.12.0" + version: "1.15.0" mime: dependency: "direct main" description: @@ -1458,10 +1458,10 @@ packages: dependency: transitive description: name: platform - sha256: "12220bb4b65720483f8fa9450b4332347737cf8213dd2840d8b2c823e47243ec" + sha256: "9b71283fc13df574056616011fb138fd3b793ea47cc509c189a6c3fa5f8a1a65" url: "https://pub.dev" source: hosted - version: "3.1.4" + version: "3.1.5" plugin_platform_interface: dependency: transitive description: @@ -1863,26 +1863,26 @@ packages: dependency: "direct dev" description: name: test - sha256: "7ee446762c2c50b3bd4ea96fe13ffac69919352bd3b4b17bac3f3465edc58073" + sha256: "7ee44229615f8f642b68120165ae4c2a75fe77ae2065b1e55ae4711f6cf0899e" url: "https://pub.dev" source: hosted - version: "1.25.2" + version: "1.25.7" test_api: dependency: transitive description: name: test_api - sha256: "9955ae474176f7ac8ee4e989dadfb411a58c30415bcfb648fa04b2b8a03afa7f" + sha256: "5b8a98dafc4d5c4c9c72d8b31ab2b23fc13422348d2997120294d3bac86b4ddb" url: "https://pub.dev" source: hosted - version: "0.7.0" + version: "0.7.2" test_core: dependency: transitive description: name: test_core - sha256: "2bc4b4ecddd75309300d8096f781c0e3280ca1ef85beda558d33fcbedc2eead4" + sha256: "55ea5a652e38a1dfb32943a7973f3681a60f872f8c3a05a14664ad54ef9c6696" url: "https://pub.dev" source: hosted - version: "0.6.0" + version: "0.6.4" timezone: dependency: transitive description: @@ -2079,10 +2079,10 @@ packages: dependency: transitive description: name: vm_service - sha256: "3923c89304b715fb1eb6423f017651664a03bf5f4b29983627c4da791f74a4ec" + sha256: f652077d0bdf60abe4c1f6377448e8655008eef28f128bc023f7b5e8dfeb48fc url: "https://pub.dev" source: hosted - version: "14.2.1" + version: "14.2.4" watcher: dependency: transitive description: