github.com/masterhung0112/hk_server/v5@v5.0.0-20220302090640-ec71aef15e1c/services/marketplace/client.go (about)

     1  // Copyright (c) 2015-present Mattermost, Inc. All Rights Reserved.
     2  // See LICENSE.txt for license information.
     3  
     4  package marketplace
     5  
     6  import (
     7  	"fmt"
     8  	"io"
     9  	"io/ioutil"
    10  	"net/http"
    11  	"net/url"
    12  	"strings"
    13  
    14  	"github.com/pkg/errors"
    15  
    16  	"github.com/masterhung0112/hk_server/v5/model"
    17  	"github.com/masterhung0112/hk_server/v5/services/httpservice"
    18  )
    19  
    20  // Client is the programmatic interface to the marketplace server API.
    21  type Client struct {
    22  	address    string
    23  	httpClient *http.Client
    24  }
    25  
    26  // NewClient creates a client to the marketplace server at the given address.
    27  func NewClient(address string, httpService httpservice.HTTPService) (*Client, error) {
    28  	var httpClient *http.Client
    29  	addressURL, err := url.Parse(address)
    30  	if err != nil {
    31  		return nil, errors.Wrap(err, "failed to parse marketplace address")
    32  	}
    33  	if addressURL.Hostname() == "localhost" || addressURL.Hostname() == "127.0.0.1" {
    34  		httpClient = httpService.MakeClient(true)
    35  	} else {
    36  		httpClient = httpService.MakeClient(false)
    37  	}
    38  
    39  	return &Client{
    40  		address:    address,
    41  		httpClient: httpClient,
    42  	}, nil
    43  }
    44  
    45  // GetPlugins fetches the list of plugins from the configured server.
    46  func (c *Client) GetPlugins(request *model.MarketplacePluginFilter) ([]*model.BaseMarketplacePlugin, error) {
    47  	u, err := url.Parse(c.buildURL("/api/v1/plugins"))
    48  	if err != nil {
    49  		return nil, err
    50  	}
    51  
    52  	request.ApplyToURL(u)
    53  
    54  	resp, err := c.doGet(u.String())
    55  	if err != nil {
    56  		return nil, err
    57  	}
    58  	defer closeBody(resp)
    59  
    60  	switch resp.StatusCode {
    61  	case http.StatusOK:
    62  		return model.BaseMarketplacePluginsFromReader(resp.Body)
    63  	default:
    64  		return nil, errors.Errorf("failed with status code %d", resp.StatusCode)
    65  	}
    66  }
    67  
    68  func (c *Client) GetPlugin(filter *model.MarketplacePluginFilter, pluginVersion string) (*model.BaseMarketplacePlugin, error) {
    69  	plugins, err := c.GetPlugins(filter)
    70  	if err != nil {
    71  		return nil, err
    72  	}
    73  	for _, plugin := range plugins {
    74  		if plugin.Manifest.Version == pluginVersion {
    75  			return plugin, nil
    76  		}
    77  	}
    78  	return nil, errors.New("plugin not found")
    79  }
    80  
    81  // closeBody ensures the Body of an http.Response is properly closed.
    82  func closeBody(r *http.Response) {
    83  	if r.Body != nil {
    84  		_, _ = io.Copy(ioutil.Discard, r.Body)
    85  		_ = r.Body.Close()
    86  	}
    87  }
    88  
    89  func (c *Client) buildURL(urlPath string, args ...interface{}) string {
    90  	return fmt.Sprintf("%s/%s", strings.TrimRight(c.address, "/"), strings.TrimLeft(fmt.Sprintf(urlPath, args...), "/"))
    91  }
    92  
    93  func (c *Client) doGet(u string) (*http.Response, error) {
    94  	return c.httpClient.Get(u)
    95  }