File tree 6 files changed +201
-3
lines changed
6 files changed +201
-3
lines changed Original file line number Diff line number Diff line change @@ -119,6 +119,38 @@ func main() {
119
119
}
120
120
```
121
121
122
+ ### HTTP Server
123
+ ``` go
124
+ package main
125
+
126
+ import (
127
+ " net"
128
+ " net/http"
129
+ " time"
130
+
131
+ " github.com/pires/go-proxyproto"
132
+ )
133
+
134
+ func main () {
135
+ server := http.Server {
136
+ Addr: " :8080" ,
137
+ }
138
+
139
+ ln , err := net.Listen (" tcp" , server.Addr )
140
+ if err != nil {
141
+ panic (err)
142
+ }
143
+
144
+ proxyListener := &proxyproto.Listener {
145
+ Listener: ln,
146
+ ReadHeaderTimeout: 10 * time.Second ,
147
+ }
148
+ defer proxyListener.Close ()
149
+
150
+ server.Serve (proxyListener)
151
+ }
152
+ ```
153
+
122
154
## Special notes
123
155
124
156
### AWS
Original file line number Diff line number Diff line change
1
+ package main
2
+
3
+ import (
4
+ "io"
5
+ "log"
6
+ "net"
7
+
8
+ proxyproto "github.com/pires/go-proxyproto"
9
+ )
10
+
11
+ func chkErr (err error ) {
12
+ if err != nil {
13
+ log .Fatalf ("Error: %s" , err .Error ())
14
+ }
15
+ }
16
+
17
+ func main () {
18
+ // Dial some proxy listener e.g. https://github.com/mailgun/proxyproto
19
+ target , err := net .ResolveTCPAddr ("tcp" , "127.0.0.1:9876" )
20
+ chkErr (err )
21
+
22
+ conn , err := net .DialTCP ("tcp" , nil , target )
23
+ chkErr (err )
24
+
25
+ defer conn .Close ()
26
+
27
+ // Create a proxyprotocol header or use HeaderProxyFromAddrs() if you
28
+ // have two conn's
29
+ header := & proxyproto.Header {
30
+ Version : 1 ,
31
+ Command : proxyproto .PROXY ,
32
+ TransportProtocol : proxyproto .TCPv4 ,
33
+ SourceAddr : & net.TCPAddr {
34
+ IP : net .ParseIP ("10.1.1.1" ),
35
+ Port : 1000 ,
36
+ },
37
+ DestinationAddr : & net.TCPAddr {
38
+ IP : net .ParseIP ("20.2.2.2" ),
39
+ Port : 2000 ,
40
+ },
41
+ }
42
+ // After the connection was created write the proxy headers first
43
+ _ , err = header .WriteTo (conn )
44
+ chkErr (err )
45
+ // Then your data... e.g.:
46
+ _ , err = io .WriteString (conn , "HELO" )
47
+ chkErr (err )
48
+ }
Original file line number Diff line number Diff line change
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "net"
6
+ "net/http"
7
+ "time"
8
+
9
+ "github.com/pires/go-proxyproto"
10
+ )
11
+
12
+ // TODO: add httpclient example
13
+
14
+ func main () {
15
+ server := http.Server {
16
+ Addr : ":8080" ,
17
+ ConnState : func (c net.Conn , s http.ConnState ) {
18
+ if s == http .StateNew {
19
+ log .Printf ("[ConnState] %s -> %s" , c .LocalAddr ().String (), c .RemoteAddr ().String ())
20
+ }
21
+ },
22
+ Handler : http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
23
+ log .Printf ("[Handler] remote ip %q" , r .RemoteAddr )
24
+ }),
25
+ }
26
+
27
+ ln , err := net .Listen ("tcp" , server .Addr )
28
+ if err != nil {
29
+ panic (err )
30
+ }
31
+
32
+ proxyListener := & proxyproto.Listener {
33
+ Listener : ln ,
34
+ ReadHeaderTimeout : 10 * time .Second ,
35
+ }
36
+ defer proxyListener .Close ()
37
+
38
+ server .Serve (proxyListener )
39
+ }
Original file line number Diff line number Diff line change
1
+ package main
2
+
3
+ import (
4
+ "log"
5
+ "net"
6
+
7
+ proxyproto "github.com/pires/go-proxyproto"
8
+ )
9
+
10
+ func main () {
11
+ // Create a listener
12
+ addr := "localhost:9876"
13
+ list , err := net .Listen ("tcp" , addr )
14
+ if err != nil {
15
+ log .Fatalf ("couldn't listen to %q: %q\n " , addr , err .Error ())
16
+ }
17
+
18
+ // Wrap listener in a proxyproto listener
19
+ proxyListener := & proxyproto.Listener {Listener : list }
20
+ defer proxyListener .Close ()
21
+
22
+ // Wait for a connection and accept it
23
+ conn , err := proxyListener .Accept ()
24
+ defer conn .Close ()
25
+
26
+ // Print connection details
27
+ if conn .LocalAddr () == nil {
28
+ log .Fatal ("couldn't retrieve local address" )
29
+ }
30
+ log .Printf ("local address: %q" , conn .LocalAddr ().String ())
31
+
32
+ if conn .RemoteAddr () == nil {
33
+ log .Fatal ("couldn't retrieve remote address" )
34
+ }
35
+ log .Printf ("remote address: %q" , conn .RemoteAddr ().String ())
36
+ }
Original file line number Diff line number Diff line change @@ -13,9 +13,10 @@ import (
13
13
// If the connection is using the protocol, the RemoteAddr() will return
14
14
// the correct client address.
15
15
type Listener struct {
16
- Listener net.Listener
17
- Policy PolicyFunc
18
- ValidateHeader Validator
16
+ Listener net.Listener
17
+ Policy PolicyFunc
18
+ ValidateHeader Validator
19
+ ReadHeaderTimeout time.Duration
19
20
}
20
21
21
22
// Conn is used to wrap and underlying connection which
@@ -52,6 +53,10 @@ func (p *Listener) Accept() (net.Conn, error) {
52
53
return nil , err
53
54
}
54
55
56
+ if d := p .ReadHeaderTimeout ; d != 0 {
57
+ conn .SetReadDeadline (time .Now ().Add (d ))
58
+ }
59
+
55
60
proxyHeaderPolicy := USE
56
61
if p .Policy != nil {
57
62
proxyHeaderPolicy , err = p .Policy (conn .RemoteAddr ())
Original file line number Diff line number Diff line change @@ -6,13 +6,15 @@ package proxyproto
6
6
7
7
import (
8
8
"bytes"
9
+ "context"
9
10
"crypto/tls"
10
11
"crypto/x509"
11
12
"fmt"
12
13
"io"
13
14
"io/ioutil"
14
15
"net"
15
16
"testing"
17
+ "time"
16
18
)
17
19
18
20
func TestPassthrough (t * testing.T ) {
@@ -61,6 +63,42 @@ func TestPassthrough(t *testing.T) {
61
63
}
62
64
}
63
65
66
+ func TestReadHeaderTimeout (t * testing.T ) {
67
+ l , err := net .Listen ("tcp" , "127.0.0.1:0" )
68
+ if err != nil {
69
+ t .Fatalf ("err: %v" , err )
70
+ }
71
+
72
+ pl := & Listener {
73
+ Listener : l ,
74
+ ReadHeaderTimeout : 1 * time .Millisecond ,
75
+ }
76
+
77
+ ctx , cancel := context .WithCancel (context .Background ())
78
+ defer cancel ()
79
+
80
+ go func () {
81
+ conn , err := net .Dial ("tcp" , pl .Addr ().String ())
82
+ if err != nil {
83
+ t .Fatalf ("err: %v" , err )
84
+ }
85
+ defer conn .Close ()
86
+
87
+ <- ctx .Done ()
88
+ }()
89
+
90
+ conn , err := pl .Accept ()
91
+ if err != nil {
92
+ t .Fatalf ("err: %v" , err )
93
+ }
94
+ defer conn .Close ()
95
+
96
+ // Read blocks forever if there is no ReadHeaderTimeout
97
+ recv := make ([]byte , 4 )
98
+ _ , err = conn .Read (recv )
99
+
100
+ }
101
+
64
102
func TestParse_ipv4 (t * testing.T ) {
65
103
l , err := net .Listen ("tcp" , "127.0.0.1:0" )
66
104
if err != nil {
You can’t perform that action at this time.
0 commit comments