Skip to content

Commit 162a2ff

Browse files
authored
Fix sending WSAs if they are already present (#48)
1 parent 3c329bd commit 162a2ff

File tree

3 files changed

+48
-4
lines changed

3 files changed

+48
-4
lines changed

onvif/client.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
import zeep.helpers
1515
from zeep.proxy import AsyncServiceProxy
1616
from zeep.transports import AsyncTransport
17-
from zeep.wsa import WsAddressingPlugin
1817
from zeep.wsdl import Document
1918
from zeep.wsse.username import UsernameToken
2019

@@ -28,6 +27,7 @@
2827
from .types import FastDateTime
2928
from .util import create_no_verify_ssl_context, normalize_url, path_isfile, utcnow
3029
from .wrappers import retry_connection_error # noqa: F401
30+
from .wsa import WsAddressingIfMissingPlugin
3131

3232
logger = logging.getLogger("onvif")
3333
logging.basicConfig(level=logging.INFO)
@@ -242,7 +242,7 @@ async def setup(self):
242242
wsdl=self.document,
243243
transport=self.transport,
244244
settings=settings,
245-
plugins=[WsAddressingPlugin()],
245+
plugins=[WsAddressingIfMissingPlugin()],
246246
)
247247
self.ws_client_authless = self.zeep_client_authless.create_service(
248248
binding_name, self.xaddr
@@ -252,7 +252,7 @@ async def setup(self):
252252
wsse=wsse,
253253
transport=self.transport,
254254
settings=settings,
255-
plugins=[WsAddressingPlugin()],
255+
plugins=[WsAddressingIfMissingPlugin()],
256256
)
257257
self.ws_client = self.zeep_client.create_service(binding_name, self.xaddr)
258258
namespace = binding_name[binding_name.find("{") + 1 : binding_name.find("}")]

onvif/util.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import os
88
import ssl
99
from typing import Any
10-
from urllib.parse import urlparse, urlunparse, ParseResultBytes
10+
from urllib.parse import ParseResultBytes, urlparse, urlunparse
1111

1212
from zeep.exceptions import Fault
1313

onvif/wsa.py

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
import uuid
2+
3+
from lxml import etree
4+
from lxml.builder import ElementMaker
5+
from zeep import ns
6+
from zeep.plugins import Plugin
7+
from zeep.wsdl.utils import get_or_create_header
8+
9+
WSA = ElementMaker(namespace=ns.WSA, nsmap={"wsa": ns.WSA})
10+
11+
12+
class WsAddressingIfMissingPlugin(Plugin):
13+
nsmap = {"wsa": ns.WSA}
14+
15+
def __init__(self, address_url: str = None):
16+
self.address_url = address_url
17+
18+
def egress(self, envelope, http_headers, operation, binding_options):
19+
"""Apply the ws-addressing headers to the given envelope."""
20+
header = get_or_create_header(envelope)
21+
for elem in header:
22+
if (elem.prefix or "").startswith("wsa"):
23+
# WSA header already exists
24+
return envelope, http_headers
25+
26+
wsa_action = operation.abstract.wsa_action
27+
if not wsa_action:
28+
wsa_action = operation.soapaction
29+
30+
headers = [
31+
WSA.Action(wsa_action),
32+
WSA.MessageID("urn:uuid:" + str(uuid.uuid4())),
33+
WSA.To(self.address_url or binding_options["address"]),
34+
]
35+
header.extend(headers)
36+
37+
# the top_nsmap kwarg was added in lxml 3.5.0
38+
if etree.LXML_VERSION[:2] >= (3, 5):
39+
etree.cleanup_namespaces(
40+
header, keep_ns_prefixes=header.nsmap, top_nsmap=self.nsmap
41+
)
42+
else:
43+
etree.cleanup_namespaces(header)
44+
return envelope, http_headers

0 commit comments

Comments
 (0)