From 1c8bf34ff159c8519c475835368a1bb1a6b5f903 Mon Sep 17 00:00:00 2001 From: Garth Michel Date: Wed, 14 Jun 2023 11:33:17 -0400 Subject: [PATCH] Adding the ability to set the Envelope Headers --- client.go | 5 ++++ client_test.go | 75 ++++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 80 insertions(+) diff --git a/client.go b/client.go index 0915118..cf1fbb7 100644 --- a/client.go +++ b/client.go @@ -56,6 +56,7 @@ type Client struct { SoapVersion string HTTPClientDoFn func(req *http.Request) (*http.Response, error) LogRemoveHeaderNames []string + EnvelopeHeader *Header } // NewClient constructor. SOAP 1.1 is used by default. Switch to SOAP 1.2 with @@ -96,6 +97,10 @@ func (c *Client) Call(ctx context.Context, soapAction string, request, response Body: Body{Content: request}, } + if c.EnvelopeHeader != nil { + envelope.Header = *c.EnvelopeHeader + } + xmlBytes, err := c.Marshaller.Marshal(envelope) if err != nil { return nil, err diff --git a/client_test.go b/client_test.go index d077231..7529960 100644 --- a/client_test.go +++ b/client_test.go @@ -19,6 +19,11 @@ type FooRequest struct { Foo string } +type FooHeader struct { + XMLName xml.Name `xml:"fooHeader"` + Value string +} + // FooResponse a simple response type FooResponse struct { Bar string @@ -34,6 +39,19 @@ func TestClient_Call(t *testing.T) { `) + wantSOAPBodyWithHeader := []byte(` +
+ + test header + +
+ + + hello world + + +
`) + httpSOAPResponse := []byte(` @@ -80,7 +98,39 @@ func TestClient_Call(t *testing.T) { assert.Exactly(t, 200, httpResp.StatusCode) assert.Exactly(t, FooResponse{Bar: `I love deadlines. I like the whooshing sound they make as they fly by.`}, resp) }) + t.Run("with header success", func(t *testing.T) { + c := NewClient("http://localhorst.ch", &BasicAuth{ + Login: "test", + Password: "test", + }) + c.EnvelopeHeader = &Header{ + Header: &FooHeader{Value: "test header"}, + } + c.UserAgent = "ncc-1701-d" + c.RequestHeaderFn = func(header http.Header) { + header.Set("X-Answer", "42") + } + c.HTTPClientDoFn = clientDoFn(func(r *http.Request) (*http.Response, error) { + haveBody, _ := ioutil.ReadAll(r.Body) + assert.Exactly(t, wantSOAPBodyWithHeader, haveBody) + assert.Exactly(t, "42", r.Header.Get("X-Answer")) + assert.Exactly(t, "ncc-1701-d", r.Header.Get("User-Agent")) + return &http.Response{ + StatusCode: 200, + Body: ioutil.NopCloser(bytes.NewReader(httpSOAPResponse)), + }, nil + }) + req := FooRequest{ + Foo: "hello world", + } + var resp FooResponse + httpResp, err := c.Call(context.Background(), "MySOAPAction", &req, &resp) + require.NoError(t, err) + assert.NotNil(t, httpResp) + assert.Exactly(t, 200, httpResp.StatusCode) + assert.Exactly(t, FooResponse{Bar: `I love deadlines. I like the whooshing sound they make as they fly by.`}, resp) + }) t.Run("no soap body", func(t *testing.T) { c := NewClient("http://localhorst.ch", nil) c.HTTPClientDoFn = clientDoFn(func(r *http.Request) (*http.Response, error) { @@ -124,6 +174,31 @@ func TestClient_Call(t *testing.T) { assert.Exactly(t, 200, httpResp.StatusCode) assert.Exactly(t, FooResponse{Bar: `I love deadlines. I like the whooshing sound they make as they fly by.`}, resp) }) + t.Run("with header success", func(t *testing.T) { + c := NewClient("http://localhorst.ch", nil) + c.EnvelopeHeader = &Header{ + Header: &FooHeader{Value: "test header"}, + } + c.HTTPClientDoFn = clientDoFn(func(r *http.Request) (*http.Response, error) { + buf, mw := createMultiPart(t, httpSOAPResponse) + hdr := http.Header{} + hdr.Add("Content-Type", mw.FormDataContentType()) + return &http.Response{ + Header: hdr, + StatusCode: 200, + Body: ioutil.NopCloser(buf), + }, nil + }) + req := FooRequest{ + Foo: "hello world", + } + var resp FooResponse + httpResp, err := c.Call(context.Background(), "MySOAPAction", &req, &resp) + require.NoError(t, err) + assert.NotNil(t, httpResp) + assert.Exactly(t, 200, httpResp.StatusCode) + assert.Exactly(t, FooResponse{Bar: `I love deadlines. I like the whooshing sound they make as they fly by.`}, resp) + }) t.Run("no soap found", func(t *testing.T) { c := NewClient("http://localhorst.ch", nil) c.HTTPClientDoFn = clientDoFn(func(r *http.Request) (*http.Response, error) {