The public code is `SaveAsFile()`.  It takes a URL, checksum and authentication info, and downloads the artifact and its hash using HTTP.  It saves the content as a file and returns the file's path on success, otherwise an error.

As I'm fairly new to Go I would like to get some feedback on the error handling and on any ways to write this code more elegantly?

https://go.dev/play/p/8i_xZ-EVTvP

    import (
    	"io"
    	"io/ioutil"
    	"net/http"
    	"os"
    	"strings"
    	"time"
    
    	"github.com/pkg/errors"
    )
    
    var errCode = errors.New("bad response status code")
    var errFileNotWritten = errors.New("file not written")
    var errDigest = errors.New("digest are not identical")
    
    const (
    	statusMsg        = `code: %d, response body:\n%s`
    	notWritten       = `unable to write file %s from Response body`
    	msgDigestFailure = `target: \"%s\", file: \"%s\")`
    	msgFileNotClosed = `unable to close file %s`
    )
    
    func respBody(url string, user string, pass string) (io.ReadCloser, error) {
    	client := &http.Client{
    		Timeout: time.Second * 10,
    	}
    	req, err := http.NewRequest("GET", url, nil)
    	if err != nil {
    		return nil, err
    	}
    
    	if user != "" && pass != "" {
    		req.SetBasicAuth(user, pass)
    	}
    	resp, err := client.Do(req)
    	if err != nil {
    		return nil, err
    	}
    	if resp.StatusCode < 200 || resp.StatusCode >= 300 {
    		return nil, errors.Wrapf(errCode, statusMsg, resp.StatusCode, resp.Body)
    	}
    	return resp.Body, nil
    }
    
    func classify(url string, user string, pass string) (string, error) {
    	const suffix = ".sha512"
    	rb, err := respBody(url+suffix, user, pass)
    	if err != nil {
    		return "", err
    	}
    	defer rb.Close()
    	bodyBytes, err := ioutil.ReadAll(rb)
    	if err != nil {
    		return "", err
    	}
    
    	return string(bodyBytes), nil
    }
    
    func downFile(url string, user string, pass string) (*os.File, error) {
    	responseBody, err := respBody(url, user, pass)
    	if err != nil {
    		return nil, err
    	}
    	defer responseBody.Close()
    
    	file, err := ioutil.TempFile("", "*")
    	if err != nil {
    		return nil, err
    	}
    	written, err := io.Copy(file, responseBody)
    	if err != nil {
    		return nil, errors.Wrapf(err, notWritten, file.Name())
    	} else if written <= 0 {
    		return nil, errors.Wrapf(errFileNotWritten, notWritten, file.Name())
    	}
    
    	if err := file.Close(); err != nil {
    		return nil, errors.Wrapf(err, msgFileNotClosed, file.Name())
    	}
    
    	return file, nil
    }
    
    
    func SaveAsFile(url string, digest string, user string, pass string) (string, error) {
    	file, err := downFile(url, user, pass)
    	if err != nil {
    		return "", err
    	}
    	if digest != "" {
    		targetDigest, err := classify(url, user, pass)
    		if err != nil {
    			return "", err
    		}
    		if strings.Compare(targetDigest, digest) != 0 {
    			return "", errors.Wrapf(errDigest, msgDigestFailure, targetDigest, digest)
    		}
    	}
    	return file.Name(), nil
    }