Skip to content

Commit 73eff76

Browse files
authored
fix(conf): parse IdleTimeout parameter from string (#1547)
1 parent 334f814 commit 73eff76

File tree

3 files changed

+79
-4
lines changed

3 files changed

+79
-4
lines changed

config/confpar/confpar.go

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,10 @@
11
// Package confpar provide the core parameters of the config
22
package confpar
33

4-
import "time"
4+
import (
5+
"encoding/json"
6+
"time"
7+
)
58

69
// Access provides rules around any access
710
type Access struct {
@@ -19,7 +22,7 @@ type Access struct {
1922
type AccessesWebhook struct {
2023
URL string `json:"url"` // URL to call
2124
Headers map[string]string `json:"headers"` // Token to use in the
22-
Timeout time.Duration `json:"timeout"` // Max time request can take
25+
Timeout Duration `json:"timeout"` // Max time request can take
2326
}
2427

2528
// SyncAndDelete provides
@@ -65,7 +68,7 @@ type Content struct {
6568
PublicHost string `json:"public_host"` // Public host to listen on
6669
MaxClients int `json:"max_clients"` // Maximum clients who can connect
6770
HashPlaintextPasswords bool `json:"hash_plaintext_passwords"` // Overwrite plain-text passwords with hashed equivalents
68-
IdleTimeout time.Duration `json:"idle_timeout"` // Maximum idle time for client connections
71+
IdleTimeout Duration `json:"idle_timeout"` // Maximum idle time for client connections
6972
Accesses []*Access `json:"accesses"` // Accesses offered to users
7073
PassiveTransferPortRange *PortRange `json:"passive_transfer_port_range"` // Listen port range
7174
Extensions Extensions `json:"extensions"` // Extended features
@@ -74,3 +77,21 @@ type Content struct {
7477
TLSRequired string `json:"tls_required"`
7578
AccessesWebhook *AccessesWebhook `json:"accesses_webhook"` // Webhook to call when accesses are updated
7679
}
80+
81+
// Duration wraps time.Duration to allow unmarshaling from JSON strings
82+
// in Go duration format (e.g., "5m", "30s", "1h")
83+
type Duration struct {
84+
time.Duration
85+
}
86+
87+
func (d *Duration) MarshalJSON() ([]byte, error) {
88+
return json.Marshal(d.String())
89+
}
90+
91+
func (d *Duration) UnmarshalJSON(b []byte) (err error) {
92+
var s string
93+
if err = json.Unmarshal(b, &s); err == nil {
94+
d.Duration, err = time.ParseDuration(s)
95+
}
96+
return
97+
}

config/confpar/confpar_test.go

Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
package confpar
2+
3+
import (
4+
"bytes"
5+
"encoding/json"
6+
"testing"
7+
"time"
8+
)
9+
10+
func TestDurationMarshalJSON(t *testing.T) {
11+
for _, item := range []struct {
12+
duration time.Duration
13+
want string
14+
}{
15+
{0, `0s`},
16+
{31 * time.Second, `31s`},
17+
{5 * time.Minute, `5m0s`},
18+
{1 * time.Hour, `1h0m0s`},
19+
} {
20+
have, err := json.Marshal(&Duration{item.duration})
21+
if err != nil {
22+
t.Fatalf("json.Marshal(): %v", err)
23+
}
24+
if !bytes.Equal(have, []byte(`"`+item.want+`"`)) {
25+
t.Fatalf("have:%s want:%q", string(have), item.want)
26+
}
27+
}
28+
}
29+
30+
func TestDurationUnmarshalJSON(t *testing.T) {
31+
for _, item := range []struct {
32+
input string
33+
want time.Duration
34+
wantErr bool
35+
}{
36+
{`5m`, 5 * time.Minute, false},
37+
{`30s`, 30 * time.Second, false},
38+
{`1h`, time.Hour, false},
39+
{`0s`, 0, false},
40+
{`invalid`, 0, true},
41+
} {
42+
var have Duration
43+
err := json.Unmarshal([]byte(`"`+item.input+`"`), &have)
44+
if err == nil && item.wantErr {
45+
t.Fatalf("expecting error for invalid input")
46+
}
47+
if err != nil && !item.wantErr {
48+
t.Fatalf("json.Unmarshal(): %v", err)
49+
}
50+
if have.Duration != item.want {
51+
t.Fatalf("have:%v want:%v", have.Duration, item.want)
52+
}
53+
}
54+
}

server/server.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -201,7 +201,7 @@ func (s *Server) getAccessFromWebhook(user, pass string) (*confpar.Access, error
201201
}
202202

203203
// Timeout is implemented with context termination
204-
ctx, cancel := context.WithTimeout(context.Background(), s.config.Content.AccessesWebhook.Timeout)
204+
ctx, cancel := context.WithTimeout(context.Background(), s.config.Content.AccessesWebhook.Timeout.Duration)
205205
defer cancel()
206206

207207
// Create a new HTTP request

0 commit comments

Comments
 (0)