Skip to content

Commit

Permalink
add tcp server
Browse files Browse the repository at this point in the history
  • Loading branch information
markus621 committed Dec 30, 2023
1 parent 7d294c1 commit be8dd27
Show file tree
Hide file tree
Showing 28 changed files with 655 additions and 49 deletions.
8 changes: 5 additions & 3 deletions examples/go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ replace (
go.osspkg.com/goppy/routine => ../routine
go.osspkg.com/goppy/sqlcommon => ../sqlcommon
go.osspkg.com/goppy/syscall => ../syscall
go.osspkg.com/goppy/tcp => ../tcp
go.osspkg.com/goppy/udp => ../udp
go.osspkg.com/goppy/unixsocket => ../unixsocket
go.osspkg.com/goppy/web => ../web
Expand All @@ -35,7 +36,7 @@ replace (

require (
go.osspkg.com/goppy v0.15.4
go.osspkg.com/goppy/app v0.1.4
go.osspkg.com/goppy/app v0.1.5
go.osspkg.com/goppy/auth v0.1.0
go.osspkg.com/goppy/console v0.1.0
go.osspkg.com/goppy/geoip v0.1.0
Expand All @@ -45,13 +46,14 @@ require (
go.osspkg.com/goppy/ormsqlite v0.1.0
go.osspkg.com/goppy/plugins v0.1.1
go.osspkg.com/goppy/routine v0.1.2
go.osspkg.com/goppy/syscall v0.1.0
go.osspkg.com/goppy/syscall v0.1.1
go.osspkg.com/goppy/tcp v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/udp v0.0.2
go.osspkg.com/goppy/unixsocket v0.1.0
go.osspkg.com/goppy/web v0.1.5
go.osspkg.com/goppy/ws v0.1.0
go.osspkg.com/goppy/xc v0.1.0
go.osspkg.com/goppy/xdns v0.0.0-00010101000000-000000000000
go.osspkg.com/goppy/xdns v0.1.0
go.osspkg.com/goppy/xlog v0.1.4
)

Expand Down
38 changes: 38 additions & 0 deletions examples/x/demo-tcp/main.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package main

import (
"fmt"
"os"
"time"

"go.osspkg.com/goppy/syscall"
"go.osspkg.com/goppy/tcp/server"
"go.osspkg.com/goppy/xc"
"go.osspkg.com/goppy/xlog"
)

func main() {
conf := server.ConfigItem{
Pools: []server.Pool{{Port: 11111, Certs: nil}},
Timeout: 5 * time.Second,
}
l := xlog.New()
l.SetLevel(xlog.LevelDebug)
l.SetFormatter(xlog.NewFormatString())
l.SetOutput(os.Stdout)
defer l.Close()

s := server.New(conf, l)
c := xc.New()

fmt.Println(s.Up(c))
syscall.OnStop(func() {
c.Close()
})
fmt.Println(s.Down())
}
10 changes: 7 additions & 3 deletions examples/x/demo-udp-client/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,7 @@ func main() {
if err != nil {
panic(err)
}
cli.Handler(func(err error, b []byte) {
fmt.Println(err, ">", len(b), "...", string(b))
})
cli.HandleFunc(&Printer{})
routine.Interval(context.TODO(), time.Second, func(ctx context.Context) {
if _, err = cli.Write([]byte("123")); err != nil {
fmt.Println(err)
Expand All @@ -32,3 +30,9 @@ func main() {
fmt.Println(cli.Close())
})
}

type Printer struct{}

func (v *Printer) HandlerUDP(err error, b []byte) {
fmt.Println(err, ">", len(b), "...", string(b))
}
12 changes: 8 additions & 4 deletions examples/x/demo-udp-server/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,12 +17,16 @@ import (

func main() {
serv := server.New(xlog.Default(), ":11111")
serv.Handler(func(w server.Writer, addr net.Addr, b []byte) {
fmt.Println(addr.String(), "> ", string(b))
w.WriteTo(b, addr) //nolint: errcheck
})
serv.HandleFunc(&Echo{})
fmt.Println(serv.Up(xc.New()))
syscall.OnStop(func() {
fmt.Println(serv.Down())
})
}

type Echo struct{}

func (v *Echo) HandlerUDP(w server.Writer, addr net.Addr, b []byte) {
fmt.Println(addr.String(), "> ", string(b))
w.WriteTo(b, addr) //nolint: errcheck
}
1 change: 1 addition & 0 deletions go.work
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ use (
./sip
./sqlcommon
./syscall
./tcp
./udp
./unixsocket
./version
Expand Down
14 changes: 14 additions & 0 deletions ioutil/ascii.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package ioutil

import "bytes"

var asciiEof = []byte{255, 244, 255, 253, 6}

func IsAsciiEOF(b []byte) bool {
return bytes.Equal(b, asciiEof)
}
25 changes: 25 additions & 0 deletions tcp/go.mod
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
module go.osspkg.com/goppy/tcp

go 1.18

replace (
go.osspkg.com/goppy/errors => ../errors
go.osspkg.com/goppy/iosync => ../iosync
go.osspkg.com/goppy/plugins => ../plugins
go.osspkg.com/goppy/xc => ../xc
go.osspkg.com/goppy/xlog => ../xlog
go.osspkg.com/goppy/xtest => ../xtest
)

require (
go.osspkg.com/goppy/errors v0.1.0
go.osspkg.com/goppy/iosync v0.1.2
go.osspkg.com/goppy/plugins v0.1.1
go.osspkg.com/goppy/xc v0.1.0
go.osspkg.com/goppy/xlog v0.1.4
)

require (
github.com/josharian/intern v1.0.0 // indirect
github.com/mailru/easyjson v0.7.7 // indirect
)
4 changes: 4 additions & 0 deletions tcp/go.sum
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
github.com/josharian/intern v1.0.0 h1:vlS4z54oSdjm0bgjRigI+G1HpF+tI+9rE5LLzOg8HmY=
github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y=
github.com/mailru/easyjson v0.7.7 h1:UGYAvKxe3sBsEDzO8ZeWOSlIQfWFlxbzLZe7hwFURr0=
github.com/mailru/easyjson v0.7.7/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc=
42 changes: 42 additions & 0 deletions tcp/plugin_server.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package tcp

import (
"time"

"go.osspkg.com/goppy/plugins"
"go.osspkg.com/goppy/tcp/server"
"go.osspkg.com/goppy/xlog"
)

type Config struct {
TCP server.ConfigItem `yaml:"tcp"`
}

func (v *Config) Default() {
if len(v.TCP.Pools) == 0 {
v.TCP.Pools = append(v.TCP.Pools, server.Pool{
Port: 8080,
Certs: []server.Cert{{
Public: "./ssl/public.crt",
Private: "./ssl/private.key",
}},
})
}
if v.TCP.Timeout == 0 {
v.TCP.Timeout = 10 * time.Second
}
}

func WithServer() plugins.Plugin {
return plugins.Plugin{
Config: &Config{},
Inject: func(c *Config, l xlog.Logger) *server.Server {
return server.New(c.TCP, l)
},
}
}
21 changes: 21 additions & 0 deletions tcp/server/common.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package server

import (
"net"
)

type HandlerTCP interface {
HandlerTCP(p Processor)
}

type Processor interface {
Write([]byte) (int, error)
ReadLine() ([]byte, error)
Read(b []byte) (int, error)
Addr() net.Addr
}
23 changes: 23 additions & 0 deletions tcp/server/config.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package server

import "time"

type ConfigItem struct {
Pools []Pool `yaml:"pool"`
Timeout time.Duration `yaml:"timeout,omitempty"`
}

type Pool struct {
Port int `yaml:"port"`
Certs []Cert `yaml:"certs,omitempty"`
}

type Cert struct {
Public string `yaml:"pub"`
Private string `yaml:"priv"`
}
55 changes: 55 additions & 0 deletions tcp/server/listener.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package server

import (
"crypto/rand"
"crypto/tls"
"fmt"
"net"
)

type (
Listen struct {
conn net.Listener
tls bool
}
)

func NewListen(port int, certs ...Cert) (*Listen, error) {
address := fmt.Sprintf("0.0.0.0:%d", port)

if len(certs) == 0 {
l, err := net.Listen("tcp", address)
if err != nil {
return nil, err
}
return &Listen{conn: l}, nil
}

certificates := make([]tls.Certificate, 0, len(certs))
for _, c := range certs {
cert, err := tls.LoadX509KeyPair(c.Public, c.Private)
if err != nil {
return nil, err
}
certificates = append(certificates, cert)
}
config := tls.Config{Certificates: certificates, Rand: rand.Reader}
l, err := tls.Listen("tcp", address, &config)
if err != nil {
return nil, err
}
return &Listen{conn: l, tls: true}, nil
}

func (v *Listen) Close() error {
return v.conn.Close()
}

func (v *Listen) Accept() (net.Conn, error) {
return v.conn.Accept()
}
37 changes: 37 additions & 0 deletions tcp/server/log_handler.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*
* Copyright (c) 2022-2023 Mikhail Knyazhev <markus621@yandex.ru>. All rights reserved.
* Use of this source code is governed by a BSD 3-Clause license that can be found in the LICENSE file.
*/

package server

import (
"go.osspkg.com/goppy/xlog"
)

type logHandler struct {
log xlog.Logger
}

func NewLogHandlerTCP(l xlog.Logger) HandlerTCP {
return &logHandler{log: l}
}

func (v *logHandler) HandlerTCP(p Processor) {
for {
b, err := p.ReadLine()
if err != nil {
v.log.WithFields(xlog.Fields{
"addr": p.Addr().String(),
"err": err.Error(),
}).Errorf("Empty log handler TCP")
return
}

v.log.WithFields(xlog.Fields{
"addr": p.Addr().String(),
"len": len(b),
"body": string(b),
}).Warnf("Empty log handler TCP")
}
}
Loading

0 comments on commit be8dd27

Please sign in to comment.