From 35a66bbaf11f71d9c380b8fbae5d217685d74e79 Mon Sep 17 00:00:00 2001 From: Mike Dillon Date: Tue, 15 Sep 2015 20:47:02 -0700 Subject: [PATCH 1/6] Implement xml.Unmarshaller for SOAPBody Allows unmarshalling to happen in a single pass Fixes #37 --- soap_tmpl.go | 85 ++++++++++++++++++++++++++++++++++++++-------------- 1 file changed, 62 insertions(+), 23 deletions(-) diff --git a/soap_tmpl.go b/soap_tmpl.go index 9a5fdb2..cc9a839 100644 --- a/soap_tmpl.go +++ b/soap_tmpl.go @@ -13,19 +13,26 @@ func dialTimeout(network, addr string) (net.Conn, error) { type SOAPEnvelope struct { XMLName xml.Name ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Envelope"` + "`" + ` - Body SOAPBody ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` + "`" + ` + + Body SOAPBody } type SOAPHeader struct { + XMLName xml.Name ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Header"` + "`" + ` + Header interface{} } type SOAPBody struct { - Fault *SOAPFault ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault,omitempty"` + "`" + ` - Content string ` + "`" + `xml:",innerxml"` + "`" + ` + XMLName xml.Name ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Body"` + "`" + ` + + Fault *SOAPFault ` + "`" + `xml:",omitempty"` + "`" + ` + Content interface{} ` + "`" + `xml:",omitempty"` + "`" + ` } type SOAPFault struct { + XMLName xml.Name ` + "`" + `xml:"http://schemas.xmlsoap.org/soap/envelope/ Fault"` + "`" + ` + Code string ` + "`" + `xml:"faultcode,omitempty"` + "`" + ` String string ` + "`" + `xml:"faultstring,omitempty"` + "`" + ` Actor string ` + "`" + `xml:"faultactor,omitempty"` + "`" + ` @@ -43,6 +50,56 @@ type SOAPClient struct { auth *BasicAuth } +func (b *SOAPBody) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + if b.Content == nil { + return xml.UnmarshalError("Content must be a pointer to a struct") + } + + var ( + token xml.Token + err error + consumed bool + ) + +Loop: + for { + if token, err = d.Token(); err != nil { + return err + } + + if token == nil { + break + } + + switch se := token.(type) { + case xml.StartElement: + if consumed { + return xml.UnmarshalError("Found multiple elements inside SOAP body; not wrapped-document/literal WS-I compliant") + } else if se.Name.Space == "http://schemas.xmlsoap.org/soap/envelope/" && se.Name.Local == "Fault" { + b.Fault = &SOAPFault{} + b.Content = nil + + err = d.DecodeElement(b.Fault, &se) + if err != nil { + return err + } + + consumed = true + } else { + if err = d.DecodeElement(b.Content, &se); err != nil { + return err + } + + consumed = true + } + case xml.EndElement: + break Loop + } + } + + return nil +} + func (f *SOAPFault) Error() string { return f.String } @@ -60,14 +117,7 @@ func (s *SOAPClient) Call(soapAction string, request, response interface{}) erro //Header: SoapHeader{}, } - if request != nil { - reqXml, err := xml.Marshal(request) - if err != nil { - return err - } - - envelope.Body.Content = string(reqXml) - } + envelope.Body.Content = request buffer := new(bytes.Buffer) encoder := xml.NewEncoder(buffer) @@ -118,28 +168,17 @@ func (s *SOAPClient) Call(soapAction string, request, response interface{}) erro log.Println(string(rawbody)) respEnvelope := new(SOAPEnvelope) + respEnvelope.Body = SOAPBody{Content: response} err = xml.Unmarshal(rawbody, respEnvelope) if err != nil { return err } - body := respEnvelope.Body.Content fault := respEnvelope.Body.Fault - if body == "" { - log.Println("empty response body", "envelope", respEnvelope, "body", body) - return nil - } - - log.Println("response", "envelope", respEnvelope, "body", body) if fault != nil { return fault } - err = xml.Unmarshal([]byte(body), response) - if err != nil { - return err - } - return nil } ` From afb3e0bcd76dbd05c53e3fa67d4ebee90d7eeccf Mon Sep 17 00:00:00 2001 From: Camilo Aguilar Date: Wed, 16 Sep 2015 15:19:41 -0400 Subject: [PATCH 2/6] Bumps version --- Makefile | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Makefile b/Makefile index 6622f1e..2eb27b0 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ GHACCOUNT := hooklift NAME := gowsdl -VERSION := v0.1.2 +VERSION := v0.2.0 include common.mk From 170d60f7f63a9cb8df8bfa8d04f85080d7df8ed5 Mon Sep 17 00:00:00 2001 From: Kyle Scott Mcgill Date: Thu, 15 Oct 2015 10:24:00 +1300 Subject: [PATCH 3/6] added flag for insecure tls certs --- cmd/gowsdl/main.go | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/cmd/gowsdl/main.go b/cmd/gowsdl/main.go index b3e167d..7d5fd1f 100644 --- a/cmd/gowsdl/main.go +++ b/cmd/gowsdl/main.go @@ -66,6 +66,7 @@ var Name string var vers = flag.Bool("v", false, "Shows gowsdl version") var pkg = flag.String("p", "myservice", "Package under which code will be generated") var outFile = flag.String("o", "myservice.go", "File where the generated code will be saved") +var insecure = flag.Bool("i", false, "Skips TLS Verification") func init() { log.SetFlags(0) @@ -99,7 +100,7 @@ func main() { } // load wsdl - gowsdl, err := gen.NewGoWSDL(wsdlPath, *pkg, false) + gowsdl, err := gen.NewGoWSDL(wsdlPath, *pkg, *insecure) if err != nil { log.Fatalln(err) } From 377770b41e9422bfadc652d9c5d5bb29822c4d0f Mon Sep 17 00:00:00 2001 From: Kyle Scott Mcgill Date: Fri, 16 Oct 2015 09:32:55 +1300 Subject: [PATCH 4/6] Update Readme to reflect the TLS Skip Verification command line option --- README.md | 1 + 1 file changed, 1 insertion(+) diff --git a/README.md b/README.md index ef57536..7ef9445 100644 --- a/README.md +++ b/README.md @@ -31,5 +31,6 @@ Usage: gowsdl [options] myservice.wsdl File where the generated code will be saved (default "myservice.go") -p string Package under which code will be generated (default "myservice") + -i Skips TLS Verification -v Shows gowsdl version ``` From 623ec3fd0971ddbb307e29643cccc1d34772864b Mon Sep 17 00:00:00 2001 From: Whitham Reeve Date: Mon, 23 Nov 2015 17:57:36 -0900 Subject: [PATCH 5/6] Fix caching of xsd includes to handle the common case of endpoint?xsd=file1.xsd endpoint?xsd=file2.xsd --- gowsdl.go | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/gowsdl.go b/gowsdl.go index 858ace9..6451189 100644 --- a/gowsdl.go +++ b/gowsdl.go @@ -185,8 +185,7 @@ func (g *GoWSDL) resolveXSDExternals(schema *XSDSchema, url *url.URL) error { return err } - _, schemaName := filepath.Split(location.Path) - if g.resolvedXSDExternals[schemaName] { + if g.resolvedXSDExternals[incl.SchemaLocation] { continue } @@ -222,7 +221,7 @@ func (g *GoWSDL) resolveXSDExternals(schema *XSDSchema, url *url.URL) error { if g.resolvedXSDExternals == nil { g.resolvedXSDExternals = make(map[string]bool, maxRecursion) } - g.resolvedXSDExternals[schemaName] = true + g.resolvedXSDExternals[incl.SchemaLocation] = true } return nil From 11027a61236bb6be81cfac6a279d05ef9b36e550 Mon Sep 17 00:00:00 2001 From: Whitham Reeve Date: Mon, 23 Nov 2015 20:18:34 -0900 Subject: [PATCH 6/6] Fix include caching, cleanup file vs external dependancy fetching. --- gowsdl.go | 66 ++++++++++++++++++++++++++++++++----------------------- 1 file changed, 39 insertions(+), 27 deletions(-) diff --git a/gowsdl.go b/gowsdl.go index fead8ca..8cad47f 100644 --- a/gowsdl.go +++ b/gowsdl.go @@ -178,18 +178,19 @@ func (g *GoWSDL) unmarshal() error { return nil } -func (g *GoWSDL) resolveXSDExternals(schema *XSDSchema, url *url.URL) error { - for _, incl := range schema.Includes { - location, err := url.Parse(incl.SchemaLocation) +func (g *GoWSDL) getSchema(schemaLocation string, url *url.URL) error { + _, schemaFile := filepath.Split(schemaLocation) + + data, err := ioutil.ReadFile(schemaFile) + if err != nil { + + location, err := url.Parse(schemaLocation) if err != nil { return err } - if g.resolvedXSDExternals[incl.SchemaLocation] { - continue - } + schemaLocation = location.String() - schemaLocation := location.String() if !location.IsAbs() { if !url.IsAbs() { return fmt.Errorf("Unable to resolve external schema %s through WSDL URL %s", schemaLocation, url) @@ -199,55 +200,66 @@ func (g *GoWSDL) resolveXSDExternals(schema *XSDSchema, url *url.URL) error { log.Println("Downloading external schema", "location", schemaLocation) - data, err := downloadFile(schemaLocation, g.ignoreTLS) - newschema := new(XSDSchema) - - err = xml.Unmarshal(data, newschema) + data, err = downloadFile(schemaLocation, g.ignoreTLS) if err != nil { return err } + } + newschema := new(XSDSchema) + + err = xml.Unmarshal(data, newschema) + if err != nil { + return err + } - if len(newschema.Includes) > 0 && - maxRecursion > g.currentRecursionLevel { + if len(newschema.Includes) > 0 || len(newschema.Imports) > 0 { + if maxRecursion > g.currentRecursionLevel { g.currentRecursionLevel++ //log.Printf("Entering recursion %d\n", g.currentRecursionLevel) g.resolveXSDExternals(newschema, url) } + } - g.wsdl.Types.Schemas = append(g.wsdl.Types.Schemas, newschema) + g.wsdl.Types.Schemas = append(g.wsdl.Types.Schemas, newschema) + return nil +} + +func (g *GoWSDL) resolveXSDExternals(schema *XSDSchema, url *url.URL) error { + if len(schema.Includes) > 0 || len(schema.Imports) > 0 { if g.resolvedXSDExternals == nil { g.resolvedXSDExternals = make(map[string]bool, maxRecursion) } - g.resolvedXSDExternals[incl.SchemaLocation] = true } - for _, incl := range schema.Imports { - location, err := url.Parse(incl.SchemaLocation) + var err error + for _, incl := range schema.Includes { + if g.resolvedXSDExternals[incl.SchemaLocation] { + continue + } + + err = g.getSchema(incl.SchemaLocation, url) if err != nil { return err } - _, schemaName := filepath.Split(location.Path) - if g.resolvedXSDExternals[schemaName] { + g.resolvedXSDExternals[incl.SchemaLocation] = true + } + + for _, imp := range schema.Imports { + if g.resolvedXSDExternals[imp.SchemaLocation] { continue } - data, err := ioutil.ReadFile(schemaName) - newschema := new(XSDSchema) - err = xml.Unmarshal(data, newschema) + err = g.getSchema(imp.SchemaLocation, url) if err != nil { return err } - g.wsdl.Types.Schemas = append(g.wsdl.Types.Schemas, newschema) + g.resolvedXSDExternals[imp.SchemaLocation] = true - if g.resolvedXSDExternals == nil { - g.resolvedXSDExternals = make(map[string]bool, maxRecursion) - } - g.resolvedXSDExternals[schemaName] = true } return nil