123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158 |
- package upnp
- import (
- "bytes"
- "net/http"
- "strconv"
- "strings"
- loger2 "github.com/IceWhaleTech/CasaOS/pkg/utils/loger"
- "github.com/pkg/errors"
- )
- //
- ////添加一个端口映射
- func (n *Upnp) AddPortMapping(localPort, remotePort int, protocol string) (err error) {
- defer func() {
- if errTemp := recover(); errTemp != nil {
- loger2.NewOLoger().Error("upnp模块报错了", errTemp)
- }
- }()
- if isSuccess := addSend(localPort, remotePort, protocol, n.GatewayHost, n.CtrlUrl, n.LocalHost); isSuccess {
- return nil
- } else {
- return errors.New("添加一个端口映射失败")
- }
- }
- func addSend(localPort, remotePort int, protocol, host, ctrUrl, localHost string) bool {
- request := addRequest(localPort, remotePort, protocol, host, ctrUrl, localHost)
- response, _ := http.DefaultClient.Do(request)
- defer response.Body.Close()
- //resultBody, _ := ioutil.ReadAll(response.Body)
- //fmt.Println(string(resultBody))
- return response.StatusCode == 200
- }
- type Node struct {
- Name string
- Content string
- Attr map[string]string
- Child []Node
- }
- func addRequest(localPort, remotePort int, protocol string, gatewayHost, ctlUrl, localHost string) *http.Request {
- //请求头
- header := http.Header{}
- header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
- header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#AddPortMapping"`)
- header.Set("Content-Type", "text/xml")
- header.Set("Connection", "Close")
- header.Set("Content-Length", "")
- //请求体
- body := Node{Name: "SOAP-ENV:Envelope",
- Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
- "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
- childOne := Node{Name: `SOAP-ENV:Body`}
- childTwo := Node{Name: `m:AddPortMapping`,
- Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
- childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
- childList2 := Node{Name: "NewInternalPort", Content: strconv.Itoa(localPort)}
- childList3 := Node{Name: "NewProtocol", Content: protocol}
- childList4 := Node{Name: "NewEnabled", Content: "1"}
- childList5 := Node{Name: "NewInternalClient", Content: localHost}
- childList6 := Node{Name: "NewLeaseDuration", Content: "0"}
- childList7 := Node{Name: "NewPortMappingDescription", Content: "Oasis"}
- childList8 := Node{Name: "NewRemoteHost"}
- childTwo.AddChild(childList1)
- childTwo.AddChild(childList2)
- childTwo.AddChild(childList3)
- childTwo.AddChild(childList4)
- childTwo.AddChild(childList5)
- childTwo.AddChild(childList6)
- childTwo.AddChild(childList7)
- childTwo.AddChild(childList8)
- childOne.AddChild(childTwo)
- body.AddChild(childOne)
- bodyStr := body.BuildXML()
- //请求
- request, _ := http.NewRequest("POST", "http://"+gatewayHost+ctlUrl,
- strings.NewReader(bodyStr))
- request.Header = header
- request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
- return request
- }
- func (n *Node) AddChild(node Node) {
- n.Child = append(n.Child, node)
- }
- func (n *Node) BuildXML() string {
- buf := bytes.NewBufferString("<")
- buf.WriteString(n.Name)
- for key, value := range n.Attr {
- buf.WriteString(" ")
- buf.WriteString(key + "=" + value)
- }
- buf.WriteString(">" + n.Content)
- for _, node := range n.Child {
- buf.WriteString(node.BuildXML())
- }
- buf.WriteString("</" + n.Name + ">")
- return buf.String()
- }
- func (n *Upnp) DelPortMapping(remotePort int, protocol string) bool {
- isSuccess := delSendSend(remotePort, protocol, n.GatewayHost, n.CtrlUrl)
- if isSuccess {
- //this.MappingPort.delMapping(remotePort, protocol)
- //fmt.Println("删除了一个端口映射: remote:", remotePort)
- }
- return isSuccess
- }
- func delSendSend(remotePort int, protocol, host, ctlUrl string) bool {
- delrequest := delbuildRequest(remotePort, protocol, host, ctlUrl)
- response, _ := http.DefaultClient.Do(delrequest)
- //resultBody, _ := ioutil.ReadAll(response.Body)
- defer response.Body.Close()
- return response.StatusCode == 200
- }
- func delbuildRequest(remotePort int, protocol, host, ctlUrl string) *http.Request {
- //请求头
- header := http.Header{}
- header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
- header.Set("SOAPAction", `"urn:schemas-upnp-org:service:WANIPConnection:1#DeletePortMapping"`)
- header.Set("Content-Type", "text/xml")
- header.Set("Connection", "Close")
- header.Set("Content-Length", "")
- //请求体
- body := Node{Name: "SOAP-ENV:Envelope",
- Attr: map[string]string{"xmlns:SOAP-ENV": `"http://schemas.xmlsoap.org/soap/envelope/"`,
- "SOAP-ENV:encodingStyle": `"http://schemas.xmlsoap.org/soap/encoding/"`}}
- childOne := Node{Name: `SOAP-ENV:Body`}
- childTwo := Node{Name: `m:DeletePortMapping`,
- Attr: map[string]string{"xmlns:m": `"urn:schemas-upnp-org:service:WANIPConnection:1"`}}
- childList1 := Node{Name: "NewExternalPort", Content: strconv.Itoa(remotePort)}
- childList2 := Node{Name: "NewProtocol", Content: protocol}
- childList3 := Node{Name: "NewRemoteHost"}
- childTwo.AddChild(childList1)
- childTwo.AddChild(childList2)
- childTwo.AddChild(childList3)
- childOne.AddChild(childTwo)
- body.AddChild(childOne)
- bodyStr := body.BuildXML()
- //请求
- request, _ := http.NewRequest("POST", "http://"+host+ctlUrl,
- strings.NewReader(bodyStr))
- request.Header = header
- request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
- return request
- }
|