aboutsummaryrefslogtreecommitdiffstats
path: root/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go
diff options
context:
space:
mode:
authorFelix Lange <fjl@twurst.com>2015-02-17 20:10:11 +0800
committerFelix Lange <fjl@twurst.com>2015-02-17 20:10:11 +0800
commitf965f41b6e8d177f4f06a8421ee071350813a1ac (patch)
tree1ca45238447aecf08ae50f322a42526a1302e759 /Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go
parent119bea22aaf061d5b3e6a9abee9b1b95655b9fbe (diff)
downloadgo-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.tar
go-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.tar.gz
go-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.tar.bz2
go-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.tar.lz
go-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.tar.xz
go-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.tar.zst
go-tangerine-f965f41b6e8d177f4f06a8421ee071350813a1ac.zip
p2p/nat: switch to github.com/huin/goupnp
My temporary fix was merged upstream.
Diffstat (limited to 'Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go')
-rw-r--r--Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go109
1 files changed, 109 insertions, 0 deletions
diff --git a/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go b/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go
new file mode 100644
index 000000000..120b92444
--- /dev/null
+++ b/Godeps/_workspace/src/github.com/huin/goupnp/goupnp.go
@@ -0,0 +1,109 @@
+// goupnp is an implementation of a client for various UPnP services.
+//
+// For most uses, it is recommended to use the code-generated packages under
+// github.com/huin/goupnp/dcps. Example use is shown at
+// http://godoc.org/github.com/huin/goupnp/example
+//
+// A commonly used client is internetgateway1.WANPPPConnection1:
+// http://godoc.org/github.com/huin/goupnp/dcps/internetgateway1#WANPPPConnection1
+//
+// Currently only a couple of schemas have code generated for them from the
+// UPnP example XML specifications. Not all methods will work on these clients,
+// because the generated stubs contain the full set of specified methods from
+// the XML specifications, and the discovered services will likely support a
+// subset of those methods.
+package goupnp
+
+import (
+ "encoding/xml"
+ "fmt"
+ "net/http"
+ "net/url"
+
+ "github.com/huin/goupnp/httpu"
+ "github.com/huin/goupnp/ssdp"
+)
+
+// ContextError is an error that wraps an error with some context information.
+type ContextError struct {
+ Context string
+ Err error
+}
+
+func (err ContextError) Error() string {
+ return fmt.Sprintf("%s: %v", err.Context, err.Err)
+}
+
+// MaybeRootDevice contains either a RootDevice or an error.
+type MaybeRootDevice struct {
+ Root *RootDevice
+ Err error
+}
+
+// DiscoverDevices attempts to find targets of the given type. This is
+// typically the entry-point for this package. searchTarget is typically a URN
+// in the form "urn:schemas-upnp-org:device:..." or
+// "urn:schemas-upnp-org:service:...". A single error is returned for errors
+// while attempting to send the query. An error or RootDevice is returned for
+// each discovered RootDevice.
+func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
+ httpu, err := httpu.NewHTTPUClient()
+ if err != nil {
+ return nil, err
+ }
+ defer httpu.Close()
+ responses, err := ssdp.SSDPRawSearch(httpu, string(searchTarget), 2, 3)
+ if err != nil {
+ return nil, err
+ }
+
+ results := make([]MaybeRootDevice, len(responses))
+ for i, response := range responses {
+ maybe := &results[i]
+ loc, err := response.Location()
+ if err != nil {
+
+ maybe.Err = ContextError{"unexpected bad location from search", err}
+ continue
+ }
+ locStr := loc.String()
+ root := new(RootDevice)
+ if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil {
+ maybe.Err = ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err}
+ continue
+ }
+ var urlBaseStr string
+ if root.URLBaseStr != "" {
+ urlBaseStr = root.URLBaseStr
+ } else {
+ urlBaseStr = locStr
+ }
+ urlBase, err := url.Parse(urlBaseStr)
+ if err != nil {
+ maybe.Err = ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err}
+ continue
+ }
+ root.SetURLBase(urlBase)
+ maybe.Root = root
+ }
+
+ return results, nil
+}
+
+func requestXml(url string, defaultSpace string, doc interface{}) error {
+ resp, err := http.Get(url)
+ if err != nil {
+ return err
+ }
+ defer resp.Body.Close()
+
+ if resp.StatusCode != 200 {
+ return fmt.Errorf("goupnp: got response status %s from %q",
+ resp.Status, url)
+ }
+
+ decoder := xml.NewDecoder(resp.Body)
+ decoder.DefaultSpace = defaultSpace
+
+ return decoder.Decode(doc)
+}