@@ -2,8 +2,8 @@ package proxy
2
2
3
3
import (
4
4
"bufio"
5
- "context"
6
5
"crypto/tls"
6
+ "errors"
7
7
"fmt"
8
8
"io"
9
9
"log/slog"
@@ -12,6 +12,7 @@ import (
12
12
"net/url"
13
13
"strings"
14
14
"sync"
15
+ "sync/atomic"
15
16
16
17
"github.com/coder/boundary/audit"
17
18
"github.com/coder/boundary/rules"
@@ -24,6 +25,7 @@ type Server struct {
24
25
logger * slog.Logger
25
26
tlsConfig * tls.Config
26
27
httpPort int
28
+ started atomic.Bool
27
29
28
30
listener net.Listener
29
31
}
@@ -49,7 +51,12 @@ func NewProxyServer(config Config) *Server {
49
51
}
50
52
51
53
// Start starts the HTTP proxy server with TLS termination capability
52
- func (p * Server ) Start (ctx context.Context ) error {
54
+ func (p * Server ) Start () error {
55
+ if p .isStarted () {
56
+ return nil
57
+ }
58
+ p .started .Store (true )
59
+
53
60
// Start HTTP server with custom listener for TLS detection
54
61
go func () {
55
62
p .logger .Info ("Starting HTTP proxy with TLS termination" , "port" , p .httpPort )
@@ -62,46 +69,49 @@ func (p *Server) Start(ctx context.Context) error {
62
69
63
70
for {
64
71
conn , err := p .listener .Accept ()
72
+ if err != nil && errors .Is (err , net .ErrClosed ) && p .isStopped () {
73
+ return
74
+ }
65
75
if err != nil {
66
- select {
67
- case <- ctx .Done ():
68
- err = p .listener .Close ()
69
- if err != nil {
70
- p .logger .Error ("Failed to close listener" , "error" , err )
71
- }
72
- return
73
- default :
74
- p .logger .Error ("Failed to accept connection" , "error" , err )
75
- continue
76
- }
76
+ p .logger .Error ("Failed to accept connection" , "error" , err )
77
+ continue
77
78
}
78
79
79
80
// Handle connection with TLS detection
80
81
go p .handleConnectionWithTLSDetection (conn )
81
82
}
82
83
}()
83
84
84
- // Wait for context cancellation
85
- <- ctx .Done ()
86
- return p .Stop ()
85
+ return nil
87
86
}
88
87
89
88
// Stops proxy server
90
89
func (p * Server ) Stop () error {
91
- if p .listener == nil {
90
+ if p .isStopped () {
92
91
return nil
93
92
}
93
+ p .started .Store (false )
94
+
95
+ if p .listener == nil {
96
+ return errors .New ("listener is nil; server was not started" )
97
+ }
94
98
95
99
err := p .listener .Close ()
96
100
if err != nil {
97
101
p .logger .Error ("Failed to close listener" , "error" , err )
98
102
}
99
103
100
- fmt .Printf ("STOP is finished\n " )
101
-
102
104
return nil
103
105
}
104
106
107
+ func (p * Server ) isStarted () bool {
108
+ return p .started .Load ()
109
+ }
110
+
111
+ func (p * Server ) isStopped () bool {
112
+ return ! p .started .Load ()
113
+ }
114
+
105
115
// handleHTTP handles regular HTTP requests and CONNECT tunneling
106
116
func (p * Server ) handleHTTP (w http.ResponseWriter , r * http.Request ) {
107
117
p .logger .Debug ("handleHTTP called" , "method" , r .Method , "url" , r .URL .String (), "host" , r .Host )
0 commit comments