device.go 2.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889
  1. package upnp
  2. import (
  3. "encoding/xml"
  4. "io/ioutil"
  5. "net/http"
  6. "strings"
  7. )
  8. func GetCtrlUrl(host, device string) string {
  9. request := ctrlUrlRequest(host, device)
  10. response, _ := http.DefaultClient.Do(request)
  11. resultBody, _ := ioutil.ReadAll(response.Body)
  12. defer response.Body.Close()
  13. if response.StatusCode == 200 {
  14. return resolve(string(resultBody))
  15. }
  16. return ""
  17. }
  18. func ctrlUrlRequest(host string, deviceDescUrl string) *http.Request {
  19. //请求头
  20. header := http.Header{}
  21. header.Set("Accept", "text/html, image/gif, image/jpeg, *; q=.2, */*; q=.2")
  22. header.Set("User-Agent", "preston")
  23. header.Set("Host", host)
  24. header.Set("Connection", "keep-alive")
  25. request, _ := http.NewRequest("GET", "http://"+host+deviceDescUrl, nil)
  26. request.Header = header
  27. return request
  28. }
  29. func resolve(resultStr string) string {
  30. inputReader := strings.NewReader(resultStr)
  31. // 从文件读取,如可以如下:
  32. // content, err := ioutil.ReadFile("studygolang.xml")
  33. // decoder := xml.NewDecoder(bytes.NewBuffer(content))
  34. lastLabel := ""
  35. ISUpnpServer := false
  36. IScontrolURL := false
  37. var controlURL string //`controlURL`
  38. // var eventSubURL string //`eventSubURL`
  39. // var SCPDURL string //`SCPDURL`
  40. decoder := xml.NewDecoder(inputReader)
  41. for t, err := decoder.Token(); err == nil && !IScontrolURL; t, err = decoder.Token() {
  42. switch token := t.(type) {
  43. // 处理元素开始(标签)
  44. case xml.StartElement:
  45. if ISUpnpServer {
  46. name := token.Name.Local
  47. lastLabel = name
  48. }
  49. // 处理元素结束(标签)
  50. case xml.EndElement:
  51. // log.Println("结束标记:", token.Name.Local)
  52. // 处理字符数据(这里就是元素的文本)
  53. case xml.CharData:
  54. //得到url后其他标记就不处理了
  55. content := string([]byte(token))
  56. //找到提供端口映射的服务
  57. if content == "urn:schemas-upnp-org:service:WANIPConnection:1" {
  58. ISUpnpServer = true
  59. continue
  60. }
  61. if ISUpnpServer {
  62. switch lastLabel {
  63. case "controlURL":
  64. controlURL = content
  65. IScontrolURL = true
  66. case "eventSubURL":
  67. // eventSubURL = content
  68. case "SCPDURL":
  69. // SCPDURL = content
  70. }
  71. }
  72. default:
  73. // ...
  74. }
  75. }
  76. return controlURL
  77. }