@@ -11,6 +11,7 @@ import (
11
11
"net/url"
12
12
"os"
13
13
"os/exec"
14
+ "strconv"
14
15
"sync"
15
16
"time"
16
17
@@ -74,21 +75,11 @@ func New(c *up.Config) (http.Handler, error) {
74
75
75
76
timeout := time .Duration (c .Proxy .Timeout ) * time .Second
76
77
77
- transport := & http.Transport {
78
- DialContext : (& net.Dialer {
79
- Timeout : 2 * time .Second ,
80
- KeepAlive : 2 * time .Second ,
81
- DualStack : true ,
82
- }).DialContext ,
83
- ResponseHeaderTimeout : timeout ,
84
- DisableKeepAlives : true ,
85
- }
86
-
87
78
p := & Proxy {
88
79
config : c ,
89
80
stdout : writer .New (stdout , ctx ),
90
81
stderr : writer .New (stderr , ctx ),
91
- transport : transport ,
82
+ transport : newTransport ( timeout ) ,
92
83
}
93
84
94
85
if err := p .Start (); err != nil {
@@ -145,8 +136,16 @@ func (p *Proxy) Restart() error {
145
136
func (p * Proxy ) RoundTrip (r * http.Request ) (* http.Response , error ) {
146
137
id := r .Header .Get ("X-Request-Id" )
147
138
ctx = ctx .WithField ("id" , id )
139
+ transport := p .transport
140
+
141
+ // timeout header
142
+ if s := r .Header .Get ("X-Up-Timeout" ); s != "" {
143
+ if n , err := strconv .ParseInt (s , 10 , 64 ); err == nil {
144
+ transport = newTransport (time .Duration (n ) * time .Second )
145
+ }
146
+ }
148
147
149
- res , err := p . transport .RoundTrip (r )
148
+ res , err := transport .RoundTrip (r )
150
149
151
150
// timeout error
152
151
if e , ok := err .(net.Error ); ok && e .Timeout () {
@@ -213,6 +212,19 @@ func (p *Proxy) command(s string, env []string) *exec.Cmd {
213
212
return cmd
214
213
}
215
214
215
+ // newTransport returns a new http.Transport with the given timeout.
216
+ func newTransport (timeout time.Duration ) * http.Transport {
217
+ return & http.Transport {
218
+ DialContext : (& net.Dialer {
219
+ Timeout : 2 * time .Second ,
220
+ KeepAlive : 2 * time .Second ,
221
+ DualStack : true ,
222
+ }).DialContext ,
223
+ ResponseHeaderTimeout : timeout ,
224
+ DisableKeepAlives : true ,
225
+ }
226
+ }
227
+
216
228
// env returns an environment variable.
217
229
func env (name string , val interface {}) string {
218
230
return fmt .Sprintf ("%s=%v" , name , val )
0 commit comments