mapping.go 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163
  1. package upnp
  2. import (
  3. "bytes"
  4. "github.com/pkg/errors"
  5. "net/http"
  6. "strconv"
  7. "strings"
  8. )
  9. //
  10. ////添加一个端口映射
  11. func (n *Upnp)AddPortMapping(localPort, remotePort int, protocol string) (err error) {
  12. defer func(err error) {
  13. if errTemp := recover(); errTemp != nil {
  14. //log.Println("upnp模块报错了", errTemp)
  15. err = errTemp.(error)
  16. }
  17. }(err)
  18. if issuccess := addSend(localPort, remotePort, protocol,n.GatewayHost, n.CtrlUrl,n.LocalHost); issuccess {
  19. return nil
  20. } else {
  21. return errors.New("添加一个端口映射失败")
  22. }
  23. return
  24. }
  25. func addSend(localPort, remotePort int, protocol, host, ctrUrl,localHost string) bool {
  26. request := addRequest(localPort, remotePort, protocol, host, ctrUrl,localHost)
  27. response, _ := http.DefaultClient.Do(request)
  28. defer response.Body.Close()
  29. //resultBody, _ := ioutil.ReadAll(response.Body)
  30. //fmt.Println(string(resultBody))
  31. if response.StatusCode == 200 {
  32. return true
  33. }
  34. return false
  35. }
  36. type Node struct {
  37. Name string
  38. Content string
  39. Attr map[string]string
  40. Child []Node
  41. }
  42. func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl,localHost string) *http.Request {
  43. //请求头
  44. header := http.Header{}
  45. header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
  46. header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"`)
  47. header.Set("Content-Type", "text/xml")
  48. header.Set("Connection", "Close")
  49. header.Set("Content-Length", "")
  50. //请求体
  51. body := Node{Name: "SOAP-ENV:Envelope",
  52. Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
  53. "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
  54. childOne := Node{Name: `SOAP-ENV:Body`}
  55. childTwo := Node{Name: `m:AddPortMapping`,
  56. Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
  57. childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
  58. childList2 := Node{Name: "NewInternalPort", Content: strconv.Itoa(localPort)}
  59. childList3 := Node{Name: "NewProtocol", Content: protocol}
  60. childList4 := Node{Name: "NewEnabled", Content: "1"}
  61. childList5 := Node{Name: "NewInternalClient", Content: localHost}
  62. childList6 := Node{Name: "NewLeaseDuration", Content: "0"}
  63. childList7 := Node{Name: "NewPortMappingDescription", Content: "Oasis"}
  64. childList8 := Node{Name: "NewRemoteHost"}
  65. childTwo.AddChild(childList1)
  66. childTwo.AddChild(childList2)
  67. childTwo.AddChild(childList3)
  68. childTwo.AddChild(childList4)
  69. childTwo.AddChild(childList5)
  70. childTwo.AddChild(childList6)
  71. childTwo.AddChild(childList7)
  72. childTwo.AddChild(childList8)
  73. childOne.AddChild(childTwo)
  74. body.AddChild(childOne)
  75. bodyStr := body.BuildXML()
  76. //请求
  77. request, _ := http.NewRequest("POST", "http://"+gatewayHost+ctlUrl,
  78. strings.NewReader(bodyStr))
  79. request.Header = header
  80. request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
  81. return request
  82. }
  83. func (n *Node) AddChild(node Node) {
  84. n.Child = append(n.Child, node)
  85. }
  86. func (n *Node) BuildXML() string {
  87. buf := bytes.NewBufferString("<")
  88. buf.WriteString(n.Name)
  89. for key, value := range n.Attr {
  90. buf.WriteString(" ")
  91. buf.WriteString(key + "=" + value)
  92. }
  93. buf.WriteString(">" + n.Content)
  94. for _, node := range n.Child {
  95. buf.WriteString(node.BuildXML())
  96. }
  97. buf.WriteString("</" + n.Name + ">")
  98. return buf.String()
  99. }
  100. func (n *Upnp)DelPortMapping(remotePort int, protocol string) bool {
  101. issuccess := delSendSend(remotePort, protocol,n.GatewayHost,n.CtrlUrl)
  102. if issuccess {
  103. //this.MappingPort.delMapping(remotePort, protocol)
  104. //fmt.Println("删除了一个端口映射: remote:", remotePort)
  105. }
  106. return issuccess
  107. }
  108. func delSendSend(remotePort int, protocol,host,ctlUrl string) bool {
  109. delrequest := delbuildRequest(remotePort, protocol,host,ctlUrl)
  110. response, _ := http.DefaultClient.Do(delrequest)
  111. //resultBody, _ := ioutil.ReadAll(response.Body)
  112. defer response.Body.Close()
  113. if response.StatusCode == 200 {
  114. // log.Println(string(resultBody))
  115. return true
  116. }
  117. return false
  118. }
  119. func delbuildRequest(remotePort int, protocol,host,ctlUrl string) *http.Request {
  120. //请求头
  121. header := http.Header{}
  122. header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
  123. header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"`)
  124. header.Set("Content-Type", "text/xml")
  125. header.Set("Connection", "Close")
  126. header.Set("Content-Length", "")
  127. //请求体
  128. body := Node{Name: "SOAP-ENV:Envelope",
  129. Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
  130. "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
  131. childOne := Node{Name: `SOAP-ENV:Body`}
  132. childTwo := Node{Name: `m:DeletePortMapping`,
  133. Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
  134. childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
  135. childList2 := Node{Name: "NewProtocol", Content: protocol}
  136. childList3 := Node{Name: "NewRemoteHost"}
  137. childTwo.AddChild(childList1)
  138. childTwo.AddChild(childList2)
  139. childTwo.AddChild(childList3)
  140. childOne.AddChild(childTwo)
  141. body.AddChild(childOne)
  142. bodyStr := body.BuildXML()
  143. //请求
  144. request, _ := http.NewRequest("POST", "http://"+host+ctlUrl,
  145. strings.NewReader(bodyStr))
  146. request.Header = header
  147. request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
  148. return request
  149. }