Integrate soap.Action type with soap/client.

This commit is contained in:
John Beisley 2022-06-10 17:54:04 +01:00
parent be592a92bd
commit 656e810e54
4 changed files with 33 additions and 17 deletions

View File

@ -81,7 +81,7 @@ func run() error {
// as well as necessary for extended types. // as well as necessary for extended types.
typeMap := types.TypeMap().Clone() typeMap := types.TypeMap().Clone()
typeMap[soapActionInterface] = typedesc.TypeDesc{ typeMap[soapActionInterface] = typedesc.TypeDesc{
GoType: reflect.TypeOf((*soap.SOAPAction)(nil)).Elem(), GoType: reflect.TypeOf((*soap.Action)(nil)).Elem(),
} }
for _, m := range manifests.DCPS { for _, m := range manifests.DCPS {

View File

@ -9,6 +9,7 @@ import (
"io" "io"
"net/http" "net/http"
"github.com/huin/goupnp/v2alpha/soap"
"github.com/huin/goupnp/v2alpha/soap/envelope" "github.com/huin/goupnp/v2alpha/soap/envelope"
) )
@ -85,19 +86,17 @@ func (c *Client) Do(
return ParseResponseAction(resp, actionOut) return ParseResponseAction(resp, actionOut)
} }
// PerformAction makes a SOAP request, with the given `argsIn` as input // PerformAction makes a SOAP request, with the given action.
// arguments, and `argsOut` to capture the output arguments into.
// `serviceType` is the SOAP service type URN, `actionName` is the action to
// call.
// //
// 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( func PerformAction(
ctx context.Context, c *Client, ctx context.Context, c *Client,
serviceType, actionName string, action soap.Action,
argsIn, argsOut any,
) error { ) error {
actionIn := envelope.NewSendAction(serviceType, actionName, argsIn) actionIn := envelope.NewSendAction(
actionOut := &envelope.Action{Args: argsOut} action.ServiceType(), action.ActionName(), action.RefRequest())
actionOut := &envelope.Action{Args: action.RefResponse()}
return c.Do(ctx, actionIn, actionOut) return c.Do(ctx, actionIn, actionOut)
} }

View File

@ -8,9 +8,25 @@ import (
"testing" "testing"
"time" "time"
"github.com/huin/goupnp/v2alpha/soap"
"github.com/huin/goupnp/v2alpha/soap/envelope" "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 { type ActionArgs struct {
Name string Name string
} }
@ -81,7 +97,7 @@ func TestPerformAction(t *testing.T) {
service := &fakeSoapServer{ service := &fakeSoapServer{
responses: map[actionKey]*envelope.Action{ responses: map[actionKey]*envelope.Action{
{"/endpointpath", "\"http://example.com/endpointns#Foo\""}: { {"/endpointpath", fmt.Sprintf("\"%s#%s\"", serviceType, actionName)}: {
Args: &ActionReply{Greeting: "Hello, World!"}, Args: &ActionReply{Greeting: "Hello, World!"},
}, },
}, },
@ -91,13 +107,14 @@ func TestPerformAction(t *testing.T) {
c := New(ts.URL + "/endpointpath") c := New(ts.URL + "/endpointpath")
reply := &ActionReply{} a := &Action{
req: ActionArgs{Name: "World"},
}
if err := PerformAction(ctx, c, "http://example.com/endpointns", "Foo", if err := PerformAction(ctx, c, a); err != nil {
&ActionArgs{Name: "World"}, reply); err != nil {
t.Errorf("got error: %v, want success", err) t.Errorf("got error: %v, want success", err)
} else { } 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) t.Errorf("got %q, want %q", got, want)
} }
} }

View File

@ -1,9 +1,9 @@
// Package soap defines basic types used by SOAP packages. // Package soap defines basic types used by SOAP packages.
package soap 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. // struct types.
type SOAPAction interface { type Action interface {
// ServiceType returns Service type, e.g. "urn:schemas-upnp-org:service:Foo:1". // ServiceType returns Service type, e.g. "urn:schemas-upnp-org:service:Foo:1".
ServiceType() string ServiceType() string
// ActionName returns Action name, e.g. "SetBar". // ActionName returns Action name, e.g. "SetBar".