Skip to content

Commit 16415a0

Browse files
committed
support in-process connection
1 parent 9bdbc0a commit 16415a0

File tree

5 files changed

+168
-8
lines changed

5 files changed

+168
-8
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,10 +5,10 @@
55
[![Go Report Card](https://goreportcard.com/badge/github.com/hslam/socket)](https://goreportcard.com/report/github.com/hslam/socket)
66
[![LICENSE](https://img.shields.io/github/license/hslam/socket.svg?style=flat-square)](https://github.com/hslam/socket/blob/master/LICENSE)
77

8-
Package socket implements a network socket that supports TCP, UNIX, HTTP and WS.
8+
Package socket implements a network socket that supports TCP, UNIX, HTTP, WS and INPROC.
99

1010
## Feature
11-
* TCP/UNIX/HTTP/WS
11+
* TCP/UNIX/HTTP/WS/INPROC
1212
* [Epoll/Kqueue](https://github.com/hslam/netpoll "netpoll")
1313
* TLS
1414

socket.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
// Copyright (c) 2020 Meng Huang (mhboy@outlook.com)
22
// This package is licensed under a MIT license that can be found in the LICENSE file.
33

4-
// Package socket implements a network socket that supports TCP, UNIX, HTTP and WS.
4+
// Package socket implements a network socket that supports TCP, UNIX, HTTP, WS and INPROC.
55
package socket
66

77
import (
@@ -101,6 +101,8 @@ func NewSocket(network string, config *tls.Config) (Socket, error) {
101101
return NewHTTPSocket(config), nil
102102
case "ws", "wss":
103103
return NewWSSocket(config), nil
104+
case "inproc", "inprocs":
105+
return NewINPROCSocket(config), nil
104106
default:
105107
return nil, ErrNetwork
106108
}

socket_inproc.go

Lines changed: 125 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,125 @@
1+
// Copyright (c) 2021 Meng Huang (mhboy@outlook.com)
2+
// This package is licensed under a MIT license that can be found in the LICENSE file.
3+
4+
package socket
5+
6+
import (
7+
"crypto/tls"
8+
"errors"
9+
"github.com/hslam/inproc"
10+
"github.com/hslam/netpoll"
11+
"net"
12+
)
13+
14+
// INPROC implements the Socket interface.
15+
type INPROC struct {
16+
Config *tls.Config
17+
}
18+
19+
// INPROConn implements the Conn interface.
20+
type INPROConn struct {
21+
net.Conn
22+
}
23+
24+
// Messages returns a new Messages.
25+
func (c *INPROConn) Messages() Messages {
26+
return NewMessages(c.Conn, false, 0, 0)
27+
}
28+
29+
// Connection returns the net.Conn.
30+
func (c *INPROConn) Connection() net.Conn {
31+
return c.Conn
32+
}
33+
34+
// NewINPROCSocket returns a new TCP socket.
35+
func NewINPROCSocket(config *tls.Config) Socket {
36+
return &INPROC{Config: config}
37+
}
38+
39+
// Scheme returns the socket's scheme.
40+
func (t *INPROC) Scheme() string {
41+
if t.Config == nil {
42+
return "inproc"
43+
}
44+
return "inprocs"
45+
}
46+
47+
// Dial connects to an address.
48+
func (t *INPROC) Dial(address string) (Conn, error) {
49+
conn, err := inproc.Dial(address)
50+
if err != nil {
51+
return nil, err
52+
}
53+
if t.Config == nil {
54+
return &INPROConn{conn}, err
55+
}
56+
t.Config.ServerName = address
57+
tlsConn := tls.Client(conn, t.Config)
58+
if err = tlsConn.Handshake(); err != nil {
59+
conn.Close()
60+
return nil, err
61+
}
62+
return &INPROConn{tlsConn}, err
63+
}
64+
65+
// Listen announces on the local address.
66+
func (t *INPROC) Listen(address string) (Listener, error) {
67+
lis, err := inproc.Listen(address)
68+
if err != nil {
69+
return nil, err
70+
}
71+
return &INPROCListener{l: lis, config: t.Config}, err
72+
}
73+
74+
// INPROCListener implements the Listener interface.
75+
type INPROCListener struct {
76+
l net.Listener
77+
config *tls.Config
78+
}
79+
80+
// Accept waits for and returns the next connection to the listener.
81+
func (l *INPROCListener) Accept() (Conn, error) {
82+
conn, err := l.l.Accept()
83+
if err != nil {
84+
return nil, err
85+
}
86+
if l.config == nil {
87+
return &INPROConn{conn}, err
88+
}
89+
tlsConn := tls.Server(conn, l.config)
90+
if err = tlsConn.Handshake(); err != nil {
91+
conn.Close()
92+
return nil, err
93+
}
94+
return &INPROConn{tlsConn}, err
95+
}
96+
97+
// Serve serves the netpoll.Handler by the netpoll.
98+
func (l *INPROCListener) Serve(handler netpoll.Handler) error {
99+
return errors.New("not pollable")
100+
}
101+
102+
// ServeData serves the opened func and the serve func by the netpoll.
103+
func (l *INPROCListener) ServeData(opened func(net.Conn) error, serve func(req []byte) (res []byte)) error {
104+
return errors.New("not pollable")
105+
}
106+
107+
// ServeConn serves the opened func and the serve func by the netpoll.
108+
func (l *INPROCListener) ServeConn(opened func(net.Conn) (Context, error), serve func(Context) error) error {
109+
return errors.New("not pollable")
110+
}
111+
112+
// ServeMessages serves the opened func and the serve func by the netpoll.
113+
func (l *INPROCListener) ServeMessages(opened func(Messages) (Context, error), serve func(Context) error) error {
114+
return errors.New("not pollable")
115+
}
116+
117+
// Close closes the listener.
118+
func (l *INPROCListener) Close() error {
119+
return l.l.Close()
120+
}
121+
122+
// Addr returns the listener's network address.
123+
func (l *INPROCListener) Addr() net.Addr {
124+
return l.l.Addr()
125+
}

socket_inproc_test.go

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
// Copyright (c) 2021 Meng Huang (mhboy@outlook.com)
2+
// This package is licensed under a MIT license that can be found in the LICENSE file.
3+
4+
package socket
5+
6+
import (
7+
"testing"
8+
)
9+
10+
func TestINPROC(t *testing.T) {
11+
address := ":9999"
12+
serverSock := NewINPROCSocket(nil)
13+
l, err := serverSock.Listen(address)
14+
defer l.Close()
15+
if err != nil {
16+
t.Error(err)
17+
}
18+
if _, err := serverSock.Listen(address); err == nil {
19+
t.Error(err)
20+
}
21+
l.Serve(nil)
22+
l.ServeConn(nil, nil)
23+
l.ServeData(nil, nil)
24+
l.ServeMessages(nil, nil)
25+
l.Close()
26+
}

socket_test.go

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -19,22 +19,21 @@ func TestSocket(t *testing.T) {
1919
testSocket(NewUNIXSocket(nil), NewUNIXSocket(nil), "unix", t)
2020
testSocket(NewHTTPSocket(nil), NewHTTPSocket(nil), "http", t)
2121
testSocket(NewWSSocket(nil), NewWSSocket(nil), "ws", t)
22+
testSocket(NewINPROCSocket(nil), NewINPROCSocket(nil), "inproc", t)
2223
testSocket(NewTCPSocket(DefalutTLSConfig()), NewTCPSocket(SkipVerifyTLSConfig()), "tcps", t)
2324
testSocket(NewUNIXSocket(DefalutTLSConfig()), NewUNIXSocket(SkipVerifyTLSConfig()), "unixs", t)
2425
testSocket(NewHTTPSocket(DefalutTLSConfig()), NewHTTPSocket(SkipVerifyTLSConfig()), "https", t)
2526
testSocket(NewWSSocket(DefalutTLSConfig()), NewWSSocket(SkipVerifyTLSConfig()), "wss", t)
27+
testSocket(NewINPROCSocket(DefalutTLSConfig()), NewINPROCSocket(SkipVerifyTLSConfig()), "inprocs", t)
2628
testTCPSocket(NewTCPSocket(nil), NewTCPSocket(nil), "tcp", t)
27-
2829
}
2930

3031
func testSocket(serverSock Socket, clientSock Socket, scheme string, t *testing.T) {
3132
var addr = ":9999"
3233
if serverSock.Scheme() != scheme {
3334
t.Error(serverSock.Scheme())
3435
}
35-
if _, err := clientSock.Dial("-1"); err == nil {
36-
t.Error("should be missing port in address / no such file or directory")
37-
}
36+
3837
if _, err := clientSock.Dial(addr); err == nil {
3938
t.Error("should be refused")
4039
}
@@ -71,7 +70,14 @@ func testSocket(serverSock Socket, clientSock Socket, scheme string, t *testing.
7170
if err != nil {
7271
t.Error(err)
7372
}
74-
conn.Connection()
73+
netConn := conn.Connection()
74+
netConn.SetWriteDeadline(time.Now().Add(time.Second))
75+
netConn.SetReadDeadline(time.Now().Add(time.Second))
76+
netConn.SetDeadline(time.Now().Add(time.Second))
77+
netConn.LocalAddr()
78+
raddr := netConn.RemoteAddr()
79+
raddr.Network()
80+
raddr.String()
7581
messages := conn.Messages()
7682
str := "Hello World"
7783
str = strings.Repeat(str, 50)
@@ -166,6 +172,7 @@ func TestSocketTLS(t *testing.T) {
166172
testSocketTLS(NewUNIXSocket(DefalutTLSConfig()), NewUNIXSocket(config), t)
167173
testSocketTLS(NewHTTPSocket(DefalutTLSConfig()), NewHTTPSocket(config), t)
168174
testSocketTLS(NewWSSocket(DefalutTLSConfig()), NewWSSocket(config), t)
175+
testSocketTLS(NewINPROCSocket(DefalutTLSConfig()), NewINPROCSocket(config), t)
169176
}
170177

171178
func testSocketTLS(serverSock Socket, clientSock Socket, t *testing.T) {

0 commit comments

Comments
 (0)