Skip to content

Commit

Permalink
Merge pull request #287 from thrawn01/thrawn/develop
Browse files Browse the repository at this point in the history
Added AddOverrideHeader()
  • Loading branch information
thrawn01 authored May 27, 2022
2 parents acda9bf + d25e820 commit 908899b
Show file tree
Hide file tree
Showing 4 changed files with 62 additions and 6 deletions.
8 changes: 7 additions & 1 deletion httphelpers.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"context"
"encoding/json"
"fmt"
"github.com/pkg/errors"
"io"
"io/ioutil"
"mime/multipart"
Expand All @@ -15,6 +14,8 @@ import (
"path"
"regexp"
"strings"

"github.com/pkg/errors"
)

var validURL = regexp.MustCompile(`/v[2-4].*`)
Expand Down Expand Up @@ -274,6 +275,11 @@ func (r *httpRequest) NewRequest(ctx context.Context, method string, payload pay
}

for header, value := range r.Headers {
// Special case, override the Host header
if header == "Host" {
req.Host = value
continue
}
req.Header.Add(header, value)
}
return req, nil
Expand Down
21 changes: 16 additions & 5 deletions mailgun.go
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ type Mailgun interface {
Client() *http.Client
SetClient(client *http.Client)
SetAPIBase(url string)
AddOverrideHeader(k string, v string)

Send(ctx context.Context, m *Message) (string, string, error)
ReSend(ctx context.Context, id string, recipients ...string) (string, string, error)
Expand Down Expand Up @@ -241,11 +242,12 @@ type Mailgun interface {
// MailgunImpl bundles data needed by a large number of methods in order to interact with the Mailgun API.
// Colloquially, we refer to instances of this structure as "clients."
type MailgunImpl struct {
apiBase string
domain string
apiKey string
client *http.Client
baseURL string
apiBase string
domain string
apiKey string
client *http.Client
baseURL string
overrideHeaders map[string]string
}

// NewMailGun creates a new client instance.
Expand Down Expand Up @@ -318,6 +320,15 @@ func (mg *MailgunImpl) SetAPIBase(address string) {
mg.apiBase = address
}

// AddOverrideHeader allows the user to specify additional headers that will be included in the HTTP request
// This is mostly useful for testing the Mailgun API hosted at a different endpoint.
func (mg *MailgunImpl) AddOverrideHeader(k string, v string) {
if mg.overrideHeaders == nil {
mg.overrideHeaders = make(map[string]string)
}
mg.overrideHeaders[k] = v
}

// generateApiUrl renders a URL for an API endpoint using the domain and endpoint name.
func generateApiUrl(m Mailgun, endpoint string) string {
return fmt.Sprintf("%s/%s/%s", m.APIBase(), m.Domain(), endpoint)
Expand Down
4 changes: 4 additions & 0 deletions messages.go
Original file line number Diff line number Diff line change
Expand Up @@ -672,6 +672,10 @@ func (mg *MailgunImpl) Send(ctx context.Context, message *Message) (mes string,
r := newHTTPRequest(generateApiUrlWithDomain(mg, message.specific.endpoint(), message.domain))
r.setClient(mg.Client())
r.setBasicAuth(basicAuthUser, mg.APIKey())
// Override any HTTP headers if provided
for k, v := range mg.overrideHeaders {
r.addHeader(k, v)
}

var response sendMessageResponse
err = postResponseFromJSON(ctx, r, payload, &response)
Expand Down
35 changes: 35 additions & 0 deletions messages_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -536,6 +536,41 @@ func TestResendStored(t *testing.T) {
ensure.DeepEqual(t, id, exampleID)
}

func TestAddOverrideHeader(t *testing.T) {
const (
exampleDomain = "testDomain"
exampleAPIKey = "testAPIKey"
toUser = "[email protected]"
exampleMessage = "Queue. Thank you"
exampleID = "<[email protected]>"
)
srv := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, req *http.Request) {
ensure.DeepEqual(t, req.Method, http.MethodPost)
ensure.DeepEqual(t, req.URL.Path, fmt.Sprintf("/v3/%s/messages", exampleDomain))
ensure.DeepEqual(t, req.Header.Get("CustomHeader"), "custom-value")
ensure.DeepEqual(t, req.Host, "example.com")

rsp := fmt.Sprintf(`{"message":"%s", "id":"%s"}`, exampleMessage, exampleID)
fmt.Fprint(w, rsp)
}))
defer srv.Close()

mg := NewMailgun(exampleDomain, exampleAPIKey)
mg.SetAPIBase(srv.URL + "/v3")
mg.AddOverrideHeader("Host", "example.com")
mg.AddOverrideHeader("CustomHeader", "custom-value")
ctx := context.Background()

m := mg.NewMessage(fromUser, exampleSubject, exampleText, toUser)
m.SetRequireTLS(true)
m.SetSkipVerification(true)

msg, id, err := mg.Send(ctx, m)
ensure.Nil(t, err)
ensure.DeepEqual(t, msg, exampleMessage)
ensure.DeepEqual(t, id, exampleID)
}

func TestSendTLSOptions(t *testing.T) {
const (
exampleDomain = "testDomain"
Expand Down

0 comments on commit 908899b

Please sign in to comment.