+270
-90
lines changedFilter options
+270
-90
lines changed Original file line number Diff line number Diff line change
@@ -139,7 +139,7 @@ func identifyViaCloudAPI(props *properties.Map, settings *configuration.Settings
139
139
}
140
140
141
141
// identify returns a list of boards checking first the installed platforms or the Cloud API
142
-
func identify(pme *packagemanager.Explorer, port *discovery.Port, settings *configuration.Settings) ([]*rpc.BoardListItem, error) {
142
+
func identify(pme *packagemanager.Explorer, port *discovery.Port, settings *configuration.Settings, skipCloudAPI bool) ([]*rpc.BoardListItem, error) {
143
143
boards := []*rpc.BoardListItem{}
144
144
if port.Properties == nil {
145
145
return boards, nil
@@ -170,7 +170,7 @@ func identify(pme *packagemanager.Explorer, port *discovery.Port, settings *conf
170
170
171
171
// if installed cores didn't recognize the board, try querying
172
172
// the builder API if the board is a USB device port
173
-
if len(boards) == 0 {
173
+
if len(boards) == 0 && !skipCloudAPI && !settings.SkipCloudApiForBoardDetection() {
174
174
items, err := identifyViaCloudAPI(port.Properties, settings)
175
175
if err != nil {
176
176
// this is bad, but keep going
@@ -225,7 +225,7 @@ func (s *arduinoCoreServerImpl) BoardList(ctx context.Context, req *rpc.BoardLis
225
225
226
226
ports := []*rpc.DetectedPort{}
227
227
for _, port := range dm.List() {
228
-
boards, err := identify(pme, port, s.settings)
228
+
boards, err := identify(pme, port, s.settings, req.GetSkipCloudApiForBoardDetection())
229
229
if err != nil {
230
230
warnings = append(warnings, err.Error())
231
231
}
@@ -298,7 +298,7 @@ func (s *arduinoCoreServerImpl) BoardListWatch(req *rpc.BoardListWatchRequest, s
298
298
299
299
boardsError := ""
300
300
if event.Type == "add" {
301
-
boards, err := identify(pme, event.Port, s.settings)
301
+
boards, err := identify(pme, event.Port, s.settings, req.GetSkipCloudApiForBoardDetection())
302
302
if err != nil {
303
303
boardsError = err.Error()
304
304
}
Original file line number Diff line number Diff line change
@@ -157,7 +157,7 @@ func TestBoardIdentifySorting(t *testing.T) {
157
157
defer release()
158
158
159
159
settings := configuration.NewSettings()
160
-
res, err := identify(pme, &discovery.Port{Properties: idPrefs}, settings)
160
+
res, err := identify(pme, &discovery.Port{Properties: idPrefs}, settings, true)
161
161
require.NoError(t, err)
162
162
require.NotNil(t, res)
163
163
require.Len(t, res, 4)
Original file line number Diff line number Diff line change
@@ -224,12 +224,73 @@ func TestDelete(t *testing.T) {
224
224
srv := NewArduinoCoreServer()
225
225
loadConfig(t, srv, paths.New("testdata", "arduino-cli.yml"))
226
226
227
-
_, err := srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"})
227
+
// Check loaded config
228
+
resp, err := srv.ConfigurationSave(context.Background(), &rpc.ConfigurationSaveRequest{
229
+
SettingsFormat: "yaml",
230
+
})
231
+
require.NoError(t, err)
232
+
require.YAMLEq(t, `
233
+
board_manager:
234
+
additional_urls:
235
+
- http://foobar.com
236
+
- http://example.com
237
+
238
+
daemon:
239
+
port: "50051"
240
+
241
+
directories:
242
+
data: /home/massi/.arduino15
243
+
downloads: /home/massi/.arduino15/staging
244
+
245
+
logging:
246
+
file: ""
247
+
format: text
248
+
level: info
249
+
250
+
network:
251
+
proxy: "123"
252
+
`, resp.GetEncodedSettings())
253
+
254
+
// Check default and setted values
255
+
res, err := srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"})
256
+
require.NoError(t, err)
257
+
require.Equal(t, `{"proxy":"123"}`, res.GetEncodedValue())
258
+
// Maybe should be like this?
259
+
// require.Equal(t, `{"proxy":"123","connection_timeout":"1m0s"}`, res.GetEncodedValue())
260
+
res, err = srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network.connection_timeout"})
261
+
require.Equal(t, `"1m0s"`, res.GetEncodedValue()) // default value
228
262
require.NoError(t, err)
229
263
264
+
// Run deletion
230
265
_, err = srv.SettingsSetValue(context.Background(), &rpc.SettingsSetValueRequest{Key: "network", EncodedValue: ""})
231
266
require.NoError(t, err)
267
+
resp, err = srv.ConfigurationSave(context.Background(), &rpc.ConfigurationSaveRequest{
268
+
SettingsFormat: "yaml",
269
+
})
270
+
require.NoError(t, err)
271
+
require.YAMLEq(t, `
272
+
board_manager:
273
+
additional_urls:
274
+
- http://foobar.com
275
+
- http://example.com
232
276
233
-
_, err = srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"})
234
-
require.Error(t, err)
277
+
daemon:
278
+
port: "50051"
279
+
280
+
directories:
281
+
data: /home/massi/.arduino15
282
+
downloads: /home/massi/.arduino15/staging
283
+
284
+
logging:
285
+
file: ""
286
+
format: text
287
+
level: info
288
+
`, resp.GetEncodedSettings())
289
+
// Check default and setted values
290
+
res, err = srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network"})
291
+
require.NoError(t, err)
292
+
require.Equal(t, `{"connection_timeout":"1m0s"}`, res.GetEncodedValue())
293
+
res, err = srv.SettingsGetValue(context.Background(), &rpc.SettingsGetValueRequest{Key: "network.connection_timeout"})
294
+
require.Equal(t, `"1m0s"`, res.GetEncodedValue()) // default value
295
+
require.NoError(t, err)
235
296
}
Original file line number Diff line number Diff line change
@@ -45,6 +45,11 @@
45
45
[time.ParseDuration()](https://pkg.go.dev/time#ParseDuration), defaults to `720h` (30 days).
46
46
- `network` - configuration options related to the network connection.
47
47
- `proxy` - URL of the proxy server.
48
+
- `connection_timeout` - network connection timeout, the value format must be a valid input for
49
+
[time.ParseDuration()](https://pkg.go.dev/time#ParseDuration), defaults to `60s` (60 seconds). `0` means it will
50
+
wait indefinitely.
51
+
- `cloud_api.skip_board_detection_calls` - if set to `true` it will make the Arduino CLI skip network calls to Arduino
52
+
Cloud API to help detection of an unknown board.
48
53
49
54
### Default directories
50
55
Original file line number Diff line number Diff line change
@@ -38,16 +38,8 @@
38
38
},
39
39
"ttl": {
40
40
"description": "cache expiration time of build folders. If the cache is hit by a compilation the corresponding build files lifetime is renewed. The value format must be a valid input for time.ParseDuration(), defaults to `720h` (30 days)",
41
-
"oneOf": [
42
-
{
43
-
"type": "integer",
44
-
"minimum": 0
45
-
},
46
-
{
47
-
"type": "string",
48
-
"pattern": "^\\+?([0-9]?\\.?[0-9]+(([nuµm]?s)|m|h))+$"
49
-
}
50
-
]
41
+
"type": "string",
42
+
"pattern": "^[+-]?(([0-9]+(\\.[0-9]*)?|(\\.[0-9]+))(ns|us|µs|μs|ms|s|m|h))+$"
51
43
}
52
44
},
53
45
"type": "object"
@@ -146,6 +138,35 @@
146
138
},
147
139
"type": "object"
148
140
},
141
+
"network": {
142
+
"description": "settings related to network connections.",
143
+
"type": "object",
144
+
"properties": {
145
+
"proxy": {
146
+
"description": "proxy settings for network connections.",
147
+
"type": "string"
148
+
},
149
+
"user_agent_ext": {
150
+
"description": "extra string to append to the user agent string in HTTP requests.",
151
+
"type": "string"
152
+
},
153
+
"connection_timeout": {
154
+
"description": "timeout for network connections, defaults to '30s'",
155
+
"type": "string",
156
+
"pattern": "^[+-]?(([0-9]+(\\.[0-9]*)?|(\\.[0-9]+))(ns|us|µs|μs|ms|s|m|h))+$"
157
+
},
158
+
"cloud_api": {
159
+
"description": "settings related to the Arduino Cloud API.",
160
+
"type": "object",
161
+
"properties": {
162
+
"skip_board_detection_calls": {
163
+
"description": "do not call the Arduino Cloud API to detect an unknown board",
164
+
"type": "boolean"
165
+
}
166
+
}
167
+
}
168
+
}
169
+
},
149
170
"output": {
150
171
"description": "settings related to text output.",
151
172
"properties": {
Original file line number Diff line number Diff line change
@@ -71,6 +71,9 @@ func SetDefaults(settings *Settings) {
71
71
// network settings
72
72
setKeyTypeSchema("network.proxy", "")
73
73
setKeyTypeSchema("network.user_agent_ext", "")
74
+
setDefaultValueAndKeyTypeSchema("network.connection_timeout", (time.Second * 60).String())
75
+
// network: Arduino Cloud API settings
76
+
setKeyTypeSchema("network.cloud_api.skip_board_detection_calls", false)
74
77
75
78
// locale
76
79
setKeyTypeSchema("locale", "")
Original file line number Diff line number Diff line change
@@ -22,6 +22,7 @@ import (
22
22
"net/url"
23
23
"os"
24
24
"runtime"
25
+
"time"
25
26
26
27
"github.com/arduino/arduino-cli/commands/cmderrors"
27
28
"github.com/arduino/arduino-cli/internal/i18n"
@@ -58,6 +59,19 @@ func (settings *Settings) ExtraUserAgent() string {
58
59
return settings.GetString("network.user_agent_ext")
59
60
}
60
61
62
+
// ConnectionTimeout returns the network connection timeout
63
+
func (settings *Settings) ConnectionTimeout() time.Duration {
64
+
if timeout, ok, _ := settings.GetDurationOk("network.connection_timeout"); ok {
65
+
return timeout
66
+
}
67
+
return settings.Defaults.GetDuration("network.connection_timeout")
68
+
}
69
+
70
+
// SkipCloudApiForBoardDetection returns whether the cloud API should be ignored for board detection
71
+
func (settings *Settings) SkipCloudApiForBoardDetection() bool {
72
+
return settings.GetBool("network.cloud_api.skip_board_detection_calls")
73
+
}
74
+
61
75
// NetworkProxy returns the proxy configuration (mainly used by HTTP clients)
62
76
func (settings *Settings) NetworkProxy() (*url.URL, error) {
63
77
if proxyConfig, ok, _ := settings.GetStringOk("network.proxy"); !ok {
@@ -82,6 +96,7 @@ func (settings *Settings) NewHttpClient() (*http.Client, error) {
82
96
},
83
97
userAgent: settings.UserAgent(),
84
98
},
99
+
Timeout: settings.ConnectionTimeout(),
85
100
}, nil
86
101
}
87
102
Original file line number Diff line number Diff line change
@@ -21,6 +21,7 @@ import (
21
21
"net/http"
22
22
"net/http/httptest"
23
23
"testing"
24
+
"time"
24
25
25
26
"github.com/arduino/arduino-cli/internal/cli/configuration"
26
27
"github.com/stretchr/testify/require"
@@ -68,3 +69,41 @@ func TestProxy(t *testing.T) {
68
69
require.NoError(t, err)
69
70
require.Equal(t, http.StatusNoContent, response.StatusCode)
70
71
}
72
+
73
+
func TestConnectionTimeout(t *testing.T) {
74
+
ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
75
+
time.Sleep(5 * time.Second)
76
+
w.WriteHeader(http.StatusNoContent)
77
+
}))
78
+
defer ts.Close()
79
+
80
+
doRequest := func(timeout int) (*http.Response, time.Duration, error) {
81
+
settings := configuration.NewSettings()
82
+
require.NoError(t, settings.Set("network.proxy", ts.URL))
83
+
if timeout != 0 {
84
+
require.NoError(t, settings.Set("network.connection_timeout", "2s"))
85
+
}
86
+
client, err := settings.NewHttpClient()
87
+
require.NoError(t, err)
88
+
89
+
request, err := http.NewRequest("GET", "http://arduino.cc", nil)
90
+
require.NoError(t, err)
91
+
92
+
start := time.Now()
93
+
resp, err := client.Do(request)
94
+
duration := time.Since(start)
95
+
96
+
return resp, duration, err
97
+
}
98
+
99
+
// Using default timeout (0), will wait indefinitely (in our case up to 5s)
100
+
response, elapsed, err := doRequest(0)
101
+
require.NoError(t, err)
102
+
require.Equal(t, http.StatusNoContent, response.StatusCode)
103
+
require.True(t, elapsed.Seconds() >= 4 && elapsed.Seconds() <= 6) // Adding some tolerance just in case...
104
+
105
+
// Setting a timeout of 1 seconds, will drop the connection after 1s
106
+
_, elapsed, err = doRequest(1)
107
+
require.Error(t, err)
108
+
require.True(t, elapsed.Seconds() >= 0.5 && elapsed.Seconds() <= 3) // Adding some tolerance just in case...
109
+
}
You can’t perform that action at this time.
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4