Skip to content

Commit

Permalink
Merge branch 'master' into master
Browse files Browse the repository at this point in the history
  • Loading branch information
nij4t authored Jun 17, 2020
2 parents c833870 + d44b69f commit 837b5be
Show file tree
Hide file tree
Showing 10 changed files with 124 additions and 32 deletions.
3 changes: 2 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,8 @@ func main() {
if err != nil {
log.Fatalf("SoapClient error: %s", err)
}


// Use gosoap.ArrayParams to support fixed position params
params := gosoap.Params{
"sIp": "8.8.8.8",
}
Expand Down
15 changes: 14 additions & 1 deletion encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,20 @@ func (tokens *tokenData) recursiveEncode(hm interface{}) {
for i := 0; i < v.Len(); i++ {
tokens.recursiveEncode(v.Index(i).Interface())
}
case reflect.Array:
if v.Len() == 2 {
label := v.Index(0).Interface()
t := xml.StartElement{
Name: xml.Name{
Space: "",
Local: label.(string),
},
}

tokens.data = append(tokens.data, t)
tokens.recursiveEncode(v.Index(1).Interface())
tokens.data = append(tokens.data, xml.EndElement{Name: t.Name})
}
case reflect.String:
content := xml.CharData(v.String())
tokens.data = append(tokens.data, content)
Expand Down Expand Up @@ -154,7 +168,6 @@ func (tokens *tokenData) endHeader(m string) {
tokens.data = append(tokens.data, r, h)
}

// startToken initiate body of the envelope
func (tokens *tokenData) startBody(m, n string) error {
b := xml.StartElement{
Name: xml.Name{
Expand Down
28 changes: 26 additions & 2 deletions encode_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
)

var (
tests = []struct {
mapParamsTests = []struct {
Params Params
Err string
}{
Expand All @@ -14,15 +14,39 @@ var (
Err: "error expected: xml: start tag with no name",
},
}

arrayParamsTests = []struct {
Params ArrayParams
Err string
}{
{
Params: ArrayParams{{"", ""}},
Err: "error expected: xml: start tag with no name",
},
}
)

func TestClient_MarshalXML(t *testing.T) {
soap, err := SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}

for _, test := range mapParamsTests {
_, err = soap.Call("checkVat", test.Params)
if err == nil {
t.Errorf(test.Err)
}
}
}

func TestClient_MarshalXML2(t *testing.T) {
soap, err := SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl")
if err != nil {
t.Errorf("error not expected: %s", err)
}

for _, test := range tests {
for _, test := range arrayParamsTests {
_, err = soap.Call("checkVat", test.Params)
if err == nil {
t.Errorf(test.Err)
Expand Down
4 changes: 2 additions & 2 deletions go.mod
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
module github.com/tiaguinho/gosoap

require (
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3
golang.org/x/text v0.3.0 // indirect
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553
golang.org/x/text v0.3.2 // indirect
)

go 1.13
7 changes: 7 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
@@ -1,4 +1,11 @@
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3 h1:ulvT7fqt0yHWzpJwI57MezWnYDVpCAYBVuYst/L+fAY=
golang.org/x/net v0.0.0-20190125091013-d26f9f9a57f3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553 h1:efeOvDhwQ29Dj3SdAV/MJf8oukgn+8D8WgaCaRMchF8=
golang.org/x/net v0.0.0-20191209160850-c0dbc17a3553/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0 h1:g61tztE5qeGQ89tm6NTjjM9VPIm088od1l6aSorWRWg=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2 h1:tW2bmiBqwgJj/UpqtC8EpXEZVYOwU0yG4iWbprSVAcs=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
8 changes: 5 additions & 3 deletions request.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,23 +4,25 @@ import (
"fmt"
)

// Soap Request
// Request Soap Request
type Request struct {
Method string
Params Params
Params SoapParams
}

func NewRequest(m string, p Params) *Request {
func NewRequest(m string, p SoapParams) *Request {
return &Request{
Method: m,
Params: p,
}
}

// RequestStruct soap request interface
type RequestStruct interface {
SoapBuildRequest() *Request
}

// NewRequestByStruct create a new request using builder
func NewRequestByStruct(s RequestStruct) (*Request, error) {
if s == nil {
return nil, fmt.Errorf("'s' cannot be 'nil'")
Expand Down
2 changes: 1 addition & 1 deletion response.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import (
"fmt"
)

// Soap Response
// Response Soap Response
type Response struct {
Body []byte
Header []byte
Expand Down
33 changes: 22 additions & 11 deletions soap.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,18 +19,25 @@ import (
type HeaderParams map[string]interface{}

// Params type is used to set the params in soap request
type SoapParams interface {}
type Params map[string]interface{}
type ArrayParams [][2]interface{}

// SoapClient return new *Client to handle the requests with the WSDL
func SoapClient(wsdl string) (*Client, error) {
func SoapClient(wsdl string, httpClient *http.Client) (*Client, error) {
_, err := url.Parse(wsdl)
if err != nil {
return nil, err
}

if httpClient == nil {
httpClient = &http.Client{}
}

c := &Client{
wsdl: wsdl,
HttpClient: &http.Client{},
HTTPClient: httpClient,
AutoAction: false,
}

return c, nil
Expand All @@ -39,7 +46,8 @@ func SoapClient(wsdl string) (*Client, error) {
// Client struct hold all the informations about WSDL,
// request and response of the server
type Client struct {
HttpClient *http.Client
HTTPClient *http.Client
AutoAction bool
URL string
HeaderName string
HeaderParams HeaderParams
Expand All @@ -57,11 +65,11 @@ type Client struct {
}

// Call call's the method m with Params p
func (c *Client) Call(m string, p Params) (res *Response, err error) {
func (c *Client) Call(m string, p SoapParams) (res *Response, err error) {
return c.Do(NewRequest(m, p))
}

// Call call's by struct
// CallByStruct call's by struct
func (c *Client) CallByStruct(s RequestStruct) (res *Response, err error) {
req, err := NewRequestByStruct(s)
if err != nil {
Expand All @@ -82,12 +90,13 @@ func (c *Client) waitAndRefreshDefinitions(d time.Duration) {
}

func (c *Client) initWsdl() {
c.Definitions, c.definitionsErr = getWsdlDefinitions(c.wsdl, c.HttpClient)
c.Definitions, c.definitionsErr = getWsdlDefinitions(c.wsdl, c.HTTPClient)
if c.definitionsErr == nil {
c.URL = strings.TrimSuffix(c.Definitions.TargetNamespace, "/")
}
}

// SetWSDL set WSDL url
func (c *Client) SetWSDL(wsdl string) {
c.onRequest.Wait()
c.onDefinitionsRefresh.Wait()
Expand All @@ -99,7 +108,7 @@ func (c *Client) SetWSDL(wsdl string) {
c.initWsdl()
}

// Process Soap Request
// Do Process Soap Request
func (c *Client) Do(req *Request) (res *Response, err error) {
c.onDefinitionsRefresh.Wait()
c.onRequest.Add(1)
Expand Down Expand Up @@ -131,8 +140,8 @@ func (c *Client) Do(req *Request) (res *Response, err error) {
SoapAction: c.Definitions.GetSoapActionFromWsdlOperation(req.Method),
}

if p.SoapAction == "" {
p.SoapAction = fmt.Sprintf("%s/%s", c.URL, req.Method)
if p.SoapAction == "" && c.AutoAction {
p.SoapAction = fmt.Sprintf("%s/%s/%s", c.URL, c.Definitions.Services[0].Name, req.Method)
}

p.Payload, err = xml.MarshalIndent(p, "", " ")
Expand Down Expand Up @@ -202,17 +211,19 @@ func (p *process) doRequest(url string) ([]byte, error) {
}

func (p *process) httpClient() *http.Client {
if p.Client.HttpClient != nil {
return p.Client.HttpClient
if p.Client.HTTPClient != nil {
return p.Client.HTTPClient
}
return http.DefaultClient
}

// ErrorWithPayload error payload schema
type ErrorWithPayload struct {
error
Payload []byte
}

// GetPayloadFromError returns the payload of a ErrorWithPayload
func GetPayloadFromError(err error) []byte {
if err, ok := err.(ErrorWithPayload); ok {
return err.Payload
Expand Down
45 changes: 35 additions & 10 deletions soap_test.go
Original file line number Diff line number Diff line change
@@ -1,14 +1,16 @@
package gosoap

import (
"crypto/tls"
"net/http"
"testing"
)

var (
scts = []struct {
URL string
Err bool
URL string
Err bool
Client *http.Client
}{
{
URL: "://www.server",
Expand All @@ -22,18 +24,41 @@ var (
URL: "http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl",
Err: true,
},
{
URL: "http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl",
Err: true,
Client: &http.Client{
Transport: &http.Transport{
TLSClientConfig: &tls.Config{
InsecureSkipVerify: true,
},
},
},
},
}
)

func TestSoapClient(t *testing.T) {
for _, sct := range scts {
_, err := SoapClient(sct.URL)
_, err := SoapClient(sct.URL, nil)
if err != nil && sct.Err {
t.Errorf("URL: %s - error: %s", sct.URL, err)
}
}
}

func TestSoapClienWithClient(t *testing.T) {
client, err := SoapClient(scts[3].URL, scts[3].Client)

if client.HTTPClient != scts[3].Client {
t.Errorf("HTTP client is not the same as in initialization: - error: %s", err)
}

if err != nil {
t.Errorf("URL: %s - error: %s", scts[3].URL, err)
}
}

type CheckVatRequest struct {
CountryCode string
VatNumber string
Expand Down Expand Up @@ -77,7 +102,7 @@ var (
)

func TestClient_Call(t *testing.T) {
soap, err := SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl")
soap, err := SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}
Expand Down Expand Up @@ -105,7 +130,7 @@ func TestClient_Call(t *testing.T) {
t.Errorf("error: %+v", rv)
}

soap, err = SoapClient("http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL")
soap, err = SoapClient("http://webservices.oorsprong.org/websamples.countryinfo/CountryInfoService.wso?WSDL", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}
Expand All @@ -121,7 +146,7 @@ func TestClient_Call(t *testing.T) {
t.Errorf("error: %+v", rc)
}

soap, err = SoapClient("http://www.dataaccess.com/webservicesserver/numberconversion.wso?WSDL")
soap, err = SoapClient("http://www.dataaccess.com/webservicesserver/numberconversion.wso?WSDL", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}
Expand All @@ -137,7 +162,7 @@ func TestClient_Call(t *testing.T) {
t.Errorf("error: %+v", rn)
}

soap, err = SoapClient("https://domains.livedns.co.il/API/DomainsAPI.asmx?WSDL")
soap, err = SoapClient("https://domains.livedns.co.il/API/DomainsAPI.asmx?WSDL", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}
Expand Down Expand Up @@ -168,7 +193,7 @@ func TestClient_Call(t *testing.T) {
}

func TestClient_CallByStruct(t *testing.T) {
soap, err := SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl")
soap, err := SoapClient("http://ec.europa.eu/taxation_customs/vies/checkVatService.wsdl", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}
Expand All @@ -190,7 +215,7 @@ func TestClient_CallByStruct(t *testing.T) {
}

func TestClient_Call_NonUtf8(t *testing.T) {
soap, err := SoapClient("https://demo.ilias.de/webservice/soap/server.php?wsdl")
soap, err := SoapClient("https://demo.ilias.de/webservice/soap/server.php?wsdl", nil)
if err != nil {
t.Errorf("error not expected: %s", err)
}
Expand All @@ -204,7 +229,7 @@ func TestClient_Call_NonUtf8(t *testing.T) {
func TestProcess_doRequest(t *testing.T) {
c := &process{
Client: &Client{
HttpClient: &http.Client{},
HTTPClient: &http.Client{},
},
}

Expand Down
Loading

0 comments on commit 837b5be

Please sign in to comment.