ipfs-cluster/api/rest/client/client.go
Hector Sanjuan b2651b52ea Refactor some stuff to please codeclimate
License: MIT
Signed-off-by: Hector Sanjuan <code@hector.link>
2017-12-08 17:05:21 +01:00

130 lines
2.9 KiB
Go

package client
import (
"context"
"fmt"
"net/http"
"time"
logging "github.com/ipfs/go-log"
ma "github.com/multiformats/go-multiaddr"
madns "github.com/multiformats/go-multiaddr-dns"
manet "github.com/multiformats/go-multiaddr-net"
)
// Configuration defaults
var (
DefaultTimeout = 60 * time.Second
DefaultAPIAddr = "/ip4/127.0.0.1/tcp/9094"
DefaultLogLevel = "info"
)
var loggingFacility = "apiclient"
var logger = logging.Logger(loggingFacility)
// Config allows to configure the parameters to connect
// to the ipfs-cluster REST API.
type Config struct {
// Enable SSL support
SSL bool
// Skip certificate verification (insecure)
NoVerifyCert bool
// Username and password for basic authentication
Username string
Password string
// The ipfs-cluster REST API endpoint in multiaddress form
// (takes precedence over host:port)
APIAddr ma.Multiaddr
// REST API endpoint host and port. Only valid without
// APIAddr
Host string
Port string
// Define timeout for network operations
Timeout time.Duration
// Specifies if we attempt to re-use connections to the same
// hosts.
DisableKeepAlives bool
// LogLevel defines the verbosity of the logging facility
LogLevel string
}
// Client provides methods to interact with the ipfs-cluster API. Use
// NewClient() to create one.
type Client struct {
ctx context.Context
cancel func()
config *Config
transport http.RoundTripper
urlPrefix string
client *http.Client
}
// NewClient initializes a client given a Config.
func NewClient(cfg *Config) (*Client, error) {
ctx := context.Background()
var urlPrefix = ""
var tr http.RoundTripper
if cfg.SSL {
tr = newTLSTransport(cfg.NoVerifyCert)
urlPrefix += "https://"
} else {
tr = http.DefaultTransport
urlPrefix += "http://"
}
if cfg.Timeout == 0 {
cfg.Timeout = DefaultTimeout
}
// When no host/port/multiaddress defined, we set the default
if cfg.APIAddr == nil && cfg.Host == "" && cfg.Port == "" {
cfg.APIAddr, _ = ma.NewMultiaddr(DefaultAPIAddr)
}
var host string
// APIAddr takes preference. If it exists, it's resolved and dial args
// extracted. Otherwise, host port is used.
if cfg.APIAddr != nil {
// Resolve multiaddress just in case and extract host:port
resolveCtx, cancel := context.WithTimeout(ctx, cfg.Timeout)
defer cancel()
resolved, err := madns.Resolve(resolveCtx, cfg.APIAddr)
cfg.APIAddr = resolved[0]
_, host, err = manet.DialArgs(cfg.APIAddr)
if err != nil {
return nil, err
}
} else {
host = fmt.Sprintf("%s:%s", cfg.Host, cfg.Port)
}
urlPrefix += host
if lvl := cfg.LogLevel; lvl != "" {
logging.SetLogLevel(loggingFacility, lvl)
} else {
logging.SetLogLevel(loggingFacility, DefaultLogLevel)
}
client := &http.Client{
Transport: tr,
Timeout: cfg.Timeout,
}
return &Client{
ctx: ctx,
cancel: nil,
urlPrefix: urlPrefix,
transport: tr,
config: cfg,
client: client,
}, nil
}