164 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			164 lines
		
	
	
		
			5.5 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package mailgun
 | |
| 
 | |
| import (
 | |
| 	"context"
 | |
| 	"fmt"
 | |
| )
 | |
| 
 | |
| // The MailgunGoUserAgent identifies the client to the server, for logging purposes.
 | |
| // In the event of problems requiring a human administrator's assistance,
 | |
| // this user agent allows them to identify the client from human-generated activity.
 | |
| const MailgunGoUserAgent = "mailgun-go/" + Version
 | |
| 
 | |
| // This error will be returned whenever a Mailgun API returns an error response.
 | |
| // Your application can check the Actual field to see the actual HTTP response code returned.
 | |
| // URL contains the base URL accessed, sans any query parameters.
 | |
| type UnexpectedResponseError struct {
 | |
| 	Expected []int
 | |
| 	Actual   int
 | |
| 	URL      string
 | |
| 	Data     []byte
 | |
| }
 | |
| 
 | |
| // String() converts the error into a human-readable, logfmt-compliant string.
 | |
| // See http://godoc.org/github.com/kr/logfmt for details on logfmt formatting.
 | |
| func (e *UnexpectedResponseError) String() string {
 | |
| 	return fmt.Sprintf("UnexpectedResponseError URL=%s ExpectedOneOf=%#v Got=%d Error: %s", e.URL, e.Expected, e.Actual, string(e.Data))
 | |
| }
 | |
| 
 | |
| // Error() performs as String().
 | |
| func (e *UnexpectedResponseError) Error() string {
 | |
| 	return e.String()
 | |
| }
 | |
| 
 | |
| // newError creates a new error condition to be returned.
 | |
| func newError(url string, expected []int, got *httpResponse) error {
 | |
| 	return &UnexpectedResponseError{
 | |
| 		URL:      url,
 | |
| 		Expected: expected,
 | |
| 		Actual:   got.Code,
 | |
| 		Data:     got.Data,
 | |
| 	}
 | |
| }
 | |
| 
 | |
| // notGood searches a list of response codes (the haystack) for a matching entry (the needle).
 | |
| // If found, the response code is considered good, and thus false is returned.
 | |
| // Otherwise true is returned.
 | |
| func notGood(needle int, haystack []int) bool {
 | |
| 	for _, i := range haystack {
 | |
| 		if needle == i {
 | |
| 			return false
 | |
| 		}
 | |
| 	}
 | |
| 	return true
 | |
| }
 | |
| 
 | |
| // expected denotes the expected list of known-good HTTP response codes possible from the Mailgun API.
 | |
| var expected = []int{200, 202, 204}
 | |
| 
 | |
| // makeRequest shim performs a generic request, checking for a positive outcome.
 | |
| // See simplehttp.MakeRequest for more details.
 | |
| func makeRequest(ctx context.Context, r *httpRequest, method string, p payload) (*httpResponse, error) {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	rsp, err := r.makeRequest(ctx, method, p)
 | |
| 	if (err == nil) && notGood(rsp.Code, expected) {
 | |
| 		return rsp, newError(r.URL, expected, rsp)
 | |
| 	}
 | |
| 	return rsp, err
 | |
| }
 | |
| 
 | |
| // getResponseFromJSON shim performs a GET request, checking for a positive outcome.
 | |
| // See simplehttp.GetResponseFromJSON for more details.
 | |
| func getResponseFromJSON(ctx context.Context, r *httpRequest, v interface{}) error {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	response, err := r.makeGetRequest(ctx)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	if notGood(response.Code, expected) {
 | |
| 		return newError(r.URL, expected, response)
 | |
| 	}
 | |
| 	return response.parseFromJSON(v)
 | |
| }
 | |
| 
 | |
| // postResponseFromJSON shim performs a POST request, checking for a positive outcome.
 | |
| // See simplehttp.PostResponseFromJSON for more details.
 | |
| func postResponseFromJSON(ctx context.Context, r *httpRequest, p payload, v interface{}) error {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	response, err := r.makePostRequest(ctx, p)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	if notGood(response.Code, expected) {
 | |
| 		return newError(r.URL, expected, response)
 | |
| 	}
 | |
| 	return response.parseFromJSON(v)
 | |
| }
 | |
| 
 | |
| // putResponseFromJSON shim performs a PUT request, checking for a positive outcome.
 | |
| // See simplehttp.PutResponseFromJSON for more details.
 | |
| func putResponseFromJSON(ctx context.Context, r *httpRequest, p payload, v interface{}) error {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	response, err := r.makePutRequest(ctx, p)
 | |
| 	if err != nil {
 | |
| 		return err
 | |
| 	}
 | |
| 	if notGood(response.Code, expected) {
 | |
| 		return newError(r.URL, expected, response)
 | |
| 	}
 | |
| 	return response.parseFromJSON(v)
 | |
| }
 | |
| 
 | |
| // makeGetRequest shim performs a GET request, checking for a positive outcome.
 | |
| // See simplehttp.MakeGetRequest for more details.
 | |
| func makeGetRequest(ctx context.Context, r *httpRequest) (*httpResponse, error) {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	rsp, err := r.makeGetRequest(ctx)
 | |
| 	if (err == nil) && notGood(rsp.Code, expected) {
 | |
| 		return rsp, newError(r.URL, expected, rsp)
 | |
| 	}
 | |
| 	return rsp, err
 | |
| }
 | |
| 
 | |
| // makePostRequest shim performs a POST request, checking for a positive outcome.
 | |
| // See simplehttp.MakePostRequest for more details.
 | |
| func makePostRequest(ctx context.Context, r *httpRequest, p payload) (*httpResponse, error) {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	rsp, err := r.makePostRequest(ctx, p)
 | |
| 	if (err == nil) && notGood(rsp.Code, expected) {
 | |
| 		return rsp, newError(r.URL, expected, rsp)
 | |
| 	}
 | |
| 	return rsp, err
 | |
| }
 | |
| 
 | |
| // makePutRequest shim performs a PUT request, checking for a positive outcome.
 | |
| // See simplehttp.MakePutRequest for more details.
 | |
| func makePutRequest(ctx context.Context, r *httpRequest, p payload) (*httpResponse, error) {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	rsp, err := r.makePutRequest(ctx, p)
 | |
| 	if (err == nil) && notGood(rsp.Code, expected) {
 | |
| 		return rsp, newError(r.URL, expected, rsp)
 | |
| 	}
 | |
| 	return rsp, err
 | |
| }
 | |
| 
 | |
| // makeDeleteRequest shim performs a DELETE request, checking for a positive outcome.
 | |
| // See simplehttp.MakeDeleteRequest for more details.
 | |
| func makeDeleteRequest(ctx context.Context, r *httpRequest) (*httpResponse, error) {
 | |
| 	r.addHeader("User-Agent", MailgunGoUserAgent)
 | |
| 	rsp, err := r.makeDeleteRequest(ctx)
 | |
| 	if (err == nil) && notGood(rsp.Code, expected) {
 | |
| 		return rsp, newError(r.URL, expected, rsp)
 | |
| 	}
 | |
| 	return rsp, err
 | |
| }
 | |
| 
 | |
| // Extract the http status code from error object
 | |
| func GetStatusFromErr(err error) int {
 | |
| 	obj, ok := err.(*UnexpectedResponseError)
 | |
| 	if !ok {
 | |
| 		return -1
 | |
| 	}
 | |
| 	return obj.Actual
 | |
| }
 |