diff --git a/internal/upnp/upnp.go b/internal/upnp/upnp.go index d4b685b51..eb1adb3d0 100644 --- a/internal/upnp/upnp.go +++ b/internal/upnp/upnp.go @@ -448,19 +448,27 @@ func getIGDServices(rootURL string, device upnpDevice, wanDeviceURN string, wanC } func replaceRawPath(u *url.URL, rp string) { - var p, q string - fs := strings.Split(rp, "?") - p = fs[0] - if len(fs) > 1 { - q = fs[1] - } - - if p[0] == '/' { - u.Path = p + asURL, err := url.Parse(rp) + if err != nil { + return + } else if asURL.IsAbs() { + u.Path = asURL.Path + u.RawQuery = asURL.RawQuery } else { - u.Path += p + var p, q string + fs := strings.Split(rp, "?") + p = fs[0] + if len(fs) > 1 { + q = fs[1] + } + + if p[0] == '/' { + u.Path = p + } else { + u.Path += p + } + u.RawQuery = q } - u.RawQuery = q } func soapRequest(url, service, function, message string) ([]byte, error) { diff --git a/internal/upnp/upnp_test.go b/internal/upnp/upnp_test.go index e7fc6b962..db87d8dae 100644 --- a/internal/upnp/upnp_test.go +++ b/internal/upnp/upnp_test.go @@ -17,6 +17,7 @@ package upnp import ( "encoding/xml" + "net/url" "testing" ) @@ -40,3 +41,25 @@ func TestExternalIPParsing(t *testing.T) { t.Error("Parse of SOAP request failed.") } } + +func TestControlURLParsing(t *testing.T) { + rootURL := "http://192.168.243.1:80/igd.xml" + + u, _ := url.Parse(rootURL) + subject := "/upnp?control=WANCommonIFC1" + expected := "http://192.168.243.1:80/upnp?control=WANCommonIFC1" + replaceRawPath(u, subject) + + if u.String() != expected { + t.Error("URL normalization of", subject, "failed; expected", expected, "got", u.String()) + } + + u, _ = url.Parse(rootURL) + subject = "http://192.168.243.1:80/upnp?control=WANCommonIFC1" + expected = "http://192.168.243.1:80/upnp?control=WANCommonIFC1" + replaceRawPath(u, subject) + + if u.String() != expected { + t.Error("URL normalization of", subject, "failed; expected", expected, "got", u.String()) + } +}