github.com/crowdsecurity/crowdsec@v1.6.1/pkg/cwhub/remote.go (about)

     1  package cwhub
     2  
     3  import (
     4  	"fmt"
     5  	"io"
     6  	"net/http"
     7  )
     8  
     9  // RemoteHubCfg is used to retrieve index and items from the remote hub.
    10  type RemoteHubCfg struct {
    11  	Branch      string
    12  	URLTemplate string
    13  	IndexPath   string
    14  }
    15  
    16  // urlTo builds the URL to download a file from the remote hub.
    17  func (r *RemoteHubCfg) urlTo(remotePath string) (string, error) {
    18  	if r == nil {
    19  		return "", ErrNilRemoteHub
    20  	}
    21  
    22  	// the template must contain two string placeholders
    23  	if fmt.Sprintf(r.URLTemplate, "%s", "%s") != r.URLTemplate {
    24  		return "", fmt.Errorf("invalid URL template '%s'", r.URLTemplate)
    25  	}
    26  
    27  	return fmt.Sprintf(r.URLTemplate, r.Branch, remotePath), nil
    28  }
    29  
    30  // fetchIndex downloads the index from the hub and returns the content.
    31  func (r *RemoteHubCfg) fetchIndex() ([]byte, error) {
    32  	if r == nil {
    33  		return nil, ErrNilRemoteHub
    34  	}
    35  
    36  	url, err := r.urlTo(r.IndexPath)
    37  	if err != nil {
    38  		return nil, fmt.Errorf("failed to build hub index request: %w", err)
    39  	}
    40  
    41  	resp, err := hubClient.Get(url)
    42  	if err != nil {
    43  		return nil, fmt.Errorf("failed http request for hub index: %w", err)
    44  	}
    45  	defer resp.Body.Close()
    46  
    47  	if resp.StatusCode != http.StatusOK {
    48  		if resp.StatusCode == http.StatusNotFound {
    49  			return nil, IndexNotFoundError{url, r.Branch}
    50  		}
    51  
    52  		return nil, fmt.Errorf("bad http code %d for %s", resp.StatusCode, url)
    53  	}
    54  
    55  	body, err := io.ReadAll(resp.Body)
    56  	if err != nil {
    57  		return nil, fmt.Errorf("failed to read request answer for hub index: %w", err)
    58  	}
    59  
    60  	return body, nil
    61  }