Skip to content

Commit

Permalink
Merge pull request #121 from PagerDuty/custom_HTTPClient
Browse files Browse the repository at this point in the history
Allow package consumers to provide their own HTTP client
  • Loading branch information
mattstratton authored Jun 1, 2018
2 parents b4a4067 + 2c56a10 commit c71479b
Show file tree
Hide file tree
Showing 3 changed files with 61 additions and 4 deletions.
5 changes: 5 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,11 @@ func main() {
}
```

The PagerDuty API client also exposes its HTTP client as the `HTTPClient` field.
If you need to use your own HTTP client, for doing things like defining your own
transport settings, you can replace the default HTTP client with your own by
simply by setting a new value in the `HTTPClient` field.

## License
[Apache 2](http://www.apache.org/licenses/LICENSE-2.0)

Expand Down
46 changes: 44 additions & 2 deletions client.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,10 @@ import (
"encoding/json"
"fmt"
"io"
"net"
"net/http"
"runtime"
"time"
)

const (
Expand Down Expand Up @@ -42,15 +45,54 @@ type errorObject struct {
Errors interface{} `json:"errors,omitempty"`
}

func newDefaultHTTPClient() *http.Client {
return &http.Client{
Transport: &http.Transport{
Proxy: http.ProxyFromEnvironment,
DialContext: (&net.Dialer{
Timeout: 30 * time.Second,
KeepAlive: 30 * time.Second,
}).DialContext,
MaxIdleConns: 10,
IdleConnTimeout: 60 * time.Second,
TLSHandshakeTimeout: 10 * time.Second,
ExpectContinueTimeout: 1 * time.Second,
MaxIdleConnsPerHost: runtime.GOMAXPROCS(0) + 1,
},
}
}

// HTTPClient is an interface which declares the functionality we need from an
// HTTP client. This is to allow consumers to provide their own HTTP client as
// needed, without restricting them to only using *http.Client.
type HTTPClient interface {
Do(*http.Request) (*http.Response, error)
}

// defaultHTTPClient is our own default HTTP client. We use this, instead of
// http.DefaultClient, to avoid other packages tweaks to http.DefaultClient
// causing issues with our HTTP calls. This also allows us to tweak the
// transport values to be more resilient without making changes to the
// http.DefaultClient.
//
// Keep this unexported so consumers of the package can't make changes to it.
var defaultHTTPClient HTTPClient = newDefaultHTTPClient()

// Client wraps http client
type Client struct {
authToken string

// HTTPClient is the HTTP client used for making requests against the
// PagerDuty API. You can use either *http.Client here, or your own
// implementation.
HTTPClient HTTPClient
}

// NewClient creates an API client
func NewClient(authToken string) *Client {
return &Client{
authToken: authToken,
authToken: authToken,
HTTPClient: defaultHTTPClient,
}
}

Expand Down Expand Up @@ -94,7 +136,7 @@ func (c *Client) do(method, path string, body io.Reader, headers *map[string]str
req.Header.Set("Content-Type", "application/json")
req.Header.Set("Authorization", "Token token="+c.authToken)

resp, err := http.DefaultClient.Do(req)
resp, err := c.HTTPClient.Do(req)
return c.checkResponse(resp, err)
}

Expand Down
14 changes: 12 additions & 2 deletions event.go
Original file line number Diff line number Diff line change
Expand Up @@ -28,15 +28,25 @@ type EventResponse struct {
IncidentKey string `json:"incident_key"`
}

// CreateEvent sends PagerDuty an event to report, acknowledge, or resolve a problem.
// CreateEvent sends PagerDuty an event to trigger, acknowledge, or resolve a
// problem. If you need to provide a custom HTTP client, please use
// CreateEventWithHTTPClient.
func CreateEvent(e Event) (*EventResponse, error) {
return CreateEventWithHTTPClient(e, defaultHTTPClient)
}

// CreateEventWithHTTPClient sends PagerDuty an event to trigger, acknowledge,
// or resolve a problem. This function accepts a custom HTTP Client, if the
// default one used by this package doesn't fit your needs. If you don't need a
// custom HTTP client, please use CreateEvent instead.
func CreateEventWithHTTPClient(e Event, client HTTPClient) (*EventResponse, error) {
data, err := json.Marshal(e)
if err != nil {
return nil, err
}
req, _ := http.NewRequest("POST", eventEndPoint, bytes.NewBuffer(data))
req.Header.Set("Content-Type", "application/json")
resp, err := http.DefaultClient.Do(req)
resp, err := client.Do(req)
if err != nil {
return nil, err
}
Expand Down

0 comments on commit c71479b

Please sign in to comment.