Skip to content
Open
Show file tree
Hide file tree
Changes from 3 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
2 changes: 0 additions & 2 deletions .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,8 +6,6 @@ go:
before_install:
- go get -t -v ./...

script:
- go test -race -coverprofile=coverage.txt -covermode=atomic

after_success:
- bash <(curl -s https://codecov.io/bash)
18 changes: 10 additions & 8 deletions encode.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,19 +17,20 @@ func (c process) MarshalXML(e *xml.Encoder, _ xml.StartElement) error {

tokens.startEnvelope()
if len(c.Client.HeaderParams) > 0 {
tokens.startHeader(c.Client.HeaderName, c.Client.Definitions.Types[0].XsdSchema[0].TargetNamespace)
tokens.startHeader(c.Client.HeaderName, c.Client.Definitions.Types[0].XsdSchema[0].TargetNamespace) // ToDo taking from the first line is not correct

tokens.recursiveEncode(c.Client.HeaderParams)
tokens.recursiveEncodePaqram(c.Client.HeaderParams, "")

tokens.endHeader(c.Client.HeaderName)
}

err := tokens.startBody(c.Request.Method, c.Client.Definitions.Types[0].XsdSchema[0].TargetNamespace)
// append namespace for a custom type
err := tokens.startBody(c.Request.Method, c.Client.Definitions.Types[0].getWsdlSchema(c.Request.Method).TargetNamespace)
if err != nil {
return err
}

tokens.recursiveEncode(c.Request.Params)
tokens.recursiveEncodePaqram(c.Request.Params, c.Client.Definitions.TargetNamespace)

//end envelope
tokens.endBody(c.Request.Method)
Expand All @@ -49,26 +50,26 @@ type tokenData struct {
data []xml.Token
}

func (tokens *tokenData) recursiveEncode(hm interface{}) {
func (tokens *tokenData) recursiveEncodePaqram(hm interface{}, namespace string) {
v := reflect.ValueOf(hm)

switch v.Kind() {
case reflect.Map:
for _, key := range v.MapKeys() {
t := xml.StartElement{
Name: xml.Name{
Space: "",
Space: namespace,
Local: key.String(),
},
}

tokens.data = append(tokens.data, t)
tokens.recursiveEncode(v.MapIndex(key).Interface())
tokens.recursiveEncodePaqram(v.MapIndex(key).Interface(), namespace)
tokens.data = append(tokens.data, xml.EndElement{Name: t.Name})
}
case reflect.Slice:
for i := 0; i < v.Len(); i++ {
tokens.recursiveEncode(v.Index(i).Interface())
tokens.recursiveEncodePaqram(v.Index(i).Interface(), namespace)
}
case reflect.String:
content := xml.CharData(v.String())
Expand All @@ -83,6 +84,7 @@ func (tokens *tokenData) startEnvelope() {
Local: "soap:Envelope",
},
Attr: []xml.Attr{
// Default
{Name: xml.Name{Space: "", Local: "xmlns:xsi"}, Value: "http://www.w3.org/2001/XMLSchema-instance"},
{Name: xml.Name{Space: "", Local: "xmlns:xsd"}, Value: "http://www.w3.org/2001/XMLSchema"},
{Name: xml.Name{Space: "", Local: "xmlns:soap"}, Value: "http://schemas.xmlsoap.org/soap/envelope/"},
Expand Down
2 changes: 1 addition & 1 deletion soap.go
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (c *Client) waitAndRefreshDefinitions(d time.Duration) {
}

func (c *Client) initWsdl() {
c.Definitions, c.definitionsErr = getWsdlDefinitions(c.wsdl)
c.Definitions, c.definitionsErr = getWsdlDefinitions(c.wsdl, c.Username, c.Password)
if c.definitionsErr == nil {
c.URL = strings.TrimSuffix(c.Definitions.TargetNamespace, "/")
}
Expand Down
47 changes: 41 additions & 6 deletions wsdl.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,14 @@ package gosoap

import (
"encoding/xml"
"golang.org/x/net/html/charset"
"fmt"
"io"
"net/http"
"net/url"
"os"
"strings"

"golang.org/x/net/html/charset"
)

type wsdlDefinitions struct {
Expand Down Expand Up @@ -155,28 +158,48 @@ type xsdMaxInclusive struct {
Value string `xml:"value,attr"`
}

func getWsdlBody(u string) (reader io.ReadCloser, err error) {
func DownloadWSDL(URL, login, pass string) (*http.Response, error) {
req, err := http.NewRequest(http.MethodGet, URL, nil)
if err != nil {
return nil, err
}
if login != "" {
req.SetBasicAuth(login, pass)
}

httpClient := new(http.Client)
resp, err := httpClient.Do(req)
if err != nil {
return nil, err
}
if resp.StatusCode != http.StatusOK {
return nil, fmt.Errorf("status code %v", resp.StatusCode)
}
return resp, nil
}

func getWsdlBody(u, username, password string) (reader io.ReadCloser, err error) {
parse, err := url.Parse(u)
if err != nil {
return nil, err
}
if parse.Scheme == "file" {
outFile, err := os.Open(parse.Path)
outFile, err := os.Open(strings.Replace(u, fmt.Sprintf("%s:\\\\", parse.Scheme), "", -1))
if err != nil {
return nil, err
}
return outFile, nil
}
r, err := http.Get(u)
r, err := DownloadWSDL(u, username, password) // usually to download wsdl you need authorization
if err != nil {
return nil, err
}
return r.Body, nil
}

// getWsdlDefinitions sent request to the wsdl url and set definitions on struct
func getWsdlDefinitions(u string) (wsdl *wsdlDefinitions, err error) {
reader, err := getWsdlBody(u)
func getWsdlDefinitions(u, username, password string) (wsdl *wsdlDefinitions, err error) {
reader, err := getWsdlBody(u, username, password)
if err != nil {
return nil, err
}
Expand Down Expand Up @@ -212,3 +235,15 @@ type Fault struct {
Description string `xml:"faultstring"`
Detail string `xml:"detail"`
}

func (t wsdlTypes) getWsdlSchema(nodeName string) (result *xsdSchema) {
for _, schema := range t.XsdSchema {
for _, element := range schema.Elements {
if element.Name == nodeName {
return schema
}
}
}

return &xsdSchema{}
}
7 changes: 4 additions & 3 deletions wsdl_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package gosoap
import (
"fmt"
"os"
"path"
"testing"
)

Expand All @@ -24,13 +25,13 @@ func Test_getWsdlBody(t *testing.T) {
},
{
args: args{
u: fmt.Sprintf("%s/%s", dir, "testdata/ipservice.wsdl"),
u: path.Join(dir, "testdata", "ipservice.wsdl"),
},
wantErr: true,
},
{
args: args{
u: fmt.Sprintf("file://%s/%s", dir, "testdata/ipservice.wsdl"),
u: fmt.Sprintf("file:\\\\%s\\%s", dir, "testdata\\ipservice.wsdl"), // for windows
},
wantErr: false,
},
Expand All @@ -49,7 +50,7 @@ func Test_getWsdlBody(t *testing.T) {
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
_, err := getWsdlBody(tt.args.u)
_, err := getWsdlBody(tt.args.u, "", "")
if (err != nil) != tt.wantErr {
t.Errorf("getwsdlBody() error = %v, wantErr %v", err, tt.wantErr)
return
Expand Down