@cryptotaxi247 / kubo / commits / 3b02ea464

api: add authenticated transport, and direct connection

This commit was moved from ipfs/go-ipfs-http-client@d04afa02b059d2c6a631f23a6923eb57ecb21015

Alex committed Apr 9, 2019 at 19:53 UTC 3b02ea46462d1f87a64e3fe23f73ee0f186b40d5
3 files changed +80 -2
client/httpapi/api.go
+36
@@ -122,6 +122,42 @@ func NewApiWithClient(a ma.Multiaddr, c *gohttp.Client) (*HttpApi, error) {
122 return api, nil
123 }
124
125 +// NewDirectAPIClient is used to instantiate a HttpApi client
126 +// that connects to an endpoint which leverages additional http paths.
127 +//
128 +// If you need to connect to a IPFS HTTP API located at https://foo.bar/baz/api/v0
129 +// you should use NewDirectAPIClient.
130 +func NewDirectAPIClient(url string) (*HttpApi, error) {
131 + api := &HttpApi{
132 + url: url,
133 + httpcli: gohttp.Client{
134 + Transport: &gohttp.Transport{
135 + Proxy: gohttp.ProxyFromEnvironment,
136 + DisableKeepAlives: true,
137 + },
138 + },
139 + applyGlobal: func(*RequestBuilder) {},
140 + }
141 +
142 + // We don't support redirects.
143 + api.httpcli.CheckRedirect = func(_ *gohttp.Request, _ []*gohttp.Request) error {
144 + return fmt.Errorf("unexpected redirect")
145 + }
146 +
147 + return api, nil
148 +}
149 +
150 +// WithAuthorization is used to wrap an instance of HttpApi
151 +// with an authenticated transport, such as JWT
152 +func (api *HttpApi) WithAuthorization(header, value string) *HttpApi {
153 + return &HttpApi{
154 + url: api.url,
155 + httpcli: gohttp.Client{
156 + Transport: newAuthenticatedTransport(api.httpcli.Transport, header, value),
157 + },
158 + }
159 +}
160 +
161 func (api *HttpApi) WithOptions(opts ...caopts.ApiOption) (iface.CoreAPI, error) {
162 options, err := caopts.ApiOptions(opts...)
163 if err != nil {
client/httpapi/api_test.go
+23 -2
@@ -9,11 +9,11 @@ import (
9 "sync"
10 "testing"
11
12 - "github.com/ipfs/interface-go-ipfs-core"
12 + iface "github.com/ipfs/interface-go-ipfs-core"
13 "github.com/ipfs/interface-go-ipfs-core/tests"
14 local "github.com/ipfs/iptb-plugins/local"
15 "github.com/ipfs/iptb/testbed"
16 - "github.com/ipfs/iptb/testbed/interfaces"
16 + testbedi "github.com/ipfs/iptb/testbed/interfaces"
17 ma "github.com/multiformats/go-multiaddr"
18 )
19
@@ -211,3 +211,24 @@ func TestHttpApi(t *testing.T) {
211
212 tests.TestApi(newNodeProvider(ctx))(t)
213 }
214 +
215 +func TestDirectAPI(t *testing.T) {
216 + type args struct {
217 + url, header, value string
218 + }
219 + tests := []struct {
220 + name string
221 + args args
222 + }{
223 + {"Success", args{"http://127.0.0.1:5001/foo/bar/api/v0", "Authorization", "Bearer token"}},
224 + }
225 + for _, tt := range tests {
226 + t.Run(tt.name, func(t *testing.T) {
227 + api, err := NewDirectAPIClient(tt.args.url)
228 + if err != nil {
229 + t.Fatal(err)
230 + }
231 + api = api.WithAuthorization(tt.args.header, tt.args.value)
232 + })
233 + }
234 +}
client/httpapi/transport.go new
+21
@@ -0,0 +1,21 @@
1 +package httpapi
2 +
3 +import "net/http"
4 +
5 +type transport struct {
6 + header, value string
7 + httptr http.RoundTripper
8 +}
9 +
10 +func newAuthenticatedTransport(tr http.RoundTripper, header, value string) *transport {
11 + return &transport{
12 + header: header,
13 + value: value,
14 + httptr: tr,
15 + }
16 +}
17 +
18 +func (t *transport) RoundTrip(req *http.Request) (*http.Response, error) {
19 + req.Header.Set(t.header, t.value)
20 + return t.httptr.RoundTrip(req)
21 +}