@@ -11,9 +11,6 @@ import (
1111 "net/url"
1212 "strconv"
1313 "strings"
14-
15- "github.com/ethersphere/bee/v2/pkg/swarm"
16- "github.com/ethersphere/beekeeper"
1714)
1815
1916const (
@@ -38,11 +35,10 @@ const (
3835 swarmErrorDocumentHeader = "Swarm-Error-Document"
3936)
4037
41- var userAgent = "beekeeper/" + beekeeper .Version
42-
4338// Client manages communication with the Bee API.
4439type Client struct {
4540 httpClient * http.Client // HTTP client must handle authentication implicitly.
41+ apiURL * url.URL // Base URL for API requests.
4642 service service // Reuse a single struct instead of allocating one for each service on the heap.
4743
4844 // Services that API provides.
@@ -70,22 +66,24 @@ type ClientOptions struct {
7066}
7167
7268// NewClient constructs a new Client.
73- func NewClient (baseURL * url.URL , o * ClientOptions ) (c * Client ) {
74- if o == nil {
75- o = new ( ClientOptions )
69+ func NewClient (apiURL * url.URL , httpClient * http. Client ) (* Client , error ) {
70+ if httpClient == nil {
71+ httpClient = & http. Client {}
7672 }
77- if o . HTTPClient == nil {
78- o . HTTPClient = new (http. Client )
73+ if apiURL == nil {
74+ return nil , errors . New ( "baseURL is required" )
7975 }
8076
81- c = newClient (httpClientWithTransport (baseURL , o .HTTPClient ))
82- return
77+ return newClient (apiURL , httpClient ), nil
8378}
8479
8580// newClient constructs a new *Client with the provided http Client, which
8681// should handle authentication implicitly, and sets all API services.
87- func newClient (httpClient * http.Client ) (c * Client ) {
88- c = & Client {httpClient : httpClient }
82+ func newClient (apiURL * url.URL , httpClient * http.Client ) (c * Client ) {
83+ c = & Client {
84+ httpClient : httpClient ,
85+ apiURL : apiURL ,
86+ }
8987 c .service .client = c
9088
9189 c .Act = (* ActService )(& c .service )
@@ -108,32 +106,6 @@ func newClient(httpClient *http.Client) (c *Client) {
108106 return c
109107}
110108
111- func httpClientWithTransport (baseURL * url.URL , c * http.Client ) * http.Client {
112- if c == nil {
113- c = new (http.Client )
114- }
115-
116- transport := c .Transport
117- if transport == nil {
118- transport = http .DefaultTransport
119- }
120-
121- if ! strings .HasSuffix (baseURL .Path , "/" ) {
122- baseURL .Path += "/"
123- }
124-
125- c .Transport = roundTripperFunc (func (r * http.Request ) (resp * http.Response , err error ) {
126- r .Header .Set ("User-Agent" , userAgent )
127- u , err := baseURL .Parse (r .URL .String ())
128- if err != nil {
129- return nil , err
130- }
131- r .URL = u
132- return transport .RoundTrip (r )
133- })
134- return c
135- }
136-
137109// requestJSON handles the HTTP request response cycle. It JSON encodes the request
138110// body, creates an HTTP request with provided method on a path with required
139111// headers and decodes request body if the v argument is not nil and content type is
@@ -150,9 +122,22 @@ func (c *Client) requestJSON(ctx context.Context, method, path string, body, v i
150122 return c .request (ctx , method , path , bodyBuffer , v )
151123}
152124
125+ func (c * Client ) getFullURL (path string ) (string , error ) {
126+ rel , err := url .Parse (path )
127+ if err != nil {
128+ return "" , fmt .Errorf ("failed to parse path: %w" , err )
129+ }
130+ return c .apiURL .ResolveReference (rel ).String (), nil
131+ }
132+
153133// request handles the HTTP request response cycle.
154134func (c * Client ) request (ctx context.Context , method , path string , body io.Reader , v interface {}) (err error ) {
155- req , err := http .NewRequest (method , path , body )
135+ fullURL , err := c .getFullURL (path )
136+ if err != nil {
137+ return err
138+ }
139+
140+ req , err := http .NewRequest (method , fullURL , body )
156141 if err != nil {
157142 return err
158143 }
@@ -196,7 +181,12 @@ func (c *Client) requestData(ctx context.Context, method, path string, body io.R
196181
197182// requestDataGetHeader handles the HTTP request response cycle and returns the response body and header.
198183func (c * Client ) requestDataGetHeader (ctx context.Context , method , path string , body io.Reader , opts * DownloadOptions ) (resp io.ReadCloser , h http.Header , err error ) {
199- req , err := http .NewRequest (method , path , body )
184+ fullURL , err := c .getFullURL (path )
185+ if err != nil {
186+ return nil , nil , err
187+ }
188+
189+ req , err := http .NewRequest (method , fullURL , body )
200190 if err != nil {
201191 return nil , nil , err
202192 }
@@ -245,7 +235,12 @@ func (c *Client) requestDataGetHeader(ctx context.Context, method, path string,
245235
246236// requestWithHeader handles the HTTP request response cycle.
247237func (c * Client ) requestWithHeader (ctx context.Context , method , path string , header http.Header , body io.Reader , v interface {}, headerParser ... func (http.Header )) (err error ) {
248- req , err := http .NewRequest (method , path , body )
238+ fullURL , err := c .getFullURL (path )
239+ if err != nil {
240+ return err
241+ }
242+
243+ req , err := http .NewRequest (method , fullURL , body )
249244 if err != nil {
250245 return err
251246 }
@@ -324,40 +319,3 @@ func responseErrorHandler(r *http.Response) (err error) {
324319type service struct {
325320 client * Client
326321}
327-
328- // Bool is a helper routine that allocates a new bool value to store v and
329- // returns a pointer to it.
330- func Bool (v bool ) (p * bool ) { return & v }
331-
332- // roundTripperFunc type is an adapter to allow the use of ordinary functions as
333- // http.RoundTripper interfaces. If f is a function with the appropriate
334- // signature, roundTripperFunc(f) is a http.RoundTripper that calls f.
335- type roundTripperFunc func (* http.Request ) (* http.Response , error )
336-
337- // RoundTrip calls f(r).
338- func (f roundTripperFunc ) RoundTrip (r * http.Request ) (* http.Response , error ) {
339- return f (r )
340- }
341-
342- type UploadOptions struct {
343- Act bool
344- Pin bool
345- Tag uint64
346- BatchID string
347- Direct bool
348- ActHistoryAddress swarm.Address
349-
350- // Dirs
351- IndexDocument string
352- ErrorDocument string
353- }
354-
355- type DownloadOptions struct {
356- Act * bool
357- ActHistoryAddress * swarm.Address
358- ActPublicKey * swarm.Address
359- ActTimestamp * uint64
360- Cache * bool
361- RedundancyFallbackMode * bool
362- OnlyRootChunk * bool
363- }
0 commit comments