Skip to content

Commit 5e2a8fc

Browse files
committed
parse the endpoint into a URL up front, and gather the proxy from the env up front so that typos and malformed urls will surface immediately
1 parent bdf591f commit 5e2a8fc

1 file changed

Lines changed: 44 additions & 17 deletions

File tree

cmd/src/main.go

Lines changed: 44 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,11 @@ package main
33
import (
44
"encoding/json"
55
"flag"
6+
"fmt"
67
"io"
78
"log"
89
"net"
10+
"net/http"
911
"net/url"
1012
"os"
1113
"path/filepath"
@@ -107,6 +109,20 @@ func normalizeDashHelp(args []string) []string {
107109
return args
108110
}
109111

112+
func parseEndpoint(endpoint string) (*url.URL, error) {
113+
u, err := url.ParseRequestURI(strings.TrimSuffix(endpoint, "/"))
114+
if err != nil {
115+
return nil, err
116+
}
117+
if !(u.Scheme == "http" || u.Scheme == "https") {
118+
return nil, errors.Newf("Invalid scheme %s. Require http or https", u.Scheme)
119+
}
120+
if u.Host == "" {
121+
return nil, errors.Newf("Empty host")
122+
}
123+
return u, nil
124+
}
125+
110126
var cfg *config
111127

112128
// config represents the config format.
@@ -118,12 +134,13 @@ type config struct {
118134
ProxyURL *url.URL
119135
ProxyPath string
120136
ConfigFilePath string
137+
EndpointURL *url.URL
121138
}
122139

123140
// apiClient returns an api.Client built from the configuration.
124141
func (c *config) apiClient(flags *api.Flags, out io.Writer) api.Client {
125142
return api.NewClient(api.ClientOpts{
126-
Endpoint: c.Endpoint,
143+
EndpointURL: c.EndpointURL,
127144
AccessToken: c.AccessToken,
128145
AdditionalHeaders: c.AdditionalHeaders,
129146
Flags: flags,
@@ -133,7 +150,8 @@ func (c *config) apiClient(flags *api.Flags, out io.Writer) api.Client {
133150
})
134151
}
135152

136-
// readConfig reads the config file from the given path.
153+
// readConfig reads the config from the standard config file, the (deprecated) user-specified config file,
154+
// the environment variables, and the (deprecated) command-line flags.
137155
func readConfig() (*config, error) {
138156
cfgFile := *configPath
139157
userSpecified := *configPath != ""
@@ -189,9 +207,21 @@ func readConfig() (*config, error) {
189207
cfg.Proxy = envProxy
190208
}
191209

210+
// Lastly, apply endpoint flag if set
211+
if endpoint != nil && *endpoint != "" {
212+
cfg.Endpoint = *endpoint
213+
}
214+
215+
if endpointURL, err := parseEndpoint(cfg.Endpoint); err != nil {
216+
return nil, errors.Newf("invalid endpoint: %s", cfg.Endpoint)
217+
} else {
218+
cfg.EndpointURL = endpointURL
219+
cfg.Endpoint = endpointURL.String()
220+
}
221+
192222
if cfg.Proxy != "" {
193223

194-
parseEndpoint := func(endpoint string) (scheme string, address string) {
224+
parseProxyEndpoint := func(endpoint string) (scheme string, address string) {
195225
parts := strings.SplitN(endpoint, "://", 2)
196226
if len(parts) == 2 {
197227
return parts[0], parts[1]
@@ -205,7 +235,7 @@ func readConfig() (*config, error) {
205235
return slices.Contains(urlSchemes, scheme)
206236
}
207237

208-
scheme, address := parseEndpoint(cfg.Proxy)
238+
scheme, address := parseProxyEndpoint(cfg.Proxy)
209239

210240
if isURLScheme(scheme) {
211241
endpoint := cfg.Proxy
@@ -227,11 +257,19 @@ func readConfig() (*config, error) {
227257
return nil, errors.Newf("Invalid proxy configuration: %w", err)
228258
}
229259
if !isValidUDS {
230-
return nil, errors.Newf("invalid proxy socket: %s", path)
260+
return nil, errors.Newf("Invalid proxy socket: %s", path)
231261
}
232262
cfg.ProxyPath = path
233263
} else {
234-
return nil, errors.Newf("invalid proxy endpoint: %s", cfg.Proxy)
264+
return nil, errors.Newf("Invalid proxy endpoint: %s", cfg.Proxy)
265+
}
266+
} else {
267+
// no SRC_PROXY; check for the standard proxy env variables HTTP_PROXY, HTTPS_PROXY, and NO_PROXY
268+
if u, err := http.ProxyFromEnvironment(&http.Request{URL: cfg.EndpointURL}); err != nil {
269+
// when there's an error, the value for the env variable is not a legit URL
270+
return nil, fmt.Errorf("Invalid HTTP_PROXY or HTTPS_PROXY value: %w", err)
271+
} else {
272+
cfg.ProxyURL = u
235273
}
236274
}
237275

@@ -242,20 +280,9 @@ func readConfig() (*config, error) {
242280
return nil, errConfigAuthorizationConflict
243281
}
244282

245-
// Lastly, apply endpoint flag if set
246-
if endpoint != nil && *endpoint != "" {
247-
cfg.Endpoint = *endpoint
248-
}
249-
250-
cfg.Endpoint = cleanEndpoint(cfg.Endpoint)
251-
252283
return &cfg, nil
253284
}
254285

255-
func cleanEndpoint(urlStr string) string {
256-
return strings.TrimSuffix(urlStr, "/")
257-
}
258-
259286
// isValidUnixSocket checks if the given path is a valid Unix socket.
260287
//
261288
// Parameters:

0 commit comments

Comments
 (0)