Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 1 addition & 2 deletions soap/MMAEncoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"mime"
"mime/multipart"
"net/textproto"
Expand Down Expand Up @@ -130,7 +129,7 @@ func (d *mmaDecoder) Decode(v interface{}) error {
if contentID == "" {
return errors.New("Invalid multipart content ID")
}
content, err := ioutil.ReadAll(p)
content, err := io.ReadAll(p)
if err != nil {
return err
}
Expand Down
3 changes: 1 addition & 2 deletions soap/MTOMEncoder.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import (
"errors"
"fmt"
"io"
"io/ioutil"
"math/rand"
"mime"
"mime/multipart"
Expand Down Expand Up @@ -253,7 +252,7 @@ func (d *mtomDecoder) Decode(v interface{}) error {
if contentID == "" {
return errors.New("Invalid multipart content ID")
}
content, err := ioutil.ReadAll(p)
content, err := io.ReadAll(p)
if err != nil {
return err
}
Expand Down
34 changes: 20 additions & 14 deletions soap/soap.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import (
"encoding/xml"
"fmt"
"io"
"io/ioutil"
"net"
"net/http"
"time"
Expand Down Expand Up @@ -375,47 +374,54 @@ func (s *Client) SetHeaders(headers ...interface{}) {

// CallContext performs HTTP POST request with a context
func (s *Client) CallContext(ctx context.Context, soapAction string, request, response interface{}) error {
return s.call(ctx, soapAction, request, response, nil, nil)
return s.call(ctx, soapAction, nil, request, response, nil, nil)
}

// Call performs HTTP POST request.
// Note that if the server returns a status code >= 400, a HTTPError will be returned
func (s *Client) Call(soapAction string, request, response interface{}) error {
return s.call(context.Background(), soapAction, request, response, nil, nil)
return s.call(context.Background(), soapAction, nil, request, response, nil, nil)
}

// CallContextWithAttachmentsAndFaultDetail performs HTTP POST request.
// Note that if SOAP fault is returned, it will be stored in the error.
// On top the attachments array will be filled with attachments returned from the SOAP request.
func (s *Client) CallContextWithAttachmentsAndFaultDetail(ctx context.Context, soapAction string, request,
response interface{}, faultDetail FaultError, attachments *[]MIMEMultipartAttachment) error {
return s.call(ctx, soapAction, request, response, faultDetail, attachments)
return s.call(ctx, soapAction, nil, request, response, faultDetail, attachments)
}

// CallContextWithFault performs HTTP POST request.
// Note that if SOAP fault is returned, it will be stored in the error.
func (s *Client) CallContextWithFaultDetail(ctx context.Context, soapAction string, request, response interface{}, faultDetail FaultError) error {
return s.call(ctx, soapAction, request, response, faultDetail, nil)
return s.call(ctx, soapAction, nil, request, response, faultDetail, nil)
}

// CallWithFaultDetail performs HTTP POST request.
// Note that if SOAP fault is returned, it will be stored in the error.
// the passed in fault detail is expected to implement FaultError interface,
// which allows to condense the detail into a short error message.
func (s *Client) CallWithFaultDetail(soapAction string, request, response interface{}, faultDetail FaultError) error {
return s.call(context.Background(), soapAction, request, response, faultDetail, nil)
return s.call(context.Background(), soapAction, nil, request, response, faultDetail, nil)
}

func (s *Client) call(ctx context.Context, soapAction string, request, response interface{}, faultDetail FaultError,
func (s *Client) CallWithEnvelope(ctx context.Context, soapAction string, envelope, response interface{}, faultDetail FaultError,
retAttachments *[]MIMEMultipartAttachment) error {
// SOAP envelope capable of namespace prefixes
envelope := SOAPEnvelope{
XmlNS: XmlNsSoapEnv,
}
return s.call(ctx, soapAction, envelope, nil, response, faultDetail, retAttachments)
}

envelope.Headers = s.headers
func (s *Client) call(ctx context.Context, soapAction string, envelope, request, response interface{}, faultDetail FaultError,
retAttachments *[]MIMEMultipartAttachment) error {
if envelope == nil {
// SOAP envelope capable of namespace prefixes
soapEnvelope := SOAPEnvelope{
XmlNS: XmlNsSoapEnv,
}
soapEnvelope.Headers = s.headers
soapEnvelope.Body.Content = request
envelope = soapEnvelope
}

envelope.Body.Content = request
buffer := new(bytes.Buffer)
var encoder SOAPEncoder
if s.opts.mtom && s.opts.mma {
Expand Down Expand Up @@ -482,7 +488,7 @@ func (s *Client) call(ctx context.Context, soapAction string, request, response
defer res.Body.Close()

if res.StatusCode >= 400 && res.StatusCode != 500 {
body, _ := ioutil.ReadAll(res.Body)
body, _ := io.ReadAll(res.Body)
return &HTTPError{
StatusCode: res.StatusCode,
ResponseBody: body,
Expand Down
68 changes: 58 additions & 10 deletions soap/soap_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"context"
"encoding/xml"
"fmt"
"io/ioutil"
"io"
"net/http"
"net/http/httptest"
"strings"
Expand Down Expand Up @@ -48,32 +48,80 @@ type AttachmentRequest struct {
ContentID string `xml:"contentID,omitempty"`
}

type TestSoapRequest struct {
XMLName xml.Name
Body Body
}

type Body struct {
XMLName xml.Name
PingRequest Ping `xml:"Ping"`
}

func TestClient_Call(t *testing.T) {
var pingRequest = new(Ping)

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
xml.NewDecoder(r.Body).Decode(pingRequest)
rsp := `<?xml version="1.0" encoding="utf-8"?>
var soapRequest TestSoapRequest
err := xml.NewDecoder(r.Body).Decode(&soapRequest)
assert.NoError(t, err)
rsp := fmt.Sprintf(`<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<PingResponse xmlns="http://example.com/service.xsd">
<PingResult>
<Message>Pong hi</Message>
<Message>Pong %s</Message>
</PingResult>
</PingResponse>
</soap:Body>
</soap:Envelope>`
</soap:Envelope>`, soapRequest.Body.PingRequest.Request.Message)
w.Write([]byte(rsp))
}))
defer ts.Close()

client := NewClient(ts.URL)
req := &Ping{Request: &PingRequest{Message: "Hi"}}
req := &Ping{Request: &PingRequest{Message: "Alex"}}
reply := &PingResponse{}
if err := client.Call("GetData", req, reply); err != nil {
t.Fatalf("couln't call service: %v", err)
}

wantedMsg := "Pong hi"
wantedMsg := "Pong Alex"
if reply.PingResult.Message != wantedMsg {
t.Errorf("got msg %s wanted %s", reply.PingResult.Message, wantedMsg)
}
}

func TestClient_CallEnvelope(t *testing.T) {

ts := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
var soapRequest TestSoapRequest
err := xml.NewDecoder(r.Body).Decode(&soapRequest)
assert.NoError(t, err)
rsp := fmt.Sprintf(`<?xml version="1.0" encoding="utf-8"?>
<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<soap:Body>
<PingResponse xmlns="http://example.com/service.xsd">
<PingResult>
<Message>Pong %s</Message>
</PingResult>
</PingResponse>
</soap:Body>
</soap:Envelope>`, soapRequest.Body.PingRequest.Request.Message)
w.Write([]byte(rsp))
}))
defer ts.Close()

client := NewClient(ts.URL)
req := &Ping{Request: &PingRequest{Message: "Bill"}}
var env TestSoapRequest
env.Body.PingRequest = *req

reply := &PingResponse{}
if err := client.CallWithEnvelope(context.Background(), "GetData", env, reply, nil, nil); err != nil {
t.Fatalf("couln't call service: %v", err)
}

wantedMsg := "Pong Bill"
if reply.PingResult.Message != wantedMsg {
t.Errorf("got msg %s wanted %s", reply.PingResult.Message, wantedMsg)
}
Expand Down Expand Up @@ -138,7 +186,7 @@ func TestClient_Attachments_WithAttachmentResponse(t *testing.T) {
for k, v := range r.Header {
w.Header().Set(k, v[0])
}
bodyBuf, _ := ioutil.ReadAll(r.Body)
bodyBuf, _ := io.ReadAll(r.Body)
_, err := w.Write(bodyBuf)
if err != nil {
panic(err)
Expand Down Expand Up @@ -183,7 +231,7 @@ func TestClient_MTOM(t *testing.T) {
for k, v := range r.Header {
w.Header().Set(k, v[0])
}
bodyBuf, _ := ioutil.ReadAll(r.Body)
bodyBuf, _ := io.ReadAll(r.Body)
w.Write(bodyBuf)
}))
defer ts.Close()
Expand Down