Overhauling error handling of the different APIs as part of #24

- Generalized errors
- Updated version number and User-Agent string
- Made default timeout a const
This commit is contained in:
Winni Neessen 2022-12-22 11:55:56 +01:00
parent 9c4b20b01e
commit c5ea330401
Signed by: wneessen
GPG key ID: 385AC9889632126E
2 changed files with 27 additions and 15 deletions

38
hibp.go
View file

@ -4,6 +4,7 @@ package hibp
import ( import (
"bytes" "bytes"
"crypto/tls" "crypto/tls"
"errors"
"fmt" "fmt"
"io" "io"
"log" "log"
@ -13,7 +14,7 @@ import (
) )
// Version represents the version of this package // Version represents the version of this package
const Version = "1.0.2" const Version = "1.0.5"
// BaseURL is the base URL for the majority of API calls // BaseURL is the base URL for the majority of API calls
const BaseURL = "https://haveibeenpwned.com/api/v3" const BaseURL = "https://haveibeenpwned.com/api/v3"
@ -21,7 +22,22 @@ const BaseURL = "https://haveibeenpwned.com/api/v3"
// DefaultUserAgent defines the default UA string for the HTTP client // DefaultUserAgent defines the default UA string for the HTTP client
// Currently the URL in the UA string is comment out, as there is a bug in the HIBP API // Currently the URL in the UA string is comment out, as there is a bug in the HIBP API
// not allowing multiple slashes // not allowing multiple slashes
const DefaultUserAgent = `go-hibp v` + Version + ` (https://github.com/wneessen/go-hibp)` const DefaultUserAgent = `go-hibp/` + Version + ` (+https://github.com/wneessen/go-hibp)`
// DefaultTimeout is the default timeout value for the HTTP client
const DefaultTimeout = time.Second * 5
// List of common errors
var (
// ErrNoAccountID is returned if no account ID is given to the corresponding API method
ErrNoAccountID = errors.New("no account ID given")
// ErrNoName is returned if no name is given to the corresponding API method
ErrNoName = errors.New("no name given")
// ErrNonPositiveResponse should be returned if a HTTP request failed with a non HTTP-200 status
ErrNonPositiveResponse = errors.New("non HTTP-200 response for HTTP request")
)
// Client is the HIBP client object // Client is the HIBP client object
type Client struct { type Client struct {
@ -49,7 +65,7 @@ func New(options ...Option) Client {
c := Client{} c := Client{}
// Set defaults // Set defaults
c.to = time.Second * 5 c.to = DefaultTimeout
c.PwnedPassAPIOpts = &PwnedPasswordOptions{} c.PwnedPassAPIOpts = &PwnedPasswordOptions{}
c.ua = DefaultUserAgent c.ua = DefaultUserAgent
@ -183,7 +199,7 @@ func (c *Client) HTTPResBody(m string, p string, q map[string]string) ([]byte, *
} }
if hr.StatusCode != 200 { if hr.StatusCode != 200 {
return nil, hr, fmt.Errorf("API responded with non HTTP-200: %s - %s", hr.Status, hb) return nil, hr, fmt.Errorf("HTTP %s: %w", hr.Status, ErrNonPositiveResponse)
} }
return hb, hr, nil return hb, hr, nil
@ -191,18 +207,18 @@ func (c *Client) HTTPResBody(m string, p string, q map[string]string) ([]byte, *
// httpClient returns a custom http client for the HIBP Client object // httpClient returns a custom http client for the HIBP Client object
func httpClient(to time.Duration) *http.Client { func httpClient(to time.Duration) *http.Client {
tlsConfig := &tls.Config{ tc := &tls.Config{
MaxVersion: tls.VersionTLS13, MaxVersion: tls.VersionTLS13,
MinVersion: tls.VersionTLS12, MinVersion: tls.VersionTLS12,
} }
httpTransport := &http.Transport{TLSClientConfig: tlsConfig} ht := &http.Transport{TLSClientConfig: tc}
httpClient := &http.Client{ hc := &http.Client{
Transport: httpTransport, Transport: ht,
Timeout: 5 * time.Second, Timeout: DefaultTimeout,
} }
if to.Nanoseconds() > 0 { if to.Nanoseconds() > 0 {
httpClient.Timeout = to hc.Timeout = to
} }
return httpClient return hc
} }

View file

@ -2,15 +2,11 @@ package hibp
import ( import (
"encoding/json" "encoding/json"
"errors"
"fmt" "fmt"
"net/http" "net/http"
"time" "time"
) )
// ErrNoAccountID is returned if no account ID is given to the PastedAccount method
var ErrNoAccountID = errors.New("no account ID given")
// PasteAPI is a HIBP pastes API client // PasteAPI is a HIBP pastes API client
type PasteAPI struct { type PasteAPI struct {
hibp *Client // References back to the parent HIBP client hibp *Client // References back to the parent HIBP client