Fixes #9 - reacquire previously discovered device by URL.
Some more changes will be required for this to be supported by the dcps packages.
This commit is contained in:
		@@ -2,6 +2,7 @@ package example_test
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
						"net/url"
 | 
				
			||||||
	"os"
 | 
						"os"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/huin/goupnp"
 | 
						"github.com/huin/goupnp"
 | 
				
			||||||
@@ -60,3 +61,33 @@ func DisplayExternalIPResults(clients []GetExternalIPAddresser, errors []error,
 | 
				
			|||||||
		}
 | 
							}
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func Example_ReuseDiscoveredDevice() {
 | 
				
			||||||
 | 
						var allMaybeRootDevices []goupnp.MaybeRootDevice
 | 
				
			||||||
 | 
						for _, urn := range []string{internetgateway1.URN_WANPPPConnection_1, internetgateway1.URN_WANIPConnection_1} {
 | 
				
			||||||
 | 
							maybeRootDevices, err := goupnp.DiscoverDevices(internetgateway1.URN_WANPPPConnection_1)
 | 
				
			||||||
 | 
							if err != nil {
 | 
				
			||||||
 | 
								fmt.Fprintf(os.Stderr, "Could not discover %s devices: %v\n", urn, err)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							allMaybeRootDevices = append(allMaybeRootDevices, maybeRootDevices...)
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						locations := make([]*url.URL, 0, len(allMaybeRootDevices))
 | 
				
			||||||
 | 
						fmt.Fprintf(os.Stderr, "Found %d devices:\n", len(allMaybeRootDevices))
 | 
				
			||||||
 | 
						for _, maybeRootDevice := range allMaybeRootDevices {
 | 
				
			||||||
 | 
							if maybeRootDevice.Err != nil {
 | 
				
			||||||
 | 
								fmt.Fprintln(os.Stderr, "  Failed to probe device at ", maybeRootDevice.Location.String())
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								locations = append(locations, maybeRootDevice.Location)
 | 
				
			||||||
 | 
								fmt.Fprintln(os.Stderr, "  Successfully probed device at ", maybeRootDevice.Location.String())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						fmt.Fprintf(os.Stderr, "Attempt to re-acquire %d devices:\n", len(locations))
 | 
				
			||||||
 | 
						for _, location := range locations {
 | 
				
			||||||
 | 
							if _, err := goupnp.DeviceByURL(location); err != nil {
 | 
				
			||||||
 | 
								fmt.Fprintf(os.Stderr, "  Failed to reacquire device at %s: %v\n", location.String(), err)
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								fmt.Fprintf(os.Stderr, "  Successfully reacquired device at %s\n", location.String())
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
						// Output:
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										34
									
								
								goupnp.go
									
									
									
									
									
								
							
							
						
						
									
										34
									
								
								goupnp.go
									
									
									
									
									
								
							@@ -20,6 +20,7 @@ import (
 | 
				
			|||||||
	"net/http"
 | 
						"net/http"
 | 
				
			||||||
	"net/url"
 | 
						"net/url"
 | 
				
			||||||
	"time"
 | 
						"time"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"golang.org/x/net/html/charset"
 | 
						"golang.org/x/net/html/charset"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/huin/goupnp/httpu"
 | 
						"github.com/huin/goupnp/httpu"
 | 
				
			||||||
@@ -36,9 +37,17 @@ func (err ContextError) Error() string {
 | 
				
			|||||||
	return fmt.Sprintf("%s: %v", err.Context, err.Err)
 | 
						return fmt.Sprintf("%s: %v", err.Context, err.Err)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MaybeRootDevice contains either a RootDevice or an error.
 | 
					// MaybeRootDevice contains either a RootDevice (and URL) or an error.
 | 
				
			||||||
type MaybeRootDevice struct {
 | 
					type MaybeRootDevice struct {
 | 
				
			||||||
 | 
						// Set iff Err == nil.
 | 
				
			||||||
	Root *RootDevice
 | 
						Root *RootDevice
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// The location the device was discovered at. This can be used with
 | 
				
			||||||
 | 
						// DeviceByURL, assuming the device is still present. A location represents
 | 
				
			||||||
 | 
						// the discovery of a device, regardless of if there was an error probing it.
 | 
				
			||||||
 | 
						Location *url.URL
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// Any error encountered probing a discovered device.
 | 
				
			||||||
	Err error
 | 
						Err error
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@@ -67,11 +76,22 @@ func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
 | 
				
			|||||||
			maybe.Err = ContextError{"unexpected bad location from search", err}
 | 
								maybe.Err = ContextError{"unexpected bad location from search", err}
 | 
				
			||||||
			continue
 | 
								continue
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
 | 
							maybe.Location = loc
 | 
				
			||||||
 | 
							if root, err := DeviceByURL(loc); err != nil {
 | 
				
			||||||
 | 
								maybe.Err = err
 | 
				
			||||||
 | 
							} else {
 | 
				
			||||||
 | 
								maybe.Root = root
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						return results, nil
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					func DeviceByURL(loc *url.URL) (*RootDevice, error) {
 | 
				
			||||||
	locStr := loc.String()
 | 
						locStr := loc.String()
 | 
				
			||||||
	root := new(RootDevice)
 | 
						root := new(RootDevice)
 | 
				
			||||||
	if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil {
 | 
						if err := requestXml(locStr, DeviceXMLNamespace, root); err != nil {
 | 
				
			||||||
			maybe.Err = ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err}
 | 
							return nil, ContextError{fmt.Sprintf("error requesting root device details from %q", locStr), err}
 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	var urlBaseStr string
 | 
						var urlBaseStr string
 | 
				
			||||||
	if root.URLBaseStr != "" {
 | 
						if root.URLBaseStr != "" {
 | 
				
			||||||
@@ -81,14 +101,10 @@ func DiscoverDevices(searchTarget string) ([]MaybeRootDevice, error) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	urlBase, err := url.Parse(urlBaseStr)
 | 
						urlBase, err := url.Parse(urlBaseStr)
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
			maybe.Err = ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err}
 | 
							return nil, ContextError{fmt.Sprintf("error parsing location URL %q", locStr), err}
 | 
				
			||||||
			continue
 | 
					 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
	root.SetURLBase(urlBase)
 | 
						root.SetURLBase(urlBase)
 | 
				
			||||||
		maybe.Root = root
 | 
						return root, nil
 | 
				
			||||||
	}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
	return results, nil
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func requestXml(url string, defaultSpace string, doc interface{}) error {
 | 
					func requestXml(url string, defaultSpace string, doc interface{}) error {
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -2,6 +2,7 @@ package goupnp
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
import (
 | 
					import (
 | 
				
			||||||
	"fmt"
 | 
						"fmt"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	"github.com/huin/goupnp/soap"
 | 
						"github.com/huin/goupnp/soap"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user