6
1
mirror of https://git.mills.io/saltyim/saltyim.git synced 2024-06-16 03:48:24 +00:00
prologic-saltyim/client.go
James Mills 4544b1c4cf Remove the use of beeep that causes the PWA on iPhone to crash on startup (#112)
beeep was cuasing the PWA to crash on iPhone with:

```
[Error] Did not parse stylesheet at 'https://salty.mills.io/web/css/micons.woff2' because non CSS MIME types are not allowed in strict mode.
[Log] registering app service worker (app.js, line 12)
[Error] Failed to load resource: the server responded with a status of 404 () (material-components-web.min.css.map, line 0)
[Log] 2022/04/01 08:13:09 connect() (wasm_exec.js, line 22)
[Log] 2022/04/01 08:13:09 creating new client (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Looking up SRV record for _salty._tcp.mills.io" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Using DNSOverHTTPResolver, looking up SRV _salty._tcp.mills.io" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Discovered salty services salty.mills.io" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="map[Accept-Encoding:[br, gzip, deflate] Accept-Ranges:[bytes] Access-Control-Allow-Headers:[*] Access-Control-Allow-Origin:[*] Access-Control-Expose-Headers:[*] Content-Length:[151] Content-Type:[application/json] Date:[Thu, 31 Mar 2022 22:10:02 GMT] Last-Modified:[Mon, 21 Mar 2022 23:59:42 GMT] Vary:[Accept-Encoding, Cookie] X-Salty-Accept-Encoding:[br, gzip, deflate]]" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Discovered endpoint: https://salty.mills.io/inbox/01FYQEP8FS9XBDYZV9ZNRY4ENS" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Discovered capability: accept-encoding: br, gzip, deflate" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Using identity []byte with public key kex1ekt5cru4vs42wnaxppkjn5pexmt2w6uxx9z2mz0fqeuc80e0g9gsggs8ah" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Salty Addr is prologic@mills.io" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Endpoint is https://salty.mills.io/inbox/01FYQEP8FS9XBDYZV9ZNRY4ENS" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Looking up SRV record for _salty._tcp.mills.io" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Using DNSOverHTTPResolver, looking up SRV _salty._tcp.mills.io" (wasm_exec.js, line 22)
[Log] time="2022-04-01T08:13:09+10:00" level=debug msg="Connected to https://salty.mills.io/inbox/01FYQEP8FS9XBDYZV9ZNRY4ENS" (wasm_exec.js, line 22)
[Log] fatal error: panic while printing panic value (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 17 [running]: (wasm_exec.js, line 22)
[Log] runtime.throw({0x19ad82, 0x20}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:992 +0x7 fp=0x1079620 sp=0x10795f8 pc=0x12600007 (wasm_exec.js, line 22)
[Log] runtime.preprintpanics.func1() (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:529 +0x5 fp=0x1079640 sp=0x1079620 pc=0x12550005 (wasm_exec.js, line 22)
[Log] runtime.deferCallSave(0x1079718, 0x1db388) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:750 +0xe fp=0x1079658 sp=0x1079640 pc=0x125c000e (wasm_exec.js, line 22)
[Log] runtime.runOpenDeferFrame(0x12a0ea0, 0x103fb30) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:723 +0x33 fp=0x10796a0 sp=0x1079658 pc=0x125b0033 (wasm_exec.js, line 22)
[Log] panic({0xcc2e0, 0x12bb800}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:838 +0x29 fp=0x1079758 sp=0x10796a0 pc=0x125d0029 (wasm_exec.js, line 22)
[Log] runtime.panicwrap() (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/error.go:328 +0x1c fp=0x1079890 sp=0x1079758 pc=0x1090001c (wasm_exec.js, line 22)
[Log] syscall/js.(*Error).Error(0x0) (wasm_exec.js, line 22)
[Log] 	<autogenerated>:1 +0x5 fp=0x10798b8 sp=0x1079890 pc=0x178d0005 (wasm_exec.js, line 22)
[Log] runtime.preprintpanics(0x1079988) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:535 +0xa fp=0x1079910 sp=0x10798b8 pc=0x1256000a (wasm_exec.js, line 22)
[Log] panic({0x15d200, 0x0}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:939 +0x53 fp=0x10799c8 sp=0x1079910 pc=0x125d0053 (wasm_exec.js, line 22)
[Log] github.com/gen2brain/beeep.Notify.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/prologic/beeep@v0.0.0-20220331052839-35525ae5ee34/notify_js.go:25 +0xb fp=0x10799f0 sp=0x10799c8 pc=0x42c5000b (wasm_exec.js, line 22)
[Log] runtime.deferCallSave(0x1079ac8, 0x1079c10) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:750 +0xe fp=0x1079a08 sp=0x10799f0 pc=0x125c000e (wasm_exec.js, line 22)
[Log] runtime.runOpenDeferFrame(0x12a0ea0, 0x103fae0) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:723 +0x33 fp=0x1079a50 sp=0x1079a08 pc=0x125b0033 (wasm_exec.js, line 22)
[Log] panic({0xbc2a0, 0x1294ca8}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/panic.go:838 +0x29 fp=0x1079b08 sp=0x1079a50 pc=0x125d0029 (wasm_exec.js, line 22)
[Log] syscall/js.Value.Get({{}, 0x0, 0x0}, {0x18d181, 0xa}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/syscall/js/js.go:288 +0xc fp=0x1079b48 sp=0x1079b08 pc=0x174e000c (wasm_exec.js, line 22)
[Log] github.com/gen2brain/beeep.Notify({0x18bd62, 0x8}, {0x1976d0, 0x1c}, {0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/prologic/beeep@v0.0.0-20220331052839-35525ae5ee34/notify_js.go:35 +0x8 fp=0x1079c78 sp=0x1079b48 pc=0x42c30008 (wasm_exec.js, line 22)
[Log] github.com/gen2brain/beeep.Alert({0x18bd62, 0x8}, {0x1976d0, 0x1c}, {0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/prologic/beeep@v0.0.0-20220331052839-35525ae5ee34/alert_js.go:8 +0x2 fp=0x1079cc0 sp=0x1079c78 pc=0x42bf0002 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).processMessage(0x1296940, 0x1297640, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:147 +0x2 fp=0x1079e30 sp=0x1079cc0 pc=0x4f610002 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).Read(0x1296940, {0x0, 0x0}, {0x0, 0x0}, {0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:314 +0x17 fp=0x1079ec0 sp=0x1079e30 pc=0x4f6a0017 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).Drain.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:261 +0x5 fp=0x1079fe0 sp=0x1079ec0 pc=0x4f690005 (wasm_exec.js, line 22)
[Log] runtime.goexit() (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/asm_wasm.s:401 +0x1 fp=0x1079fe8 sp=0x1079fe0 pc=0x14480001 (wasm_exec.js, line 22)
[Log] created by go.mills.io/saltyim.(*Client).Drain (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:259 +0x15 (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 1 [chan receive]: (wasm_exec.js, line 22)
[Log] github.com/likexian/doh-go.(*DoH).fastECSQuery(0x103f9f0, {0x288ed0, 0x12af080}, {0x128dc80, 0x2, 0x2}, {0x107ccf0, 0x14}, {0x189fb6, 0x3}, ...) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:225 +0x1a (wasm_exec.js, line 22)
[Log] github.com/likexian/doh-go.(*DoH).ECSQuery(0x103f9f0, {0x288ed0, 0x12af080}, {0x107ccf0, 0x14}, {0x189fb6, 0x3}, {0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:181 +0xc (wasm_exec.js, line 22)
[Log] github.com/likexian/doh-go.(*DoH).Query(...) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:158 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*DNSOverHTTPResolver).LookupSRV(0xc09878, {0x18a96c, 0x5}, {0x18a0e5, 0x3}, {0x107cc51, 0x8}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/resolv.go:62 +0x13 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Addr).Refresh(0x12aec00) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/lookup.go:179 +0xd (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.LookupAddr({0x107cc48, 0x11}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/lookup.go:246 +0x4 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*ProxyLookup).LookupAddr(0x12a3360, {0x107cc48, 0x11}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/lookup.go:271 +0x3 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).getAddr(0x1296940, {0x107cc48, 0x11}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:124 +0x8 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).Lookup(...) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:345 (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim/internal/pwa/components.(*ChatMessage).Render(0x10b4c00) (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/internal/pwa/components/chatmessage.go:27 +0x13 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*Compo).render(0x10b4c00) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/component.go:442 +0x6 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*Compo).mount(0x10b4c00, {0x28cd38, 0x107fc20}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/component.go:293 +0x22 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.mount({0x28cd38, 0x107fc20}, {0x28e000, 0x10b4c00}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/node.go:188 +0x5 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*elem).replaceChildAt(0x128f220, 0x0, {0x28e000, 0x10b4c00}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/element.go:238 +0x8 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*elem).update(0x128f220, {0x28d300, 0x12bda40}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/element.go:172 +0x3f (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.update({0x28d300, 0x128f220}, {0x28d300, 0x12bda40}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/node.go:199 +0x8 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*Compo).updateRoot(0x10b4880) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/component.go:386 +0x5 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*engine).updateComponents(0x107fc20) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/engine.go:419 +0x18 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*engine).start.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/engine.go:347 +0x1c (wasm_exec.js, line 22)
[Log] sync.(*Once).doSlow(0x107fc8c, 0x1271d18) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/sync/once.go:68 +0x9 (wasm_exec.js, line 22)
[Log] sync.(*Once).Do(0x107fc8c, 0x1271d18) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/sync/once.go:59 +0x6 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*engine).start(0x107fc20, {0x288e98, 0x101e040}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/engine.go:323 +0x4 (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.RunWhenOnBrowser() (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/app.go:152 +0x86 (wasm_exec.js, line 22)
[Log] main.main() (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/internal/pwa/main.go:18 +0x2 (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 9 [select]: (wasm_exec.js, line 22)
[Log] github.com/likexian/gokit/xcache/memory.(*Objects).gc(0x1260b80) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/gokit@v0.25.6/xcache/memory/memory.go:244 +0xc (wasm_exec.js, line 22)
[Log] created by github.com/likexian/gokit/xcache/memory.New (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/gokit@v0.25.6/xcache/memory/memory.go:76 +0x12 (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 15 [chan receive]: (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim/internal/pwa/components.(*SaltyChat).connect.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/internal/pwa/components/saltychat.go:116 +0xd (wasm_exec.js, line 22)
[Log] github.com/maxence-charriere/go-app/v9/pkg/app.(*engine).Async.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/engine.go:124 +0x4 (wasm_exec.js, line 22)
[Log] created by github.com/maxence-charriere/go-app/v9/pkg/app.(*engine).Async (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/maxence-charriere/go-app/v9@v9.4.1/pkg/app/engine.go:123 +0xb (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 20 [select]: (wasm_exec.js, line 22)
[Log] github.com/likexian/doh-go.Use.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:122 +0xa (wasm_exec.js, line 22)
[Log] created by github.com/likexian/doh-go.Use (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:119 +0x14 (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 14 [waiting]: (wasm_exec.js, line 22)
[Log] runtime.gopark(0x0, 0x0, 0x0, 0x0, 0x1) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/proc.go:361 +0x27 (wasm_exec.js, line 22)
[Log] runtime.handleEvent() (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/lock_js.go:249 +0x1b (wasm_exec.js, line 22)
[Log] runtime.goexit() (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/runtime/asm_wasm.s:401 +0x1 (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 18 [select]: (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).Drain.func2() (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:284 +0x9 (wasm_exec.js, line 22)
[Log] created by go.mills.io/saltyim.(*Client).Drain (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:281 +0x2c (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 19 [select]: (wasm_exec.js, line 22)
[Log] nhooyr.io/websocket.dial({0x288e98, 0x101e040}, {0x1085740, 0x35}, 0x0) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/nhooyr.io/websocket@v1.8.7/ws_js.go:278 +0x1e (wasm_exec.js, line 22)
[Log] nhooyr.io/websocket.Dial({0x288e98, 0x101e040}, {0x1085740, 0x35}, 0x0) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/nhooyr.io/websocket@v1.8.7/ws_js.go:247 +0x2 (wasm_exec.js, line 22)
[Log] git.mills.io/prologic/msgbus/client.(*Subscriber).connect(0x12aed80) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/git.mills.io/prologic/msgbus@v0.1.13-0.20220329220338-7181b6df1bd6/client/client.go:212 +0x12 (wasm_exec.js, line 22)
[Log] created by git.mills.io/prologic/msgbus/client.(*Subscriber).Start (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/git.mills.io/prologic/msgbus@v0.1.13-0.20220329220338-7181b6df1bd6/client/client.go:247 +0x7 (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 21 [select]: (wasm_exec.js, line 22)
[Log] net/http.(*Transport).RoundTrip(0x1282dc0, 0x10b0d00) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/net/http/roundtrip_js.go:193 +0x8e (wasm_exec.js, line 22)
[Log] net/http.send(0x10b0d00, {0x2857b8, 0x1282dc0}, {0x0, 0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/net/http/client.go:252 +0x88 (wasm_exec.js, line 22)
[Log] net/http.(*Client).send(0x12c0ba0, 0x10b0d00, {0x0, 0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/net/http/client.go:176 +0x11 (wasm_exec.js, line 22)
[Log] net/http.(*Client).do(0x12c0ba0, 0x10b0d00) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/net/http/client.go:725 +0xc5 (wasm_exec.js, line 22)
[Log] net/http.(*Client).Do(...) (wasm_exec.js, line 22)
[Log] 	/usr/local/go/src/net/http/client.go:593 (wasm_exec.js, line 22)
[Log] github.com/likexian/gokit/xhttp.(*Request).Do(0x10b4e00, {0x288e60, 0x12975c0}, {0x189f62, 0x3}, {0x19dac6, 0x24}, {0x1047eb0, 0x2, 0x2}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/gokit@v0.25.6/xhttp/xhttp.go:685 +0x1d5 (wasm_exec.js, line 22)
[Log] github.com/likexian/gokit/xhttp.(*Request).Get(...) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/gokit@v0.25.6/xhttp/xhttp.go:285 (wasm_exec.js, line 22)
[Log] github.com/likexian/doh-go/provider/cloudflare.(*Provider).ECSQuery(0x12ad728, {0x288e60, 0x12975c0}, {0x107ccf0, 0x14}, {0x189fb6, 0x3}, {0x0, 0x0}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/provider/cloudflare/cloudflare.go:110 +0x30 (wasm_exec.js, line 22)
[Log] github.com/likexian/doh-go.(*DoH).fastECSQuery.func1(0x0, {0x2881f8, 0x12ad728}) (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:201 +0x4 (wasm_exec.js, line 22)
[Log] created by github.com/likexian/doh-go.(*DoH).fastECSQuery (wasm_exec.js, line 22)
[Log] 	/home/mattman/go/pkg/mod/github.com/likexian/doh-go@v0.6.4/doh.go:200 +0x5e (wasm_exec.js, line 22)
[Log]  (wasm_exec.js, line 22)
[Log] goroutine 23 [chan receive (nil chan)]: (wasm_exec.js, line 22)
[Log] go.mills.io/saltyim.(*Client).Subscribe.func1() (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:333 +0x5 (wasm_exec.js, line 22)
[Log] created by go.mills.io/saltyim.(*Client).Subscribe (wasm_exec.js, line 22)
[Log] 	/home/mattman/golang/saltyim/client.go:332 +0x26 (wasm_exec.js, line 22)
[Warning] exit code: – 2 (wasm_exec.js, line 101)
[Error] Error: Go program has already exited
	_resume (wasm_exec.js:536)
	(anonymous function) (wasm_exec.js:549)
[Error] Unhandled Promise Rejection: Error: Go program has already exited
	_resume (wasm_exec.js:536)
	(anonymous function) (wasm_exec.js:549)
	promiseReactionJob
```

Which I have no fucking clue what's going on there :/

Co-authored-by: James Mills <prologic@shortcircuit.net.au>
Reviewed-on: https://git.mills.io/saltyim/saltyim/pulls/112
Reviewed-by: xuu <xuu@noreply@mills.io>
Co-authored-by: James Mills <james@mills.io>
Co-committed-by: James Mills <james@mills.io>
2022-03-31 23:06:08 +00:00

392 lines
9.5 KiB
Go

package saltyim
import (
"bytes"
"context"
"crypto/sha256"
"errors"
"fmt"
"net/url"
"os"
"path"
"strings"
"time"
"git.mills.io/prologic/msgbus"
msgbus_client "git.mills.io/prologic/msgbus/client"
"github.com/avast/retry-go"
"github.com/keys-pub/keys"
log "github.com/sirupsen/logrus"
"go.mills.io/salty"
"go.mills.io/saltyim/internal/exec"
)
const (
DefaultEnvPath = "/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin"
ServiceUser = "salty"
)
var (
ErrNoMessages = errors.New("error: no messages found")
ErrClientNotConnected = errors.New("error: client not connected")
)
type addrCache map[string]*Addr
type Message struct {
Text string
Key *keys.EdX25519PublicKey
}
// TODO: Support shell quoting and escapes?
func parseExtraEnvs(extraenvs string) map[string]string {
env := make(map[string]string)
for _, extraenv := range strings.Split(extraenvs, " ") {
tokens := strings.SplitN(extraenv, "=", 2)
switch len(tokens) {
case 1:
env[tokens[0]] = ""
case 2:
env[tokens[0]] = tokens[1]
}
}
return env
}
// PackMessage formts an outoing message in the Message Format
// <timestamp>\t(<sender>) <message>
func PackMessage(me *Addr, msg string) []byte {
return []byte(
fmt.Sprint(
time.Now().UTC().Format(time.RFC3339), "\t",
me.Formatted(), "\t",
strings.TrimSpace(msg), "\n",
),
)
}
// Client is a Salty IM client that handles talking to a Salty IM Broker
// and Sedngina and Receiving messages to/from Salty IM Users.
type Client struct {
me *Addr
id *Identity
key *keys.EdX25519Key
cache addrCache
lookup Lookuper
send Sender
}
// NewClient reeturns a new Salty IM client for sending and receiving
// encrypted messages to other Salty IM users as well as decrypting
// and displaying messages of the user's own inbox.
func NewClient(me *Addr, options ...IdentityOption) (*Client, error) {
id, err := GetIdentity(options...)
if err != nil {
return nil, fmt.Errorf("error opening identity %s: %w", id.Source(), err)
}
if me == nil || me.IsZero() {
me = id.addr
}
if me == nil || me.IsZero() {
return nil, fmt.Errorf("unable to find your user addressn in %s", id.Source())
}
if err := me.Refresh(); err != nil {
log.WithError(err).Warn("error looking up user endpoint")
}
log.Debugf("Using identity %s with public key %s", id.Source(), id.key)
log.Debugf("Salty Addr is %s", me)
log.Debugf("Endpoint is %s", me.Endpoint())
return &Client{
me: me,
id: id,
key: id.key,
cache: make(addrCache),
lookup: &DirectLookup{},
send: &DirectSend{},
}, nil
}
func (cli *Client) getAddr(user string) (*Addr, error) {
addr, ok := cli.cache[user]
if ok {
return addr, nil
}
addr, err := cli.lookup.LookupAddr(user)
if err != nil {
return nil, fmt.Errorf("error: failed to lookup user %s: %w", user, err)
}
cli.cache[user] = addr
return addr, nil
}
func (cli *Client) processMessage(msg *msgbus.Message, extraenvs, prehook, posthook string) (Message, error) {
var data []byte
defer func() {
if posthook != "" {
out, err := exec.RunCmd(exec.DefaultRunCmdTimeout, cli.Env(extraenvs), posthook, bytes.NewBuffer(data))
if err != nil {
log.WithError(err).Debugf("error running post-hook %s", posthook)
}
log.Debugf("post-hook: %q", out)
}
}()
if prehook != "" {
out, err := exec.RunCmd(exec.DefaultRunCmdTimeout, cli.Env(extraenvs), prehook, bytes.NewBuffer(msg.Payload))
if err != nil {
log.WithError(err).Debugf("error running pre-hook %s", prehook)
}
log.Debugf("pre-hook: %q", out)
}
unencrypted, senderKey, err := salty.Decrypt(cli.key, msg.Payload)
if err != nil {
return Message{}, fmt.Errorf("error decrypting message: %w", err)
}
data = unencrypted[:]
return Message{Text: string(data), Key: senderKey}, nil
}
func (cli *Client) messageHandler(extraenvs, prehook, posthook string, msgs chan Message) msgbus.HandlerFunc {
return func(msg *msgbus.Message) error {
message, err := cli.processMessage(msg, extraenvs, prehook, posthook)
if err != nil {
return fmt.Errorf("error processing message: %w", err)
}
msgs <- message
return nil
}
}
func (cli *Client) Me() *Addr { return cli.me }
func (cli *Client) Key() *keys.EdX25519PublicKey { return cli.key.PublicKey() }
func (cli *Client) Env(extraenvs string) []string {
Path := DefaultEnvPath
GoPath := os.Getenv("GOPATH")
if GoPath != "" {
Path = fmt.Sprintf("%s/bin:%s", GoPath, Path)
}
env := []string{
fmt.Sprintf("PATH=%s", Path),
fmt.Sprintf("PWD=%s", os.Getenv("PWD")),
fmt.Sprintf("HOME=%s", os.Getenv("HOME")),
fmt.Sprintf("SALTY_USER=%s", cli.me.String()),
fmt.Sprintf("SALTY_IDENTITY=%s", cli.id.Source()),
}
for key, val := range parseExtraEnvs(extraenvs) {
log.Debugf("key: %q", key)
log.Debugf("val: %q", val)
val = os.ExpandEnv(val)
if val == "" {
val = os.Getenv(key)
}
if val != "" {
env = append(env, fmt.Sprintf("%s=%s", key, val))
}
}
log.Debugf("env: #%v", env)
return env
}
func (cli *Client) Outbox() *url.URL {
ep := cli.me.Endpoint()
ep.Path = path.Join(
path.Dir(ep.Path),
fmt.Sprintf("%x", sha256.Sum256(cli.me.key.Private())),
)
return ep
}
func (cli *Client) OutboxAddr() *Addr {
return &Addr{
endpoint: cli.Outbox(),
key: cli.me.key,
}
}
func (cli *Client) String() string {
b := &bytes.Buffer{}
fmt.Fprintln(b, "Me: ", cli.me)
fmt.Fprintln(b, "Endpoint: ", cli.me.Endpoint())
fmt.Fprintln(b, "Outbox: ", cli.Outbox())
fmt.Fprintln(b, "Key: ", cli.key)
return b.String()
}
// SetLookup sets the internal lookup interface to use (Lookuper) for looking
// up Salty Addresses. By default the DirectLookup implementation is used.
func (cli *Client) SetLookup(lookup Lookuper) {
cli.lookup = lookup
}
// SetSend sets the internal send interface to use (Sender) for sending
// messages to endpoints. By default the DirectSend implementation is used.
func (cli *Client) SetSend(send Sender) {
cli.send = send
}
// Drain drains this user's inbox by simulteneiously reading until empty anda
// subscribing to the inbox for new messages.
func (cli *Client) Drain(ctx context.Context, extraenvs, prehook, posthook string) chan Message {
msgs := make(chan Message)
go func() {
for {
msg, err := cli.Read(extraenvs, prehook, posthook)
if err != nil {
log.Debugf("err: #%v", err)
switch err {
case ErrNoMessages:
log.Debug("no more messages, existing readloop...")
return
case ErrClientNotConnected:
log.Debug("client not connected, existing readloop...")
return
default:
log.WithError(err).Warn("error reading inbox")
}
} else {
msgs <- msg
}
time.Sleep(time.Millisecond * 100)
}
}()
go func() {
msgCh := cli.Subscribe(ctx, extraenvs, prehook, posthook)
for {
select {
case msg := <-msgCh:
msgs <- msg
case <-ctx.Done():
close(msgs)
return
}
}
}()
return msgs
}
// Read reads a single message from this user's inbox
func (cli *Client) Read(extraenvs, prehook, posthook string) (Message, error) {
if cli.me.Endpoint() == nil {
return Message{}, ErrClientNotConnected
}
uri, inbox := SplitInbox(cli.me.Endpoint().String())
bus := msgbus_client.NewClient(uri, nil)
msg, err := bus.Pull(inbox)
if err != nil {
return Message{}, fmt.Errorf("error reading inbox: %w", err)
}
if msg == nil {
return Message{}, ErrNoMessages
}
return cli.processMessage(msg, extraenvs, prehook, posthook)
}
// Subscribe subscribers to this user's inbox for new messages
func (cli *Client) Subscribe(ctx context.Context, extraenvs, prehook, posthook string) chan Message {
if cli.me.Endpoint() == nil {
return nil
}
uri, inbox := SplitInbox(cli.me.Endpoint().String())
bus := msgbus_client.NewClient(uri, nil)
msgs := make(chan Message)
s := bus.Subscribe(inbox, cli.messageHandler(extraenvs, prehook, posthook, msgs))
s.Start()
log.Debugf("Connected to %s/%s", uri, inbox)
go func() {
<-ctx.Done()
s.Stop()
close(msgs)
}()
return msgs
}
// Lookup performs a lookup for a user's address and config
// If the user has an address already cached, the cached addr
// is returned, otherwise a full lookup is done.
func (cli *Client) Lookup(user string) (*Addr, error) {
return cli.getAddr(user)
}
// Send sends an encrypted message to the specified user
func (cli *Client) Send(user, msg string) error {
addr, err := cli.getAddr(user)
if err != nil {
return fmt.Errorf("error looking up user %s: %w", user, err)
}
err = cli.SendToAddr(addr, msg)
if err != nil {
return err
}
return cli.SendToAddr(cli.OutboxAddr(), msg)
}
func (cli *Client) SendToAddr(addr *Addr, msg string) error {
b, err := salty.Encrypt(cli.key, PackMessage(cli.me, msg), []string{addr.key.ID().String()})
if err != nil {
return fmt.Errorf("error encrypting message to %s: %w", addr, err)
}
if err := cli.send.Send(cli.key, addr.Endpoint().String(), string(b), addr.Cap()); err != nil {
return fmt.Errorf("error sending message to %s: %w", addr, err)
}
return nil
}
// Register sends a registration request to the service user of a Salty Broker
func (cli *Client) Register() error {
svc, err := cli.lookup.LookupAddr(fmt.Sprintf("%s@%s", ServiceUser, cli.Me().Domain))
if err != nil {
return fmt.Errorf("error looking up service user on %s: %w", cli.Me().Domain, err)
}
if err := cli.SendToAddr(svc, "REGISTER"); err != nil {
return fmt.Errorf("error sending REGISTER to %s: %w", svc, err)
}
if err := retry.Do(
func() error {
return cli.Me().Refresh()
},
); err != nil {
return fmt.Errorf("error registrating account: %w", err)
}
return nil
}