Skip to content

Commit

Permalink
Merge pull request #48 from wdreeveii/include_cache_fix2
Browse files Browse the repository at this point in the history
Cleanup external schema fetching
  • Loading branch information
c4milo committed Dec 10, 2015
2 parents f2461da + 11027a6 commit 836f647
Show file tree
Hide file tree
Showing 5 changed files with 105 additions and 53 deletions.
2 changes: 1 addition & 1 deletion Makefile
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
GHACCOUNT := hooklift
NAME := gowsdl
VERSION := v0.1.2
VERSION := v0.2.0

include common.mk

Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
```
3 changes: 2 additions & 1 deletion cmd/gowsdl/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down Expand Up @@ -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)
}
Expand Down
67 changes: 39 additions & 28 deletions gowsdl.go
Original file line number Diff line number Diff line change
Expand Up @@ -178,19 +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
}

_, schemaName := filepath.Split(location.Path)
if g.resolvedXSDExternals[schemaName] {
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)
Expand All @@ -200,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)

if len(newschema.Includes) > 0 &&
maxRecursion > g.currentRecursionLevel {
err = xml.Unmarshal(data, newschema)
if err != nil {
return err
}

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[schemaName] = 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
Expand Down
85 changes: 62 additions & 23 deletions soap_tmpl.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"` + "`" + `
Expand All @@ -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
}
Expand All @@ -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)
Expand Down Expand Up @@ -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
}
`

0 comments on commit 836f647

Please sign in to comment.