diff --git a/gosoap/README.md b/gosoap/README.md
new file mode 100644
index 0000000..9273df3
--- /dev/null
+++ b/gosoap/README.md
@@ -0,0 +1 @@
+# gosoap
diff --git a/gosoap/soap-builder.go b/gosoap/soap-builder.go
new file mode 100644
index 0000000..d3ac554
--- /dev/null
+++ b/gosoap/soap-builder.go
@@ -0,0 +1,304 @@
+package gosoap
+
+import (
+ "encoding/xml"
+ "log"
+
+ "github.com/beevik/etree"
+)
+
+//SoapMessage type from string
+type SoapMessage string
+
+// NewEmptySOAP return new SoapMessage
+func NewEmptySOAP() SoapMessage {
+ doc := buildSoapRoot()
+ //doc.IndentTabs()
+
+ res, _ := doc.WriteToString()
+
+ return SoapMessage(res)
+}
+
+//NewSOAP Get a new soap message
+func NewSOAP(headContent []*etree.Element, bodyContent []*etree.Element, namespaces map[string]string) SoapMessage {
+ doc := buildSoapRoot()
+ //doc.IndentTabs()
+
+ res, _ := doc.WriteToString()
+
+ return SoapMessage(res)
+}
+
+func (msg SoapMessage) String() string {
+ return string(msg)
+}
+
+//StringIndent handle indent
+func (msg SoapMessage) StringIndent() string {
+ doc := etree.NewDocument()
+
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+
+ doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ return res
+}
+
+//Body return body from Envelope
+func (msg SoapMessage) Body() string {
+
+ doc := etree.NewDocument()
+
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+ bodyTag := doc.Root().SelectElement("Body").ChildElements()[0]
+ doc.SetRoot(bodyTag)
+ doc.IndentTabs()
+
+ res, _ := doc.WriteToString()
+
+ return res
+}
+
+//AddStringBodyContent for Envelope
+func (msg *SoapMessage) AddStringBodyContent(data string) {
+ doc := etree.NewDocument()
+
+ if err := doc.ReadFromString(data); err != nil {
+ log.Println(err.Error())
+ }
+
+ element := doc.Root()
+
+ doc = etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+ //doc.FindElement("./Envelope/Body").AddChild(element)
+ bodyTag := doc.Root().SelectElement("Body")
+ bodyTag.AddChild(element)
+
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+}
+
+//AddBodyContent for Envelope
+func (msg *SoapMessage) AddBodyContent(element *etree.Element) {
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+ //doc.FindElement("./Envelope/Body").AddChild(element)
+ bodyTag := doc.Root().SelectElement("Body")
+ bodyTag.AddChild(element)
+
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+}
+
+//AddBodyContents for Envelope body
+func (msg *SoapMessage) AddBodyContents(elements []*etree.Element) {
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+
+ bodyTag := doc.Root().SelectElement("Body")
+
+ if len(elements) != 0 {
+ for _, j := range elements {
+ bodyTag.AddChild(j)
+ }
+ }
+
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+}
+
+//AddStringHeaderContent for Envelope body
+func (msg *SoapMessage) AddStringHeaderContent(data string) error {
+ doc := etree.NewDocument()
+
+ if err := doc.ReadFromString(data); err != nil {
+ //log.Println(err.Error())
+ return err
+ }
+
+ element := doc.Root()
+
+ doc = etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ //log.Println(err.Error())
+ return err
+ }
+
+ bodyTag := doc.Root().SelectElement("Header")
+ bodyTag.AddChild(element)
+
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+
+ return nil
+}
+
+//AddHeaderContent for Envelope body
+func (msg *SoapMessage) AddHeaderContent(element *etree.Element) {
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+
+ bodyTag := doc.Root().SelectElement("Header")
+ bodyTag.AddChild(element)
+
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+}
+
+//AddHeaderContents for Envelope body
+func (msg *SoapMessage) AddHeaderContents(elements []*etree.Element) {
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+
+ headerTag := doc.Root().SelectElement("Header")
+
+ if len(elements) != 0 {
+ for _, j := range elements {
+ headerTag.AddChild(j)
+ }
+ }
+
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+}
+
+//AddRootNamespace for Envelope body
+func (msg *SoapMessage) AddRootNamespace(key, value string) {
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+ doc.Root().CreateAttr("xmlns:"+key, value)
+ //doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)
+}
+
+//AddRootNamespaces for Envelope body
+func (msg *SoapMessage) AddRootNamespaces(namespaces map[string]string) {
+ for key, value := range namespaces {
+ msg.AddRootNamespace(key, value)
+ }
+
+ /*
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ //log.Println(err.Error())
+ return err
+ }
+
+ for key, value := range namespaces {
+ doc.Root().CreateAttr("xmlns:" + key, value)
+ }
+
+ doc.IndentTabs()
+ res, _ := doc.WriteToString()
+
+ *msg = SoapMessage(res)*/
+}
+
+func buildSoapRoot() *etree.Document {
+ doc := etree.NewDocument()
+
+ doc.CreateProcInst("xml", `version="1.0" encoding="UTF-8"`)
+
+ env := doc.CreateElement("soap-env:Envelope")
+ env.CreateElement("soap-env:Header")
+ env.CreateElement("soap-env:Body")
+
+ env.CreateAttr("xmlns:soap-env", "http://www.w3.org/2003/05/soap-envelope")
+ env.CreateAttr("xmlns:soap-enc", "http://www.w3.org/2003/05/soap-encoding")
+
+ return doc
+}
+
+//AddWSSecurity Header for soapMessage
+func (msg *SoapMessage) AddWSSecurity(username, password string) {
+ //doc := etree.NewDocument()
+ //if err := doc.ReadFromString(msg.String()); err != nil {
+ // log.Println(err.Error())
+ //}
+ /*
+ Getting an WS-Security struct representation
+ */
+ auth := NewSecurity(username, password)
+
+ /*
+ Adding WS-Security namespaces to root element of SOAP message
+ */
+ //msg.AddRootNamespace("wsse", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext1.0.xsd")
+ //msg.AddRootNamespace("wsu", "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility1.0.xsd")
+
+ soapReq, err := xml.MarshalIndent(auth, "", " ")
+ if err != nil {
+ //log.Printf("error: %v\n", err.Error())
+ panic(err)
+ }
+
+ /*
+ Adding WS-Security struct to SOAP header
+ */
+ msg.AddStringHeaderContent(string(soapReq))
+
+ //doc.IndentTabs()
+ //res, _ := doc.WriteToString()
+ //
+ //*msg = SoapMessage(res)
+}
+
+//AddAction Header handling for soapMessage
+func (msg *SoapMessage) AddAction() {
+
+ doc := etree.NewDocument()
+ if err := doc.ReadFromString(msg.String()); err != nil {
+ log.Println(err.Error())
+ }
+ // opetaionTag := doc.Root().SelectElement("Body")
+
+ // firstElemnt := opetaionTag.Child[0]
+
+ // soapReq, err := xml.MarshalIndent(action, "", " ")
+ // if err != nil {
+ // //log.Printf("error: %v\n", err.Error())
+ // panic(err)
+ // }
+ // /*
+ // Adding WS-Security struct to SOAP header
+ // */
+ // msg.AddStringHeaderContent(string(soapReq))
+
+ // //doc.IndentTabs()
+ // //res, _ := doc.WriteToString()
+ // //
+ // //*msg = SoapMessage(res)
+}
diff --git a/gosoap/ws-action.go b/gosoap/ws-action.go
new file mode 100644
index 0000000..f5a9e3d
--- /dev/null
+++ b/gosoap/ws-action.go
@@ -0,0 +1,43 @@
+package gosoap
+
+import (
+ "encoding/xml"
+)
+
+//Xlmns XML Scheam
+var actionHeaders = map[string]string{
+ "wsnt:Subscribe": "http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest",
+ "ResumeSubscription": "http://docs.oasis-open.org/wsn/bw-2/PausableSubscriptionManager/ResumeSubscriptionRequest",
+ "PauseSubscription": "http://docs.oasis-open.org/wsn/bw-2/PausableSubscriptionManager/PauseSubscriptionRequest",
+ "Unsubscribe": "http://docs.oasis-open.org/wsn/bw-2/PausableSubscriptionManager/UnsubscribeRequest",
+ "RenewRequest": "http://docs.oasis-open.org/wsn/bw-2/PausableSubscriptionManager/RenewRequest",
+}
+
+/*************************
+ Action Type in Header
+*************************/
+
+//Action type
+type Action struct {
+ //XMLName xml.Name `xml:"wsse:Security"`
+ XMLName xml.Name `xml:"wsa:Action"`
+ Operation string `xml:",chardata"`
+}
+
+/*
+
+ http://docs.oasis-open.org/wsn/bw-2/NotificationProducer/SubscribeRequest
+
+*/
+
+//NewAction get a new Action Section
+func NewAction(key, value string) Action {
+
+ /** Generating Nonce sequence **/
+ auth := Action{
+
+ // Created: time.Now().UTC().Format(time.RFC3339Nano),
+ }
+
+ return auth
+}
diff --git a/gosoap/ws-security.go b/gosoap/ws-security.go
new file mode 100644
index 0000000..900ba09
--- /dev/null
+++ b/gosoap/ws-security.go
@@ -0,0 +1,93 @@
+package gosoap
+
+import (
+ "crypto/sha1"
+ "encoding/base64"
+ "encoding/xml"
+ "time"
+
+ "github.com/elgs/gostrgen"
+)
+
+/*************************
+ WS-Security types
+*************************/
+const (
+ passwordType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-username-token-profile-1.0#PasswordDigest"
+ encodingType = "http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-soap-message-security-1.0#Base64Binary"
+)
+
+//Security type :XMLName xml.Name `xml:"http://purl.org/rss/1.0/modules/content/ encoded"`
+type Security struct {
+ //XMLName xml.Name `xml:"wsse:Security"`
+ XMLName xml.Name `xml:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-secext-1.0.xsd Security"`
+ Auth wsAuth
+}
+
+type password struct {
+ //XMLName xml.Name `xml:"wsse:Password"`
+ Type string `xml:"Type,attr"`
+ Password string `xml:",chardata"`
+}
+
+type nonce struct {
+ //XMLName xml.Name `xml:"wsse:Nonce"`
+ Type string `xml:"EncodingType,attr"`
+ Nonce string `xml:",chardata"`
+}
+
+type wsAuth struct {
+ XMLName xml.Name `xml:"UsernameToken"`
+ Username string `xml:"Username"`
+ Password password `xml:"Password"`
+ Nonce nonce `xml:"Nonce"`
+ Created string `xml:"http://docs.oasis-open.org/wss/2004/01/oasis-200401-wss-wssecurity-utility-1.0.xsd Created"`
+}
+
+/*
+
+
+ admin
+ edBuG+qVavQKLoWuGWQdPab4IBE=
+ S7wO1ZFTh0KXv2CR7bd2ZXkLAAAAAA==
+ 2018-04-10T18:04:25.836Z
+
+
+*/
+
+//NewSecurity get a new security
+func NewSecurity(username, passwd string) Security {
+ /** Generating Nonce sequence **/
+ charsToGenerate := 32
+ charSet := gostrgen.Lower | gostrgen.Digit
+
+ nonceSeq, _ := gostrgen.RandGen(charsToGenerate, charSet, "", "")
+ auth := Security{
+ Auth: wsAuth{
+ Username: username,
+ Password: password{
+ Type: passwordType,
+ Password: generateToken(username, nonceSeq, time.Now().UTC(), passwd),
+ },
+ Nonce: nonce{
+ Type: encodingType,
+ Nonce: nonceSeq,
+ },
+ Created: time.Now().UTC().Format(time.RFC3339Nano),
+ },
+ }
+
+ return auth
+}
+
+//Digest = B64ENCODE( SHA1( B64DECODE( Nonce ) + Date + Password ) )
+func generateToken(Username string, Nonce string, Created time.Time, Password string) string {
+
+ sDec, _ := base64.StdEncoding.DecodeString(Nonce)
+
+ hasher := sha1.New()
+ //hasher.Write([]byte((base64.StdEncoding.EncodeToString([]byte(Nonce)) + Created.Format(time.RFC3339) + Password)))
+ hasher.Write([]byte(string(sDec) + Created.Format(time.RFC3339Nano) + Password))
+
+ return base64.StdEncoding.EncodeToString(hasher.Sum(nil))
+}