wsdapi: Store discovered namespaces and write xmlns attributes for them.

Signed-off-by: Owen Rudge <orudge@codeweavers.com>
Signed-off-by: Huw Davies <huw@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Owen Rudge 2018-03-19 21:46:38 +00:00 committed by Alexandre Julliard
parent 45371b53f3
commit 402fce1579
4 changed files with 74 additions and 7 deletions

View file

@ -71,6 +71,13 @@ static const WCHAR relatesToString[] = { 'R','e','l','a','t','e','s','T','o', 0
static const WCHAR appSequenceString[] = { 'A','p','p','S','e','q','u','e','n','c','e', 0 };
static const WCHAR emptyString[] = { 0 };
struct discovered_namespace
{
struct list entry;
LPCWSTR prefix;
LPCWSTR uri;
};
static char *wide_to_utf8(LPCWSTR wide_string, int *length)
{
char *new_string = NULL;
@ -252,6 +259,31 @@ static void populate_soap_header(WSD_SOAP_HEADER *header, LPCWSTR to, LPCWSTR ac
/* TODO: Implement RelatesTo, ReplyTo, From, FaultTo */
}
static BOOL add_discovered_namespace(struct list *namespaces, WSDXML_NAMESPACE *discovered_ns)
{
struct discovered_namespace *ns;
LIST_FOR_EACH_ENTRY(ns, namespaces, struct discovered_namespace, entry)
{
if (lstrcmpW(ns->uri, discovered_ns->Uri) == 0)
return TRUE; /* Already added */
}
ns = WSDAllocateLinkedMemory(namespaces, sizeof(struct discovered_namespace));
if (ns == NULL)
return FALSE;
ns->prefix = duplicate_string(ns, discovered_ns->PreferredPrefix);
ns->uri = duplicate_string(ns, discovered_ns->Uri);
if ((ns->prefix == NULL) || (ns->uri == NULL))
return FALSE;
list_add_tail(namespaces, &ns->entry);
return TRUE;
}
static WSDXML_ELEMENT *create_soap_header_xml_elements(IWSDXMLContext *xml_context, WSD_SOAP_HEADER *header)
{
WSDXML_ELEMENT *header_element = NULL, *app_sequence_element = NULL;
@ -309,9 +341,10 @@ cleanup:
static HRESULT create_soap_envelope(IWSDXMLContext *xml_context, WSD_SOAP_HEADER *header, WSDXML_ELEMENT *body_element,
WS_HEAP **heap, char **output_xml, ULONG *xml_length, struct list *discovered_namespaces)
{
WS_XML_STRING *actual_envelope_prefix = NULL, *envelope_uri_xmlstr = NULL;
WS_XML_STRING *actual_envelope_prefix = NULL, *envelope_uri_xmlstr = NULL, *tmp_prefix = NULL, *tmp_uri = NULL;
WSDXML_NAMESPACE *addressing_ns = NULL, *discovery_ns = NULL, *envelope_ns = NULL;
WSDXML_ELEMENT *header_element = NULL;
struct discovered_namespace *ns;
WS_XML_BUFFER *buffer = NULL;
WS_XML_WRITER *writer = NULL;
WS_XML_STRING envelope;
@ -320,10 +353,13 @@ static HRESULT create_soap_envelope(IWSDXMLContext *xml_context, WSD_SOAP_HEADER
/* Create the necessary XML prefixes */
if (FAILED(IWSDXMLContext_AddNamespace(xml_context, addressingNsUri, addressingPrefix, &addressing_ns))) goto cleanup;
if (!add_discovered_namespace(discovered_namespaces, addressing_ns)) goto cleanup;
if (FAILED(IWSDXMLContext_AddNamespace(xml_context, discoveryNsUri, discoveryPrefix, &discovery_ns))) goto cleanup;
if (!add_discovered_namespace(discovered_namespaces, discovery_ns)) goto cleanup;
if (FAILED(IWSDXMLContext_AddNamespace(xml_context, envelopeNsUri, envelopePrefix, &envelope_ns))) goto cleanup;
if (!add_discovered_namespace(discovered_namespaces, envelope_ns)) goto cleanup;
envelope.bytes = envelopeString;
envelope.length = sizeof(envelopeString) - 1;
@ -356,6 +392,23 @@ static HRESULT create_soap_envelope(IWSDXMLContext *xml_context, WSD_SOAP_HEADER
ret = WsWriteStartElement(writer, actual_envelope_prefix, &envelope, envelope_uri_xmlstr, NULL);
if (FAILED(ret)) goto cleanup;
LIST_FOR_EACH_ENTRY(ns, discovered_namespaces, struct discovered_namespace, entry)
{
tmp_prefix = populate_xml_string(ns->prefix);
tmp_uri = populate_xml_string(ns->uri);
if ((tmp_prefix == NULL) || (tmp_uri == NULL)) goto cleanup;
ret = WsWriteXmlnsAttribute(writer, tmp_prefix, tmp_uri, FALSE, NULL);
if (FAILED(ret)) goto cleanup;
free_xml_string(tmp_prefix);
free_xml_string(tmp_uri);
}
tmp_prefix = NULL;
tmp_uri = NULL;
/* Write the header */
if (!write_xml_element(header_element, writer)) goto cleanup;
@ -401,7 +454,7 @@ static HRESULT write_and_send_message(IWSDiscoveryPublisherImpl *impl, WSD_SOAP_
char *full_xml;
HRESULT ret;
ret = create_soap_envelope(impl->xmlContext, header, NULL, &heap, &xml, &xml_length, NULL);
ret = create_soap_envelope(impl->xmlContext, header, NULL, &heap, &xml, &xml_length, discovered_namespaces);
if (ret != S_OK) return ret;
/* Prefix the XML header */
@ -439,6 +492,7 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLON
const WSD_URI_LIST *xaddrs_list, const WSDXML_ELEMENT *hdr_any, const WSDXML_ELEMENT *ref_param_any,
const WSDXML_ELEMENT *endpoint_ref_any, const WSDXML_ELEMENT *any)
{
struct list *discoveredNamespaces = NULL;
WSD_SOAP_HEADER soapHeader;
WSD_APP_SEQUENCE sequence;
WCHAR message_id[64];
@ -450,13 +504,20 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLON
if (!create_guid(message_id)) goto cleanup;
discoveredNamespaces = WSDAllocateLinkedMemory(NULL, sizeof(struct list));
if (!discoveredNamespaces) goto cleanup;
list_init(discoveredNamespaces);
populate_soap_header(&soapHeader, discoveryTo, actionHello, message_id, &sequence, hdr_any);
/* TODO: Populate message body */
/* Write and send the message */
ret = write_and_send_message(impl, &soapHeader, NULL, NULL, NULL, APP_MAX_DELAY);
ret = write_and_send_message(impl, &soapHeader, NULL, discoveredNamespaces, NULL, APP_MAX_DELAY);
cleanup:
WSDFreeLinkedMemory(discoveredNamespaces);
return ret;
}

View file

@ -506,6 +506,7 @@ static void Publish_tests(void)
messageStorage *msgStorage;
WSADATA wsaData;
BOOL messageOK;
BOOL hello_message_seen = FALSE;
int ret, i;
HRESULT rc;
ULONG ref;
@ -595,8 +596,8 @@ static void Publish_tests(void)
msg = msgStorage->messages[i];
messageOK = FALSE;
messageOK = (strstr(msg, "<wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Hello</wsa:Action>") != NULL);
messageOK = messageOK && (strstr(msg, endpointReferenceString) != NULL);
hello_message_seen = (strstr(msg, "<wsa:Action>http://schemas.xmlsoap.org/ws/2005/04/discovery/Hello</wsa:Action>") != NULL);
messageOK = hello_message_seen && (strstr(msg, endpointReferenceString) != NULL);
messageOK = messageOK && (strstr(msg, "<wsd:AppSequence InstanceId=\"1\" MessageNumber=\"1\"></wsd:AppSequence>") != NULL);
messageOK = messageOK && (strstr(msg, "<wsd:MetadataVersion>1</wsd:MetadataVersion>") != NULL);
@ -610,7 +611,8 @@ static void Publish_tests(void)
heap_free(msgStorage);
todo_wine ok(messageOK == TRUE, "Hello message not received\n");
ok(hello_message_seen == TRUE, "Hello message not received\n");
todo_wine ok(messageOK == TRUE, "Hello message metadata not received\n");
after_publish_test:

View file

@ -62,4 +62,8 @@ HRESULT send_hello_message(IWSDiscoveryPublisherImpl *impl, LPCWSTR id, ULONGLON
const WSD_URI_LIST *xaddrs_list, const WSDXML_ELEMENT *hdr_any, const WSDXML_ELEMENT *ref_param_any,
const WSDXML_ELEMENT *endpoint_ref_any, const WSDXML_ELEMENT *any);
/* xml.c */
LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value);
#endif

View file

@ -27,7 +27,7 @@
WINE_DEFAULT_DEBUG_CHANNEL(wsdapi);
static LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value)
LPWSTR duplicate_string(void *parentMemoryBlock, LPCWSTR value)
{
int valueLen;
LPWSTR dup;