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.
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 {

View File

@ -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)
}

View File

@ -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)
}
}

View File

@ -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".