mirror of
https://github.com/asmogo/nws.git
synced 2024-12-12 18:36:22 +00:00
updated readme
This commit is contained in:
parent
b8472a6549
commit
3de5d16951
9
.github/codecov.yml
vendored
Normal file
9
.github/codecov.yml
vendored
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
coverage:
|
||||||
|
status:
|
||||||
|
patch: off
|
||||||
|
project:
|
||||||
|
default:
|
||||||
|
target: auto
|
||||||
|
# adjust accordingly based on how flaky your tests are
|
||||||
|
# this allows a 10% drop from the previous base commit coverage
|
||||||
|
threshold: 10%
|
29
.github/workflows/master.yml
vendored
Normal file
29
.github/workflows/master.yml
vendored
Normal file
@ -0,0 +1,29 @@
|
|||||||
|
name: gobuild
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
branches: [ "master" ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
docker:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Set up Docker Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2
|
||||||
|
- name: Login to DockerHub
|
||||||
|
uses: docker/login-action@v2
|
||||||
|
with:
|
||||||
|
username: ${{ secrets.DOCKERHUB_USERNAME }}
|
||||||
|
password: ${{ secrets.DOCKERHUB_TOKEN }}
|
||||||
|
- name: Set up QEMU
|
||||||
|
uses: docker/setup-qemu-action@v2
|
||||||
|
- name: Docker Setup Buildx
|
||||||
|
uses: docker/setup-buildx-action@v2.0.0
|
||||||
|
- name: Build and push
|
||||||
|
uses: docker/build-push-action@v3
|
||||||
|
with:
|
||||||
|
platforms: linux/amd64,linux/arm64
|
||||||
|
push: true
|
||||||
|
tags: asmogo/nws-exit-node:latest
|
35
.github/workflows/tag.yml
vendored
Normal file
35
.github/workflows/tag.yml
vendored
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
name: goreleaser
|
||||||
|
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
# run only against tags
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: write
|
||||||
|
# packages: write
|
||||||
|
# issues: write
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
goreleaser:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
fetch-depth: 0
|
||||||
|
- run: git fetch --force --tags
|
||||||
|
- uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: '>=1.21.2'
|
||||||
|
cache: true
|
||||||
|
# More assembly might be required: Docker logins, GPG, etc. It all depends
|
||||||
|
# on your needs.
|
||||||
|
- uses: goreleaser/goreleaser-action@v2
|
||||||
|
with:
|
||||||
|
# either 'goreleaser' (default) or 'goreleaser-pro'
|
||||||
|
distribution: goreleaser
|
||||||
|
version: latest
|
||||||
|
args: release --rm-dist
|
||||||
|
env:
|
||||||
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
18
.github/workflows/test.yml
vendored
Normal file
18
.github/workflows/test.yml
vendored
Normal file
@ -0,0 +1,18 @@
|
|||||||
|
name: tests
|
||||||
|
|
||||||
|
on: [ push, pull_request ]
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
golang:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- name: Set up Go
|
||||||
|
uses: actions/setup-go@v3
|
||||||
|
with:
|
||||||
|
go-version: 1.19
|
||||||
|
- name: Golang run tests
|
||||||
|
run: go test -coverprofile=coverage.txt -covermode=atomic -v ./...
|
||||||
|
- uses: codecov/codecov-action@v3
|
||||||
|
with:
|
||||||
|
verbose: true # optional (default = false)
|
@ -103,7 +103,7 @@ If you used environment variables, no further configuration is needed.
|
|||||||
For `.env` file configurations, do so in the current working directory with the following content:
|
For `.env` file configurations, do so in the current working directory with the following content:
|
||||||
|
|
||||||
```
|
```
|
||||||
NOSTR_RELAYS = 'ws://localhost:6666;wss://relay.damus.io'
|
NOSTR_RELAYS = 'ws://localhost:6666;wss://relay.com'
|
||||||
```
|
```
|
||||||
|
|
||||||
Here, NOSTR_RELAYS is a list of nostr relays to publish events to and will only be used if there was no nprofile in the request.
|
Here, NOSTR_RELAYS is a list of nostr relays to publish events to and will only be used if there was no nprofile in the request.
|
||||||
|
71
cmd/listener/listener.go
Normal file
71
cmd/listener/listener.go
Normal file
@ -0,0 +1,71 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"io"
|
||||||
|
"log"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
startServer()
|
||||||
|
}
|
||||||
|
func startServer() {
|
||||||
|
l, err := net.Listen("tcp", "localhost:3338")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
defer l.Close()
|
||||||
|
for {
|
||||||
|
conn, err := l.Accept()
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
go handleConnection(conn)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func handleRequest(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
|
||||||
|
reader := bufio.NewReader(conn)
|
||||||
|
|
||||||
|
for {
|
||||||
|
message, err := reader.ReadString('\n') // change the delimiter according to your messaging protocol
|
||||||
|
if err != nil {
|
||||||
|
if err != io.EOF {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
break
|
||||||
|
}
|
||||||
|
fmt.Printf("Received message: %s", message)
|
||||||
|
_, err = conn.Write([]byte(message))
|
||||||
|
if err != nil {
|
||||||
|
log.Fatal(err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
func handleConnection(conn net.Conn) {
|
||||||
|
defer conn.Close()
|
||||||
|
for {
|
||||||
|
var num int32
|
||||||
|
// Read the integer from the connection
|
||||||
|
err := binary.Read(conn, binary.BigEndian, &num)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading from connection:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
// Write the integer back to the connection
|
||||||
|
err = binary.Write(conn, binary.BigEndian, num)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error writing to connection:", err)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Received and sent back:", num)
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
49
cmd/testr/testr.go
Normal file
49
cmd/testr/testr.go
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"golang.org/x/net/proxy"
|
||||||
|
"os"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
// set up a socks5 dialer
|
||||||
|
dialer, err := proxy.SOCKS5("tcp", "localhost:8882", nil, proxy.Direct)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "can't connect to the proxy:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
// use the dialer to connect to the server
|
||||||
|
conn, err := dialer.Dial("tcp", "nprofile1qqs9ntc52tn0app0w7azwpj4s39lnz8h0frnzlhf6mun2ptq9ay36kspzemhxue69uhhyetvv9ujuwpnxvejuumsv93k20v2pva:3338")
|
||||||
|
if err != nil {
|
||||||
|
fmt.Fprintln(os.Stderr, "can't connect to the server:", err)
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
counter := int32(0)
|
||||||
|
|
||||||
|
for {
|
||||||
|
|
||||||
|
// Increment the counter
|
||||||
|
counter++
|
||||||
|
|
||||||
|
// Write the counter to the connection
|
||||||
|
err = binary.Write(conn, binary.BigEndian, counter)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error writing to connection:", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Read the response from the server
|
||||||
|
var response int32
|
||||||
|
err = binary.Read(conn, binary.BigEndian, &response)
|
||||||
|
if err != nil {
|
||||||
|
fmt.Println("Error reading from connection:", err)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("Sent:", counter, "Received:", response)
|
||||||
|
|
||||||
|
}
|
||||||
|
_ = conn.Close()
|
||||||
|
}
|
1
coverage.txt
Normal file
1
coverage.txt
Normal file
@ -0,0 +1 @@
|
|||||||
|
mode: atomic
|
125
netstr/conn_test.go
Normal file
125
netstr/conn_test.go
Normal file
@ -0,0 +1,125 @@
|
|||||||
|
package netstr
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"github.com/asmogo/nws/protocol"
|
||||||
|
"github.com/nbd-wtf/go-nostr"
|
||||||
|
"runtime"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
|
"github.com/stretchr/testify/assert"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNostrConnection_Read(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
event protocol.IncomingEvent
|
||||||
|
nc func() *NostrConnection
|
||||||
|
wantN int
|
||||||
|
wantErr bool
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "Read invalid relay",
|
||||||
|
event: protocol.IncomingEvent{Relay: nil},
|
||||||
|
nc: func() *NostrConnection {
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
return &NostrConnection{
|
||||||
|
uuid: uuid.New(),
|
||||||
|
ctx: ctx,
|
||||||
|
cancel: cancelFunc,
|
||||||
|
subscriptionChan: make(chan protocol.IncomingEvent, 1),
|
||||||
|
privateKey: "788de536151854213cc28dff9c3042e7897f0a1d59b391ddbbc1619d7e716e78",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantN: 0,
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Read",
|
||||||
|
event: protocol.IncomingEvent{
|
||||||
|
Relay: &nostr.Relay{URL: "wss://relay.example.com"},
|
||||||
|
Event: &nostr.Event{
|
||||||
|
ID: "eventID",
|
||||||
|
PubKey: "8f97a664471f0b6d599a1e4a781c9a25f39902d96fb462c08df48697bb851611",
|
||||||
|
Content: "BnHzzyrUhKjDcDPOGfXJDYijUsgxw0hUZq2m+bX5QFI=?iv=NrEqv/jL+SASB2YTjo9i9Q=="}},
|
||||||
|
nc: func() *NostrConnection {
|
||||||
|
ctx, cancelFunc := context.WithCancel(context.Background())
|
||||||
|
return &NostrConnection{
|
||||||
|
uuid: uuid.New(),
|
||||||
|
ctx: ctx,
|
||||||
|
cancel: cancelFunc,
|
||||||
|
subscriptionChan: make(chan protocol.IncomingEvent, 1),
|
||||||
|
privateKey: "788de536151854213cc28dff9c3042e7897f0a1d59b391ddbbc1619d7e716e78",
|
||||||
|
}
|
||||||
|
},
|
||||||
|
wantN: 11, // hello world
|
||||||
|
wantErr: false,
|
||||||
|
},
|
||||||
|
// Add more cases here to cover more corner situations
|
||||||
|
}
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
nc := tt.nc()
|
||||||
|
defer nc.Close()
|
||||||
|
b := make([]byte, 1024)
|
||||||
|
nc.subscriptionChan <- tt.event
|
||||||
|
gotN, err := nc.Read(b)
|
||||||
|
if (err != nil) != tt.wantErr {
|
||||||
|
t.Errorf("Read() error = %v, wantErr %v", err, tt.wantErr)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
if gotN != tt.wantN {
|
||||||
|
t.Errorf("Read() gotN = %v, want %v", gotN, tt.wantN)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
func() {
|
||||||
|
// Prevent goroutine leak
|
||||||
|
for range make([]struct{}, 1000) {
|
||||||
|
runtime.Gosched()
|
||||||
|
}
|
||||||
|
}()
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNewConnection(t *testing.T) {
|
||||||
|
testCases := []struct {
|
||||||
|
name string
|
||||||
|
opts []NostrConnOption
|
||||||
|
expectedID string
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "NoOptions",
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "WithPrivateKey",
|
||||||
|
opts: []NostrConnOption{WithPrivateKey("privateKey")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "WithSub",
|
||||||
|
opts: []NostrConnOption{WithSub(true)},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "WithDst",
|
||||||
|
opts: []NostrConnOption{WithDst("destination")},
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "WithUUID",
|
||||||
|
opts: []NostrConnOption{WithUUID(uuid.New())},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tc := range testCases {
|
||||||
|
t.Run(tc.name, func(t *testing.T) {
|
||||||
|
ctx := context.Background()
|
||||||
|
connection := NewConnection(ctx, tc.opts...)
|
||||||
|
|
||||||
|
assert.NotNil(t, connection)
|
||||||
|
assert.NotNil(t, connection.pool)
|
||||||
|
assert.NotNil(t, connection.ctx)
|
||||||
|
assert.NotNil(t, connection.cancel)
|
||||||
|
assert.NotNil(t, connection.subscriptionChan)
|
||||||
|
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user