diff --git a/v2alpha/cmd/goupnp2srvgen/main.go b/v2alpha/cmd/goupnp2srvgen/main.go index 08aefe9..7ed7b65 100644 --- a/v2alpha/cmd/goupnp2srvgen/main.go +++ b/v2alpha/cmd/goupnp2srvgen/main.go @@ -81,7 +81,7 @@ func run() error { // as well as necessary for extended types. typeMap := types.TypeMap().Clone() typeMap[soapActionInterface] = typedesc.TypeDesc{ - GoType: reflect.TypeOf((*soap.SOAPAction)(nil)).Elem(), + GoType: reflect.TypeOf((*soap.Action)(nil)).Elem(), } for _, m := range manifests.DCPS { diff --git a/v2alpha/soap/client/client.go b/v2alpha/soap/client/client.go index a0958e0..c608188 100644 --- a/v2alpha/soap/client/client.go +++ b/v2alpha/soap/client/client.go @@ -9,6 +9,7 @@ import ( "io" "net/http" + "github.com/huin/goupnp/v2alpha/soap" "github.com/huin/goupnp/v2alpha/soap/envelope" ) @@ -85,19 +86,17 @@ func (c *Client) Do( return ParseResponseAction(resp, actionOut) } -// PerformAction makes a SOAP request, with the given `argsIn` as input -// arguments, and `argsOut` to capture the output arguments into. -// `serviceType` is the SOAP service type URN, `actionName` is the action to -// call. +// PerformAction makes a SOAP request, with the given action. // -// This is a convenience for calling `Client.Do` without creating `*Action` values. +// This is a convenience for calling `Client.Do` without creating +// `*envelope.Action` values. func PerformAction( ctx context.Context, c *Client, - serviceType, actionName string, - argsIn, argsOut any, + action soap.Action, ) error { - actionIn := envelope.NewSendAction(serviceType, actionName, argsIn) - actionOut := &envelope.Action{Args: argsOut} + actionIn := envelope.NewSendAction( + action.ServiceType(), action.ActionName(), action.RefRequest()) + actionOut := &envelope.Action{Args: action.RefResponse()} return c.Do(ctx, actionIn, actionOut) } diff --git a/v2alpha/soap/client/client_test.go b/v2alpha/soap/client/client_test.go index e749c27..29bde61 100644 --- a/v2alpha/soap/client/client_test.go +++ b/v2alpha/soap/client/client_test.go @@ -8,9 +8,25 @@ import ( "testing" "time" + "github.com/huin/goupnp/v2alpha/soap" "github.com/huin/goupnp/v2alpha/soap/envelope" ) +const serviceType = "fake:service:type" +const actionName = "ActionName" + +type Action struct { + req ActionArgs + resp ActionReply +} + +var _ soap.Action = &Action{} + +func (a *Action) ServiceType() string { return serviceType } +func (a *Action) ActionName() string { return actionName } +func (a *Action) RefRequest() any { return &a.req } +func (a *Action) RefResponse() any { return &a.resp } + type ActionArgs struct { Name string } @@ -81,7 +97,7 @@ func TestPerformAction(t *testing.T) { service := &fakeSoapServer{ responses: map[actionKey]*envelope.Action{ - {"/endpointpath", "\"http://example.com/endpointns#Foo\""}: { + {"/endpointpath", fmt.Sprintf("\"%s#%s\"", serviceType, actionName)}: { Args: &ActionReply{Greeting: "Hello, World!"}, }, }, @@ -91,13 +107,14 @@ func TestPerformAction(t *testing.T) { c := New(ts.URL + "/endpointpath") - reply := &ActionReply{} + a := &Action{ + req: ActionArgs{Name: "World"}, + } - if err := PerformAction(ctx, c, "http://example.com/endpointns", "Foo", - &ActionArgs{Name: "World"}, reply); err != nil { + if err := PerformAction(ctx, c, a); err != nil { t.Errorf("got error: %v, want success", err) } else { - if got, want := reply.Greeting, "Hello, World!"; got != want { + if got, want := a.resp.Greeting, "Hello, World!"; got != want { t.Errorf("got %q, want %q", got, want) } } diff --git a/v2alpha/soap/soap.go b/v2alpha/soap/soap.go index b7f2311..4204f8a 100644 --- a/v2alpha/soap/soap.go +++ b/v2alpha/soap/soap.go @@ -1,9 +1,9 @@ // Package soap defines basic types used by SOAP packages. package soap -// SOAPAction defines the interface for the convenience self-describing action request/response +// Action defines the interface for the convenience self-describing action request/response // struct types. -type SOAPAction interface { +type Action interface { // ServiceType returns Service type, e.g. "urn:schemas-upnp-org:service:Foo:1". ServiceType() string // ActionName returns Action name, e.g. "SetBar".