Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 42 additions & 16 deletions AddPortMapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ package upnp
import (
// "log"
// "fmt"
"fmt"
"io/ioutil"
"net/http"
"strconv"
Expand All @@ -13,39 +14,59 @@ type AddPortMapping struct {
upnp *Upnp
}

func (this *AddPortMapping) Send(localPort, remotePort, duration int, protocol string, desc string) bool {
func (this *AddPortMapping) Send(localPort, remotePort, duration int, internalClient string, protocol string, desc string) bool {

if !this.upnp.DurationUnsupported {
request := this.buildRequest(localPort, remotePort, duration, protocol, desc)
response, _ := http.DefaultClient.Do(request)
resultBody, _ := ioutil.ReadAll(response.Body)
request := this.buildRequest(localPort, remotePort, duration, internalClient, protocol, desc)

response, err := http.DefaultClient.Do(request)
if err != nil {
fmt.Println("http.DurationUnsupported.Do:", err)
}

result, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Println("ioutil.ReadAll:", err)
}

if response.StatusCode == 200 {
this.resolve(string(resultBody))
this.resolve(string(result))
return true
}
if strings.Contains(string(resultBody), "<errorDescription>OnlyPermanentLeasesSupported</errorDescription>") {

if strings.Contains(string(result), "<errorDescription>OnlyPermanentLeasesSupported</errorDescription>") {
this.upnp.DurationUnsupported = true
}
}

request := this.buildRequest(localPort, remotePort, 0, protocol, desc)
response, _ := http.DefaultClient.Do(request)
resultBody, _ := ioutil.ReadAll(response.Body)
request := this.buildRequest(localPort, remotePort, 0, internalClient, protocol, desc)

response, err := http.DefaultClient.Do(request)
if err != nil {
fmt.Println("http.DetClient.Do:", err)
}

result, err := ioutil.ReadAll(response.Body)
if err != nil {
fmt.Println("ioutil.ReadAll:", err)
}

if response.StatusCode == 200 {
this.resolve(string(resultBody))
this.resolve(string(result))
return true
}

return false
}
func (this *AddPortMapping) buildRequest(localPort, remotePort, duration int, protocol string, desc string) *http.Request {
//请求头
func (this *AddPortMapping) buildRequest(localPort, remotePort, duration int, internalClient string, protocol string, desc string) *http.Request {
// Request header
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", "")
//请求体
// Request body
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/"`}}
Expand All @@ -57,7 +78,7 @@ func (this *AddPortMapping) buildRequest(localPort, remotePort, duration int, pr
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: this.upnp.LocalHost}
childList5 := Node{Name: "NewInternalClient", Content: internalClient}
childList6 := Node{Name: "NewLeaseDuration", Content: strconv.Itoa(duration)}
childList7 := Node{Name: "NewPortMappingDescription", Content: desc}
childList8 := Node{Name: "NewRemoteHost"}
Expand All @@ -74,9 +95,14 @@ func (this *AddPortMapping) buildRequest(localPort, remotePort, duration int, pr
body.AddChild(childOne)
bodyStr := body.BuildXML()

//请求
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
// request
request, err := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
if err != nil {
fmt.Println("http.NewRequest:", err)
return nil
}

request.Header = header
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(bodyStr))))
return request
Expand Down
7 changes: 4 additions & 3 deletions DelPortMapping.go
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ type DelPortMapping struct {
upnp *Upnp
}

// Send sends a request to delete a port mapping
func (this *DelPortMapping) Send(remotePort int, protocol string) bool {
request := this.buildRequest(remotePort, protocol)
response, _ := http.DefaultClient.Do(request)
Expand All @@ -24,15 +25,15 @@ func (this *DelPortMapping) Send(remotePort int, protocol string) bool {
return false
}
func (this *DelPortMapping) buildRequest(remotePort int, protocol string) *http.Request {
//请求头
// Request header
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", "")

//请求体
// Request body
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/"`}}
Expand All @@ -49,7 +50,7 @@ func (this *DelPortMapping) buildRequest(remotePort int, protocol string) *http.
body.AddChild(childOne)
bodyStr := body.BuildXML()

//请求
// Request
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
Expand Down
22 changes: 11 additions & 11 deletions DeviceDesc.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,14 @@ func (this *DeviceDesc) Send() bool {
return false
}
func (this *DeviceDesc) BuildRequest() *http.Request {
//请求头
// Request header
header := http.Header{}
header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
header.Set("User-Agent", "preston")
header.Set("User-Agent", "go upnp")
header.Set("Host", this.upnp.Gateway.Host)
header.Set("Connection", "keep-alive")

//请求
// Request
request, _ := http.NewRequest("GET", "http://"+this.upnp.Gateway.Host+this.upnp.Gateway.DeviceDescUrl, nil)
request.Header = header
// request := http.Request{Method: "GET", Proto: "HTTP/1.1",
Expand All @@ -40,7 +40,7 @@ func (this *DeviceDesc) BuildRequest() *http.Request {
func (this *DeviceDesc) resolve(resultStr string) {
inputReader := strings.NewReader(resultStr)

// 从文件读取,如可以如下
// Read from the file as follows
// content, err := ioutil.ReadFile("studygolang.xml")
// decoder := xml.NewDecoder(bytes.NewBuffer(content))

Expand All @@ -56,22 +56,22 @@ func (this *DeviceDesc) resolve(resultStr string) {
decoder := xml.NewDecoder(inputReader)
for t, err := decoder.Token(); err == nil && !IScontrolURL; t, err = decoder.Token() {
switch token := t.(type) {
// 处理元素开始(标签)
// Processing element start (label)
case xml.StartElement:
if ISUpnpServer {
name := token.Name.Local
lastLabel = name
}

// 处理元素结束(标签)
// Process element end (label)
case xml.EndElement:
// log.Println("结束标记:", token.Name.Local)
// 处理字符数据(这里就是元素的文本)
// log.Println("End tag:", token.Name.Local)
// Processing character data (here is the text of the element)
case xml.CharData:
//得到url后其他标记就不处理了
// Get url after the other tags will not be processed
content := string([]byte(token))

//找到提供端口映射的服务
// Find the service that provides port mapping
if content == this.upnp.Gateway.ServiceType {
ISUpnpServer = true
continue
Expand All @@ -90,7 +90,7 @@ func (this *DeviceDesc) resolve(resultStr string) {
}
}
default:
// ...
// TODO:?
}
}
this.upnp.CtrlUrl = controlURL
Expand Down
6 changes: 3 additions & 3 deletions DeviceStatusInfo.go
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,14 @@ func (this SearchGatewayReq) Send() {
// request := this.BuildRequest()
}
func (this SearchGatewayReq) BuildRequest() *http.Request {
//请求头
// Request header
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#GetStatusInfo"`)
header.Set("Content-Type", "text/xml")
header.Set("Connection", "Close")
header.Set("Content-Length", "")
//请求体
// Request body
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/"`}}
Expand All @@ -36,7 +36,7 @@ func (this SearchGatewayReq) BuildRequest() *http.Request {
childOne.AddChild(childTwo)
body.AddChild(childOne)
bodyStr := body.BuildXML()
//请求
// Request
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
Expand Down
16 changes: 8 additions & 8 deletions ExternalIPAddress.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ func (this *ExternalIPAddress) Send() bool {
return false
}
func (this *ExternalIPAddress) BuildRequest() *http.Request {
//请求头
// Request header
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#GetExternalIPAddress"`)
header.Set("Content-Type", "text/xml")
header.Set("Connection", "Close")
header.Set("Content-Length", "")
//请求体
// Request body
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/"`}}
Expand All @@ -42,37 +42,37 @@ func (this *ExternalIPAddress) BuildRequest() *http.Request {
body.AddChild(childOne)

bodyStr := body.BuildXML()
//请求
// Request
request, _ := http.NewRequest("POST", "http://"+this.upnp.Gateway.Host+this.upnp.CtrlUrl,
strings.NewReader(bodyStr))
request.Header = header
request.Header.Set("Content-Length", strconv.Itoa(len([]byte(body.BuildXML()))))
return request
}

//NewExternalIPAddress
// NewExternalIPAddress
func (this *ExternalIPAddress) resolve(resultStr string) {
inputReader := strings.NewReader(resultStr)
decoder := xml.NewDecoder(inputReader)
ISexternalIP := false
for t, err := decoder.Token(); err == nil; t, err = decoder.Token() {
switch token := t.(type) {
// 处理元素开始(标签)
// Processing element start (label)
case xml.StartElement:
name := token.Name.Local
if name == "NewExternalIPAddress" {
ISexternalIP = true
}
// 处理元素结束(标签)
// Process element end (label)
case xml.EndElement:
// 处理字符数据(这里就是元素的文本)
// Processing character data (here is the text of the element)
case xml.CharData:
if ISexternalIP == true {
this.upnp.GatewayOutsideIP = string([]byte(token))
return
}
default:
// ...
// TODO: wht?
}
}
}
Loading