@cryptotaxi247 / kubo / commits / 5f692a76d

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 +}