Merge remote-tracking branch 'upstream/main' into kwsantiago/nwc-mock-client
This commit is contained in:
0
cmd/lerproxy/LICENSE
Normal file → Executable file
0
cmd/lerproxy/LICENSE
Normal file → Executable file
21
cmd/lerproxy/README.md
Normal file → Executable file
21
cmd/lerproxy/README.md
Normal file → Executable file
@@ -6,12 +6,12 @@ DNS verification [NIP-05](https://github.com/nostr-protocol/nips/blob/master/05.
|
||||
|
||||
## Install
|
||||
|
||||
go install lerproxy.mleku.dev@latest
|
||||
go install mleku.dev/lerproxy@latest
|
||||
|
||||
## Run
|
||||
|
||||
```
|
||||
Usage: lerproxy.mleku.dev [--listen LISTEN] [--map MAP] [--rewrites REWRITES] [--cachedir CACHEDIR] [--hsts] [--email EMAIL] [--http HTTP] [--rto RTO] [--wto WTO] [--idle IDLE] [--cert CERT]
|
||||
Usage: mleku.dev/lerproxy [--listen LISTEN] [--map MAP] [--rewrites REWRITES] [--cachedir CACHEDIR] [--hsts] [--email EMAIL] [--http HTTP] [--rto RTO] [--wto WTO] [--idle IDLE] [--cert CERT]
|
||||
|
||||
Options:
|
||||
--listen LISTEN, -l LISTEN
|
||||
@@ -49,7 +49,7 @@ as:
|
||||
* in the launch parameters for `lerproxy` you can now add any number of `--cert` parameters with
|
||||
the domain (including for wildcards), and the path to the `.crt`/`.key` files:
|
||||
|
||||
lerproxy.mleku.dev --cert <domain>:/path/to/TLS_cert
|
||||
mleku.dev/lerproxy --cert <domain>:/path/to/TLS_cert
|
||||
|
||||
this will then, if found, load and parse the TLS certificate and secret key if the suffix of
|
||||
the domain matches. The certificate path is expanded to two files with the above filename
|
||||
@@ -58,17 +58,6 @@ as:
|
||||
> Note that the match is greedy, so you can explicitly separately give a subdomain
|
||||
certificate and it will be selected even if there is a wildcard that also matches.
|
||||
|
||||
# IMPORTANT
|
||||
|
||||
With Comodo SSL (sectigo RSA) certificates you also need to append the intermediate certificate
|
||||
to the `.crt` file in order to get it to work properly with openssl library based tools like
|
||||
wget, curl and the go tool, which is quite important if you want to do subdomains on a wildcard
|
||||
certificate.
|
||||
|
||||
Probably the same applies to some of the other certificate authorities. If you sometimes get
|
||||
issues with CLI tools refusing to accept these certificates on your web server or other, this
|
||||
may be the problem.
|
||||
|
||||
## example mapping.txt
|
||||
|
||||
nostr.example.com: /path/to/nostr.json
|
||||
@@ -96,7 +85,7 @@ Description=lerproxy
|
||||
[Service]
|
||||
Type=simple
|
||||
User=username
|
||||
ExecStart=/usr/local/bin/lerproxy.mleku.dev -m /path/to/mapping.txt -l xxx.xxx.xxx.xxx:443 --http xxx.xxx.xxx.6:80 -m /path/to/mapping.txt -e email@example.com -c /path/to/letsencrypt/cache --cert example.com:/path/to/tls/certs
|
||||
ExecStart=/usr/local/bin/mleku.dev/lerproxy -m /path/to/mapping.txt -l xxx.xxx.xxx.xxx:443 --http xxx.xxx.xxx.6:80 -m /path/to/mapping.txt -e email@example.com -c /path/to/letsencrypt/cache --cert example.com:/path/to/tls/certs
|
||||
Restart=on-failure
|
||||
Wants=network-online.target
|
||||
After=network.target network-online.target wg-quick@wg0.service
|
||||
@@ -114,7 +103,7 @@ a tunnel, such as your dev machine (something I do for nostr relay development)
|
||||
|
||||
The simplest way to allow `lerproxy` to bind to port 80 and 443 is as follows:
|
||||
|
||||
setcap 'cap_net_bind_service=+ep' /path/to/lerproxy.mleku.dev
|
||||
setcap 'cap_net_bind_service=+ep' /path/to/mleku.dev/lerproxy
|
||||
|
||||
## todo
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// Package buf implements a simple concurrent safe buffer pool for raw bytes.
|
||||
package buf
|
||||
|
||||
import "sync"
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// Package hsts implements a HTTP handler that enforces HSTS.
|
||||
package hsts
|
||||
|
||||
import "net/http"
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
// Command lerproxy implements https reverse proxy with automatic LetsEncrypt
|
||||
// usage for multiple hostnames/backends,your own SSL certificates, nostr NIP-05
|
||||
// DNS verification hosting and Go vanity redirects.
|
||||
// usage for multiple hostnames/backends, and URL rewriting capability.
|
||||
package main
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"context"
|
||||
"crypto/tls"
|
||||
_ "embed"
|
||||
"encoding/json"
|
||||
@@ -15,14 +15,6 @@ import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"orly.dev/cmd/lerproxy/buf"
|
||||
"orly.dev/cmd/lerproxy/hsts"
|
||||
"orly.dev/cmd/lerproxy/reverse"
|
||||
"orly.dev/cmd/lerproxy/tcpkeepalive"
|
||||
"orly.dev/cmd/lerproxy/util"
|
||||
"orly.dev/pkg/utils/chk"
|
||||
"orly.dev/pkg/utils/context"
|
||||
"orly.dev/pkg/utils/log"
|
||||
"os"
|
||||
"os/signal"
|
||||
"path/filepath"
|
||||
@@ -34,14 +26,22 @@ import (
|
||||
"github.com/alexflint/go-arg"
|
||||
"golang.org/x/crypto/acme/autocert"
|
||||
"golang.org/x/sync/errgroup"
|
||||
"orly.dev/cmd/lerproxy/buf"
|
||||
"orly.dev/cmd/lerproxy/hsts"
|
||||
"orly.dev/cmd/lerproxy/reverse"
|
||||
"orly.dev/cmd/lerproxy/tcpkeepalive"
|
||||
"orly.dev/cmd/lerproxy/util"
|
||||
"orly.dev/pkg/utils/chk"
|
||||
"orly.dev/pkg/utils/log"
|
||||
)
|
||||
|
||||
//go:embed favicon.ico
|
||||
var defaultFavicon []byte
|
||||
|
||||
type runArgs struct {
|
||||
Addr string `arg:"-l,--listen" default:":https" help:"address to listen at"`
|
||||
Conf string `arg:"-m,--map" default:"mapping.txt" help:"file with host/backend mapping"`
|
||||
Addr string `arg:"-l,--listen" default:":https" help:"address to listen at"`
|
||||
Conf string `arg:"-m,--map" default:"mapping.txt" help:"file with host/backend mapping"`
|
||||
// Rewrites string `arg:"-r,--rewrites" default:"rewrites.txt"`
|
||||
Cache string `arg:"-c,--cachedir" default:"/var/cache/letsencrypt" help:"path to directory to cache key and certificates"`
|
||||
HSTS bool `arg:"-h,--hsts" help:"add Strict-Transport-Security header"`
|
||||
Email string `arg:"-e,--email" help:"contact email address presented to letsencrypt CA"`
|
||||
@@ -49,22 +49,21 @@ type runArgs struct {
|
||||
RTO time.Duration `arg:"-r,--rto" default:"1m" help:"maximum duration before timing out read of the request"`
|
||||
WTO time.Duration `arg:"-w,--wto" default:"5m" help:"maximum duration before timing out write of the response"`
|
||||
Idle time.Duration `arg:"-i,--idle" help:"how long idle connection is kept before closing (set rto, wto to 0 to use this)"`
|
||||
Certs []string `arg:"--cert,separate" help:"certificates and the domain they match: eg: orly.dev:/path/to/cert - this will indicate to load two, one with extension .key and one with .crt, each expected to be PEM encoded TLS private and public keys, respectively"`
|
||||
// Rewrites string `arg:"-r,--rewrites" default:"rewrites.txt"`
|
||||
Certs []string `arg:"--cert,separate" help:"certificates and the domain they match: eg: mleku.dev:/path/to/cert - this will indicate to load two, one with extension .key and one with .crt, each expected to be PEM encoded TLS private and public keys, respectively"`
|
||||
}
|
||||
|
||||
var args runArgs
|
||||
|
||||
func main() {
|
||||
arg.MustParse(&args)
|
||||
ctx, cancel := signal.NotifyContext(context.Bg(), os.Interrupt)
|
||||
ctx, cancel := signal.NotifyContext(context.Background(), os.Interrupt)
|
||||
defer cancel()
|
||||
if err := run(ctx, args); chk.T(err) {
|
||||
if err := run(ctx, args); err != nil {
|
||||
log.F.Ln(err)
|
||||
}
|
||||
}
|
||||
|
||||
func run(c context.T, args runArgs) (err error) {
|
||||
func run(ctx context.Context, args runArgs) (err error) {
|
||||
|
||||
if args.Cache == "" {
|
||||
err = log.E.Err("no cache specified")
|
||||
@@ -83,7 +82,7 @@ func run(c context.T, args runArgs) (err error) {
|
||||
if args.WTO > 0 {
|
||||
srv.WriteTimeout = args.WTO
|
||||
}
|
||||
group, ctx := errgroup.WithContext(c)
|
||||
group, ctx := errgroup.WithContext(ctx)
|
||||
if args.HTTP != "" {
|
||||
httpServer := http.Server{
|
||||
Addr: args.HTTP,
|
||||
@@ -100,8 +99,8 @@ func run(c context.T, args runArgs) (err error) {
|
||||
group.Go(
|
||||
func() error {
|
||||
<-ctx.Done()
|
||||
ctx, cancel := context.Timeout(
|
||||
context.Bg(),
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(),
|
||||
time.Second,
|
||||
)
|
||||
defer cancel()
|
||||
@@ -137,7 +136,9 @@ func run(c context.T, args runArgs) (err error) {
|
||||
group.Go(
|
||||
func() error {
|
||||
<-ctx.Done()
|
||||
ctx, cancel := context.Timeout(context.Bg(), time.Second)
|
||||
ctx, cancel := context.WithTimeout(
|
||||
context.Background(), time.Second,
|
||||
)
|
||||
defer cancel()
|
||||
return srv.Shutdown(ctx)
|
||||
},
|
||||
@@ -328,13 +329,12 @@ func setProxy(mapping map[string]string) (h http.Handler, err error) {
|
||||
)
|
||||
fin := hn + "/favicon.ico"
|
||||
var fi []byte
|
||||
if fi, err = os.ReadFile(fin); chk.E(err) {
|
||||
if fi, err = os.ReadFile(fin); !chk.E(err) {
|
||||
fi = defaultFavicon
|
||||
}
|
||||
mux.HandleFunc(
|
||||
hn+"/favicon.ico",
|
||||
func(writer http.ResponseWriter, request *http.Request) {
|
||||
log.T.F("serving favicon to %s", hn)
|
||||
if _, err = writer.Write(fi); chk.E(err) {
|
||||
return
|
||||
}
|
||||
@@ -376,12 +376,12 @@ func setProxy(mapping map[string]string) (h http.Handler, err error) {
|
||||
)
|
||||
// req.Header.Set("Access-Control-Allow-Credentials", "true")
|
||||
req.Header.Set("Access-Control-Allow-Origin", "*")
|
||||
log.I.Ln(req.URL, req.RemoteAddr)
|
||||
log.D.Ln(req.URL, req.RemoteAddr)
|
||||
},
|
||||
Transport: &http.Transport{
|
||||
DialContext: func(c context.T, n, addr string) (
|
||||
net.Conn, error,
|
||||
) {
|
||||
DialContext: func(
|
||||
ctx context.Context, n, addr string,
|
||||
) (net.Conn, error) {
|
||||
return net.DialTimeout(network, ba, 5*time.Second)
|
||||
},
|
||||
},
|
||||
|
||||
@@ -1,13 +1,12 @@
|
||||
// Package reverse is a copy of httputil.NewSingleHostReverseProxy with addition
|
||||
// of "X-Forwarded-Proto" header.
|
||||
package reverse
|
||||
|
||||
import (
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"net/url"
|
||||
"orly.dev/cmd/lerproxy/util"
|
||||
"orly.dev/pkg/utils/log"
|
||||
|
||||
"orly.dev/cmd/lerproxy/util"
|
||||
)
|
||||
|
||||
// NewSingleHostReverseProxy is a copy of httputil.NewSingleHostReverseProxy
|
||||
|
||||
@@ -1,12 +1,11 @@
|
||||
// Package tcpkeepalive implements a net.TCPListener with a singleton set period
|
||||
// for a default 3 minute keep-aline.
|
||||
package tcpkeepalive
|
||||
|
||||
import (
|
||||
"net"
|
||||
"orly.dev/cmd/lerproxy/timeout"
|
||||
"orly.dev/pkg/utils/chk"
|
||||
"time"
|
||||
|
||||
"orly.dev/cmd/lerproxy/timeout"
|
||||
)
|
||||
|
||||
// Period can be changed prior to opening a Listener to alter its'
|
||||
|
||||
@@ -1,5 +1,3 @@
|
||||
// Package timeout provides a simple extension of a net.TCPConn with a
|
||||
// configurable read/write deadline.
|
||||
package timeout
|
||||
|
||||
import (
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// Package util provides some helpers for lerproxy, a tool to convert maps of
|
||||
// strings to slices of the same strings, and a helper to avoid putting two / in
|
||||
// a URL.
|
||||
package util
|
||||
|
||||
import "strings"
|
||||
@@ -16,7 +16,7 @@ import (
|
||||
// separate from the ownersFollowed list, but there could be reasons for this
|
||||
// distinction, such as rate limiting applying to the former and not the latter.
|
||||
type Lists struct {
|
||||
sync.Mutex
|
||||
sync.RWMutex
|
||||
ownersPubkeys [][]byte
|
||||
ownersFollowed [][]byte
|
||||
followedFollows [][]byte
|
||||
@@ -24,15 +24,15 @@ type Lists struct {
|
||||
}
|
||||
|
||||
func (l *Lists) LenOwnersPubkeys() (ll int) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
ll = len(l.ownersPubkeys)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Lists) OwnersPubkeys() (pks [][]byte) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
pks = append(pks, l.ownersPubkeys...)
|
||||
return
|
||||
}
|
||||
@@ -45,15 +45,15 @@ func (l *Lists) SetOwnersPubkeys(pks [][]byte) {
|
||||
}
|
||||
|
||||
func (l *Lists) LenOwnersFollowed() (ll int) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
ll = len(l.ownersFollowed)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Lists) OwnersFollowed() (pks [][]byte) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
pks = append(pks, l.ownersFollowed...)
|
||||
return
|
||||
}
|
||||
@@ -66,15 +66,15 @@ func (l *Lists) SetOwnersFollowed(pks [][]byte) {
|
||||
}
|
||||
|
||||
func (l *Lists) LenFollowedFollows() (ll int) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
ll = len(l.followedFollows)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Lists) FollowedFollows() (pks [][]byte) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
pks = append(pks, l.followedFollows...)
|
||||
return
|
||||
}
|
||||
@@ -87,15 +87,15 @@ func (l *Lists) SetFollowedFollows(pks [][]byte) {
|
||||
}
|
||||
|
||||
func (l *Lists) LenOwnersMuted() (ll int) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
ll = len(l.ownersMuted)
|
||||
return
|
||||
}
|
||||
|
||||
func (l *Lists) OwnersMuted() (pks [][]byte) {
|
||||
l.Lock()
|
||||
defer l.Unlock()
|
||||
l.RLock()
|
||||
defer l.RUnlock()
|
||||
pks = append(pks, l.ownersMuted...)
|
||||
return
|
||||
}
|
||||
|
||||
@@ -2,7 +2,6 @@ package database
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"orly.dev/pkg/crypto/sha256"
|
||||
"orly.dev/pkg/database/indexes/types"
|
||||
"orly.dev/pkg/encoders/event"
|
||||
@@ -105,14 +104,6 @@ func (d *D) QueryEvents(c context.T, f *filter.F) (evs event.S, err error) {
|
||||
idPkTs = append(idPkTs, deletionIdPkTs...)
|
||||
}
|
||||
// First pass: collect all deletion events
|
||||
log.T.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"Debug: Starting first pass - processing %d events\n",
|
||||
len(idPkTs),
|
||||
)
|
||||
},
|
||||
)
|
||||
for _, idpk := range idPkTs {
|
||||
var ev *event.E
|
||||
ser := new(types.Uint40)
|
||||
@@ -130,14 +121,6 @@ func (d *D) QueryEvents(c context.T, f *filter.F) (evs event.S, err error) {
|
||||
}
|
||||
// Process deletion events to build our deletion maps
|
||||
if ev.Kind.Equal(kind.Deletion) {
|
||||
log.T.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"found deletion event with ID: %s\n",
|
||||
hex.Enc(ev.ID),
|
||||
)
|
||||
},
|
||||
)
|
||||
// Check for 'e' tags that directly reference event IDs
|
||||
eTags := ev.Tags.GetAll(tag.New([]byte{'e'}))
|
||||
for _, eTag := range eTags.ToSliceOfTags() {
|
||||
@@ -149,22 +132,7 @@ func (d *D) QueryEvents(c context.T, f *filter.F) (evs event.S, err error) {
|
||||
}
|
||||
// Check for 'a' tags that reference parameterized replaceable
|
||||
// events
|
||||
log.T.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"processing deletion event with ID: %s\n",
|
||||
hex.Enc(ev.ID),
|
||||
)
|
||||
},
|
||||
)
|
||||
aTags := ev.Tags.GetAll(tag.New([]byte{'a'}))
|
||||
log.D.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"Found %d a-tags\n", aTags.Len(),
|
||||
)
|
||||
},
|
||||
)
|
||||
for _, aTag := range aTags.ToSliceOfTags() {
|
||||
if aTag.Len() < 2 {
|
||||
continue
|
||||
@@ -205,21 +173,6 @@ func (d *D) QueryEvents(c context.T, f *filter.F) (evs event.S, err error) {
|
||||
dValue := string(split[2])
|
||||
deletionsByKindPubkeyDTag[key][dValue] = true
|
||||
// Debug logging
|
||||
log.D.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"processing a-tag: %s\n", string(aTag.Value()),
|
||||
)
|
||||
},
|
||||
)
|
||||
log.D.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"adding to deletion map - key: %s, d-tag: %s\n",
|
||||
key, dValue,
|
||||
)
|
||||
},
|
||||
)
|
||||
}
|
||||
// For replaceable events, we need to check if there are any
|
||||
// e-tags that reference events with the same kind and pubkey
|
||||
@@ -353,23 +306,6 @@ func (d *D) QueryEvents(c context.T, f *filter.F) (evs event.S, err error) {
|
||||
|
||||
// Check if this event has been deleted via an a-tag
|
||||
if deletionMap, exists := deletionsByKindPubkeyDTag[key]; exists {
|
||||
// Debug logging
|
||||
log.T.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"Checking deletion map - key: %s, d-tag: %s",
|
||||
key, dValue,
|
||||
)
|
||||
},
|
||||
)
|
||||
log.T.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"Deletion map contains key: %v, d-tag in map: %v",
|
||||
exists, deletionMap[dValue],
|
||||
)
|
||||
},
|
||||
)
|
||||
// If the d-tag value is in the deletion map and this event
|
||||
// is not specifically requested by ID, skip it
|
||||
if deletionMap[dValue] && !isIdInFilter {
|
||||
|
||||
@@ -248,7 +248,7 @@ func (f *F) Unmarshal(b []byte) (r []byte, err error) {
|
||||
r = b[:]
|
||||
var key []byte
|
||||
var state int
|
||||
for ; len(r) >= 0; r = r[1:] {
|
||||
for ; len(r) > 0; r = r[1:] {
|
||||
// log.I.ToSliceOfBytes("%c", rem[0])
|
||||
switch state {
|
||||
case beforeOpen:
|
||||
|
||||
@@ -140,7 +140,7 @@ func (p *S) Receive(msg typer.T) {
|
||||
// # Expected behaviour
|
||||
//
|
||||
// Delivers the event to all subscribers whose filters match the event. It
|
||||
// applies authentication checks if required by the server, and skips delivery
|
||||
// applies authentication checks if required by the server and skips delivery
|
||||
// for unauthenticated users when events are privileged.
|
||||
func (p *S) Deliver(ev *event.E) {
|
||||
var err error
|
||||
@@ -163,29 +163,11 @@ func (p *S) Deliver(ev *event.E) {
|
||||
},
|
||||
)
|
||||
for id, subscriber := range subs {
|
||||
log.T.F(
|
||||
"subscriber %s\n%s", w.RealRemote(),
|
||||
subscriber.Marshal(nil),
|
||||
)
|
||||
if !subscriber.Match(ev) {
|
||||
log.T.C(
|
||||
func() string {
|
||||
return fmt.Sprintf(
|
||||
"subscriber %s filter %s not match", id,
|
||||
subscriber.Marshal(nil),
|
||||
)
|
||||
},
|
||||
)
|
||||
continue
|
||||
}
|
||||
if p.Server.AuthRequired() {
|
||||
if !auth.CheckPrivilege(w.AuthedPubkey(), ev) {
|
||||
log.W.F(
|
||||
"not privileged %0x ev pubkey %0x ev pubkey %0x kind %s privileged: %v",
|
||||
w.AuthedPubkey(), ev.Pubkey,
|
||||
w.AuthedPubkey(), ev.Kind.Name(),
|
||||
ev.Kind.IsPrivileged(),
|
||||
)
|
||||
continue
|
||||
}
|
||||
var res *eventenvelope.Result
|
||||
|
||||
@@ -273,7 +273,7 @@ func (r *Client) ConnectWithTLS(
|
||||
); err != nil {
|
||||
r.ConnectionError = err
|
||||
r.Close()
|
||||
break
|
||||
return
|
||||
}
|
||||
message := buf.Bytes()
|
||||
var t string
|
||||
|
||||
@@ -3,10 +3,10 @@ package ws
|
||||
import (
|
||||
"crypto/tls"
|
||||
"errors"
|
||||
"fmt"
|
||||
"io"
|
||||
"net/http"
|
||||
"orly.dev/pkg/utils/context"
|
||||
"orly.dev/pkg/utils/errorf"
|
||||
"orly.dev/pkg/utils/units"
|
||||
"time"
|
||||
|
||||
@@ -40,7 +40,7 @@ func (c *Connection) WriteMessage(
|
||||
ctx context.T, data []byte,
|
||||
) (err error) {
|
||||
if err = c.conn.Write(ctx, ws.MessageText, data); err != nil {
|
||||
err = fmt.Errorf("failed to write message: %w", err)
|
||||
err = errorf.E("failed to write message: %w", err)
|
||||
return
|
||||
}
|
||||
return nil
|
||||
@@ -52,11 +52,11 @@ func (c *Connection) ReadMessage(
|
||||
) (err error) {
|
||||
var reader io.Reader
|
||||
if _, reader, err = c.conn.Reader(ctx); err != nil {
|
||||
err = fmt.Errorf("failed to get reader: %w", err)
|
||||
err = errorf.E("failed to get reader: %w", err)
|
||||
return
|
||||
}
|
||||
if _, err = io.Copy(buf, reader); err != nil {
|
||||
err = fmt.Errorf("failed to read message: %w", err)
|
||||
err = errorf.E("failed to read message: %w", err)
|
||||
return
|
||||
}
|
||||
return
|
||||
|
||||
@@ -1 +1 @@
|
||||
v0.8.5
|
||||
v0.8.7
|
||||
Reference in New Issue
Block a user