diff --git a/.gitignore b/.gitignore index e708b27a..9eed51cd 100644 --- a/.gitignore +++ b/.gitignore @@ -3,3 +3,4 @@ myservice build .DS_Store dist +release diff --git a/README.md b/README.md index 84004f2d..ff14bd2a 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,11 @@ # WSDL to Go +## FACTRY fork +This Factry fork fixes a couple of issues with the original gowsdl: +* enables proper autentication with Navision - using ntlsm +* custom datetime handling, to properly parse Dates (yyyy-mm-dd) + +## Original readme + [![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hooklift/gowsdl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/hooklift/gowsdl?status.svg)](https://godoc.org/github.com/hooklift/gowsdl) diff --git a/cmd/gowsdl/main.go b/cmd/gowsdl/main.go index ba725b43..7a577995 100644 --- a/cmd/gowsdl/main.go +++ b/cmd/gowsdl/main.go @@ -54,7 +54,7 @@ import ( "log" "os" - gen "github.com/hooklift/gowsdl" + gen "github.com/factrylabs/gowsdl" ) // Version is initialized in compilation time by go build. diff --git a/example/example.go b/example/example.go index c65cef17..eb3f39f2 100644 --- a/example/example.go +++ b/example/example.go @@ -5,8 +5,8 @@ import ( "log" "time" - "github.com/hooklift/gowsdl/example/gen" - "github.com/hooklift/gowsdl/soap" + "github.com/factrylabs/gowsdl/example/gen" + "github.com/factrylabs/gowsdl/soap" ) func ExampleBasicUsage() { diff --git a/example/gen/gen.go b/example/gen/gen.go index 3d78b86b..81b4222c 100644 --- a/example/gen/gen.go +++ b/example/gen/gen.go @@ -4,7 +4,7 @@ import ( "encoding/xml" "time" - "github.com/hooklift/gowsdl/soap" + "github.com/factrylabs/gowsdl/soap" ) // against "unused imports" diff --git a/go.mod b/go.mod deleted file mode 100644 index c4fc14c2..00000000 --- a/go.mod +++ /dev/null @@ -1 +0,0 @@ -module github.com/hooklift/gowsdl diff --git a/go.sum b/go.sum new file mode 100644 index 00000000..25617a03 --- /dev/null +++ b/go.sum @@ -0,0 +1,9 @@ +github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4 h1:pSm8mp0T2OH2CPmPDPtwHPr3VAQaOwVF/JbllOPP4xA= +github.com/Azure/go-ntlmssp v0.0.0-20180810175552-4a21cbd618b4/go.mod h1:chxPXzSsl7ZWRAuOIE23GDNzjWuZquvFlgA8xmpunjU= +golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472 h1:Gv7RPwsi3eZ2Fgewe3CBsuOebPwO27PoXzRpJPsvSSM= +golang.org/x/crypto v0.0.0-20190829043050-9756ffdc2472/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI= +golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= +golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ= diff --git a/gowsdl.go b/gowsdl.go index e549183e..f9077e81 100644 --- a/gowsdl.go +++ b/gowsdl.go @@ -386,9 +386,9 @@ var xsd2GoTypes = map[string]string{ "byte": "int8", "long": "int64", "boolean": "bool", - "datetime": "time.Time", - "date": "time.Time", - "time": "time.Time", + "datetime": "*CustomTimestamp", + "date": "*CustomTimestamp", + "time": "*CustomTimestamp", "base64binary": "[]byte", "hexbinary": "[]byte", "unsignedint": "uint32", diff --git a/header_tmpl.go b/header_tmpl.go index 21c703f1..289cb787 100644 --- a/header_tmpl.go +++ b/header_tmpl.go @@ -11,8 +11,9 @@ package {{.}} import ( "encoding/xml" + "fmt" "time" - "github.com/hooklift/gowsdl/soap" + "github.com/factrylabs/gowsdl/soap" {{/*range .Imports*/}} {{/*.*/}} @@ -22,4 +23,49 @@ import ( // against "unused imports" var _ time.Time var _ xml.Name + + +// YB : Added custom timestamp to parse all kinds of different datetime formats +type CustomTimestamp struct { + time.Time +} + +// MarshalXML will parse the time.Time back to a string format Navision understands +func (c *CustomTimestamp) MarshalXML(e *xml.Encoder, start xml.StartElement) error { + return e.EncodeElement(c.Time.Format("2006-01-02T15:04:05Z"), start) +} + +// UnmarshalXML will parse the time.Time in different ways - as Navision uses them +func (c *CustomTimestamp) UnmarshalXML(d *xml.Decoder, start xml.StartElement) error { + var v string + d.DecodeElement(&v, &start) + + parse, err := time.Parse("2006-01-02T15:04:05Z07:00", v) + if err == nil { + *c = CustomTimestamp{parse} + return nil + } + + parse, err = time.Parse("2006-01-02T15:04:05", v) + if err == nil { + *c = CustomTimestamp{parse} + return nil + } + + parse, err = time.Parse("2006-01-02", v) + if err == nil { + *c = CustomTimestamp{parse} + return nil + } + + parse, err = time.Parse("15:04:05", v) + if err == nil { + *c = CustomTimestamp{parse} + return nil + } + + // if we reach here: an error occurred.. + return fmt.Errorf("Could not parse datetime for %v", v) + +} ` diff --git a/package.json b/package.json new file mode 100644 index 00000000..3ce9badc --- /dev/null +++ b/package.json @@ -0,0 +1,23 @@ +{ + "name": "gowsdl", + "version": "0.4.0", + "description": "[![Gitter](https://badges.gitter.im/Join%20Chat.svg)](https://gitter.im/hooklift/gowsdl?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge) [![GoDoc](https://godoc.org/github.com/hooklift/gowsdl?status.svg)](https://godoc.org/github.com/hooklift/gowsdl) [![Build Status](https://travis-ci.org/hooklift/gowsdl.svg?branch=master)](https://travis-ci.org/hooklift/gowsdl)", + "main": "index.js", + "directories": { + "example": "example" + }, + "scripts": { + "test": "echo \"Error: no test specified\" && exit 1", + "pkg:linux": "env GOOS=linux GOARCH=amd64 go build -o ./release/$npm_package_name\\_v$npm_package_version\\_linux-x64 ./cmd/gowsdl/*.go" + }, + "repository": { + "type": "git", + "url": "git+https://github.com/factrylabs/gowsdl.git" + }, + "author": "", + "license": "ISC", + "bugs": { + "url": "https://github.com/factrylabs/gowsdl/issues" + }, + "homepage": "https://github.com/factrylabs/gowsdl#readme" +} diff --git a/soap/soap.go b/soap/soap.go index 58170441..6e0decf5 100644 --- a/soap/soap.go +++ b/soap/soap.go @@ -5,9 +5,10 @@ import ( "crypto/tls" "encoding/xml" "io/ioutil" - "net" "net/http" "time" + + ntlmssp "github.com/Azure/go-ntlmssp" ) type SOAPEnvelope struct { @@ -218,9 +219,10 @@ func WithHTTPHeaders(headers map[string]string) Option { // Client is soap client type Client struct { - url string - opts *options - headers []interface{} + url string + opts *options + headers []interface{} + httpClient HTTPClient } // HTTPClient is a client which can make HTTP requests @@ -235,9 +237,16 @@ func NewClient(url string, opt ...Option) *Client { for _, o := range opt { o(&opts) } + client := &http.Client{ + Timeout: time.Minute * 2, + Transport: ntlmssp.Negotiator{ + RoundTripper: &http.Transport{}, + }, + } return &Client{ - url: url, - opts: &opts, + url: url, + opts: &opts, + httpClient: client, } } @@ -283,21 +292,10 @@ func (s *Client) Call(soapAction string, request, response interface{}) error { req.Header.Set(k, v) } } - req.Close = true - - client := s.opts.client - if client == nil { - tr := &http.Transport{ - TLSClientConfig: s.opts.tlsCfg, - Dial: func(network, addr string) (net.Conn, error) { - return net.DialTimeout(network, addr, s.opts.timeout) - }, - TLSHandshakeTimeout: s.opts.tlshshaketimeout, - } - client = &http.Client{Timeout: s.opts.contimeout, Transport: tr} - } - res, err := client.Do(req) + defer req.Body.Close() + + res, err := s.httpClient.Do(req) if err != nil { return err }