Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Added support for obtaining wsdl with BasicAuth. Append namespace for a custom type (nodes method & params). Rename func #46

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
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