fix: normalize remote service endpoint
Closes #7826
Marcin Rataj committed
Dec 14, 2020 at 19:56 UTC
5f692a76de01918b202aab1bc5d6657bb177a0ea
2 files changed
+80
-6
core/commands/pin/remotepin.go
+23
-6
@@ -443,12 +443,12 @@ TIP:
443
}
444
445
name := req.Arguments[0]
446
- url := strings.TrimSuffix(req.Arguments[1], "/pins") // fix /pins/pins :-)
446
+ url := req.Arguments[1]
447
key := req.Arguments[2]
448
449
- u, err := neturl.ParseRequestURI(url)
450
- if err != nil || !strings.HasPrefix(u.Scheme, "http") {
451
- return fmt.Errorf("service endpoint must be a valid HTTP URL")
449
+ endpoint, err := normalizeEndpoint(url)
450
+ if err != nil {
451
+ return err
452
}
453
454
cfg, err := repo.Config()
@@ -465,7 +465,7 @@ TIP:
465
466
cfg.Pinning.RemoteServices[name] = config.RemotePinningService{
467
Api: config.RemotePinningServiceApi{
468
- Endpoint: url,
468
+ Endpoint: endpoint,
469
Key: key,
470
},
471
}
@@ -708,7 +708,11 @@ func getRemotePinService(env cmds.Environment, name string) (*pinclient.Client,
708
if err != nil {
709
return nil, err
710
}
711
- return pinclient.NewClient(url, key), nil
711
+ endpoint, err := normalizeEndpoint(url)
712
+ if err != nil {
713
+ return nil, err
714
+ }
715
+ return pinclient.NewClient(endpoint, key), nil
716
}
717
718
func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string, err error) {
@@ -734,3 +738,16 @@ func getRemotePinServiceInfo(env cmds.Environment, name string) (url, key string
738
}
739
return service.Api.Endpoint, service.Api.Key, nil
740
}
741
+
742
+func normalizeEndpoint(endpoint string) (string, error) {
743
+ uri, err := neturl.ParseRequestURI(endpoint)
744
+ if err != nil || !strings.HasPrefix(uri.Scheme, "http") {
745
+ return "", fmt.Errorf("service endpoint must be a valid HTTP URL")
746
+ }
747
+ // avoid //pins (https://github.com/ipfs/go-ipfs/issues/7826)
748
+ uri.Path = strings.TrimSuffix(uri.Path, "/")
749
+ // avoid /pins/pins
750
+ uri.Path = strings.TrimSuffix(uri.Path, "/pins")
751
+
752
+ return uri.String(), nil
753
+}
core/commands/pin/remotepin_test.go
new
+57
@@ -0,0 +1,57 @@
1
+package pin
2
+
3
+import (
4
+ "testing"
5
+)
6
+
7
+func TestNormalizeEndpoint(t *testing.T) {
8
+ cases := []struct {
9
+ in string
10
+ err string
11
+ out string
12
+ }{
13
+ {
14
+ in: "https://1.example.com",
15
+ err: "",
16
+ out: "https://1.example.com",
17
+ },
18
+ {
19
+ in: "https://2.example.com/",
20
+ err: "",
21
+ out: "https://2.example.com",
22
+ },
23
+ {
24
+ in: "https://3.example.com/pins/",
25
+ err: "",
26
+ out: "https://3.example.com",
27
+ },
28
+ {
29
+ in: "https://4.example.com/pins",
30
+ err: "",
31
+ out: "https://4.example.com",
32
+ },
33
+ {
34
+ in: "http://192.168.0.5:45000/pins",
35
+ err: "",
36
+ out: "http://192.168.0.5:45000",
37
+ },
38
+ {
39
+ in: "foo://4.example.com/pins",
40
+ err: "service endpoint must be a valid HTTP URL",
41
+ out: "",
42
+ },
43
+ }
44
+
45
+ for _, tc := range cases {
46
+ out, err := normalizeEndpoint(tc.in)
47
+ if out != tc.out {
48
+ t.Errorf("unexpected endpoint for %q: expected %q; got %q", tc.in, tc.out, out)
49
+ continue
50
+ }
51
+ if err != nil && tc.err != err.Error() {
52
+ t.Errorf("unexpected error for %q: expected %q; got %q", tc.in, tc.err, err)
53
+ continue
54
+ }
55
+ }
56
+
57
+}