[10/10] webservices: Include a RelatesTo header in reply messages.

Hans Leidekker hans at codeweavers.com
Wed Sep 6 08:56:14 CDT 2017


Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
 dlls/webservices/channel.c             |   3 +
 dlls/webservices/msg.c                 | 161 ++++++++++++++++++++++++++-------
 dlls/webservices/webservices_private.h |   2 +
 3 files changed, 131 insertions(+), 35 deletions(-)

diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c
index 2b2415a..20d4f4c 100644
--- a/dlls/webservices/channel.c
+++ b/dlls/webservices/channel.c
@@ -1155,6 +1155,7 @@ HRESULT WINAPI WsSendReplyMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS
                                    const WS_ASYNC_CONTEXT *ctx, WS_ERROR *error )
 {
     struct channel *channel = (struct channel *)handle;
+    GUID req_id;
     HRESULT hr;
 
     TRACE( "%p %p %p %08x %p %u %p %p %p\n", handle, msg, desc, option, body, size, request, ctx, error );
@@ -1174,6 +1175,8 @@ HRESULT WINAPI WsSendReplyMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS
     if ((hr = WsInitializeMessage( msg, WS_REPLY_MESSAGE, NULL, NULL )) != S_OK) goto done;
     if ((hr = WsAddressMessage( msg, &channel->addr, NULL )) != S_OK) goto done;
     if ((hr = message_set_action( msg, desc->action )) != S_OK) goto done;
+    if ((hr = message_get_id( request, &req_id )) != S_OK) goto done;
+    if ((hr = message_set_request_id( msg, &req_id )) != S_OK) goto done;
 
     if ((hr = init_writer( channel )) != S_OK) goto done;
     if ((hr = write_message( msg, channel->writer, desc->bodyElementDescription, option, body, size )) != S_OK)
diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c
index add5526..fdbd672 100644
--- a/dlls/webservices/msg.c
+++ b/dlls/webservices/msg.c
@@ -531,57 +531,110 @@ static HRESULT write_must_understand( WS_XML_WRITER *writer, const WS_XML_STRING
     return WsWriteEndAttribute( writer, NULL );
 }
 
+static HRESULT write_action_header( WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
+                                    const WS_XML_STRING *ns_env, const WS_XML_STRING *prefix_addr,
+                                    const WS_XML_STRING *ns_addr, const WS_XML_STRING *text )
+{
+    WS_XML_UTF8_TEXT utf8 = {{WS_XML_TEXT_TYPE_UTF8}};
+    const WS_XML_STRING *action = get_header_name( WS_ACTION_HEADER );
+    HRESULT hr;
+
+    if (!text || !text->length) return S_OK;
+    utf8.value.length = text->length;
+    utf8.value.bytes  = text->bytes;
+
+    if ((hr = WsWriteStartElement( writer, prefix_addr, action, ns_addr, NULL )) != S_OK) return hr;
+    if ((hr = write_must_understand( writer, prefix_env, ns_env )) != S_OK) return hr;
+    if ((hr = WsWriteText( writer, &utf8.text, NULL )) != S_OK) return hr;
+    return WsWriteEndElement( writer, NULL ); /* </a:Action> */
+}
+
+static HRESULT write_to_header( WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
+                                const WS_XML_STRING *ns_env, const WS_XML_STRING *prefix_addr,
+                                const WS_XML_STRING *ns_addr, const WS_STRING *addr )
+{
+    WS_XML_UTF16_TEXT utf16 = {{WS_XML_TEXT_TYPE_UTF16}, (BYTE *)addr->chars, addr->length * sizeof(WCHAR)};
+    const WS_XML_STRING *to = get_header_name( WS_TO_HEADER );
+    HRESULT hr;
+
+    if ((hr = WsWriteStartElement( writer, prefix_addr, to, ns_addr, NULL )) != S_OK) return hr;
+    if ((hr = write_must_understand( writer, prefix_env, ns_env )) != S_OK) return hr;
+    if ((hr = WsWriteText( writer, &utf16.text, NULL )) != S_OK) return hr;
+    return WsWriteEndElement( writer, NULL ); /* </a:To> */
+}
+
+static HRESULT write_replyto_header( WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
+                                     const WS_XML_STRING *ns_env, const WS_XML_STRING *prefix_addr,
+                                     const WS_XML_STRING *ns_addr )
+{
+    static const char anonymous[] = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
+    WS_XML_UTF8_TEXT utf8 = {{WS_XML_TEXT_TYPE_UTF8}, {sizeof(anonymous) - 1, (BYTE *)anonymous}};
+    const WS_XML_STRING address = {7, (BYTE *)"Address"}, *replyto = get_header_name( WS_REPLY_TO_HEADER );
+    HRESULT hr;
+
+    if ((hr = WsWriteStartElement( writer, prefix_addr, replyto, ns_addr, NULL )) != S_OK) return hr;
+    if ((hr = WsWriteStartElement( writer, prefix_addr, &address, ns_addr, NULL )) != S_OK) return hr;
+    if ((hr = WsWriteText( writer, &utf8.text, NULL )) != S_OK) return hr;
+    if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </a:Address> */
+    return WsWriteEndElement( writer, NULL ); /* </a:ReplyTo> */
+}
+
+static HRESULT write_msgid_header( WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
+                                   const WS_XML_STRING *ns_env, const WS_XML_STRING *prefix_addr,
+                                   const WS_XML_STRING *ns_addr, const GUID *guid )
+{
+    WS_XML_UNIQUE_ID_TEXT id = {{WS_XML_TEXT_TYPE_UNIQUE_ID}, *guid};
+    const WS_XML_STRING *msgid = get_header_name( WS_MESSAGE_ID_HEADER );
+    HRESULT hr;
+
+    if ((hr = WsWriteStartElement( writer, prefix_addr, msgid, ns_addr, NULL )) != S_OK) return hr;
+    if ((hr = WsWriteText( writer, &id.text, NULL )) != S_OK) return hr;
+    return WsWriteEndElement( writer, NULL ); /* </a:MessageID> */
+}
+
+static HRESULT write_relatesto_header( WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
+                                       const WS_XML_STRING *ns_env, const WS_XML_STRING *prefix_addr,
+                                       const WS_XML_STRING *ns_addr, const GUID *guid )
+{
+    WS_XML_UNIQUE_ID_TEXT id = {{WS_XML_TEXT_TYPE_UNIQUE_ID}, *guid};
+    const WS_XML_STRING *relatesto = get_header_name( WS_RELATES_TO_HEADER );
+    HRESULT hr;
+
+    if ((hr = WsWriteStartElement( writer, prefix_addr, relatesto, ns_addr, NULL )) != S_OK) return hr;
+    if ((hr = WsWriteText( writer, &id.text, NULL )) != S_OK) return hr;
+    return WsWriteEndElement( writer, NULL ); /* </a:RelatesTo> */
+}
+
 static HRESULT write_headers( struct msg *msg, WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
                               const WS_XML_STRING *ns_env, const WS_XML_STRING *prefix_addr,
                               const WS_XML_STRING *ns_addr )
 {
-    static const char anonymous[] = "http://schemas.xmlsoap.org/ws/2004/08/addressing/role/anonymous";
-    static const WS_XML_STRING header = {6, (BYTE *)"Header"}, address = {7, (BYTE *)"Address"};
-    const WS_XML_STRING *msgid = get_header_name( WS_MESSAGE_ID_HEADER );
-    const WS_XML_STRING *replyto = get_header_name( WS_REPLY_TO_HEADER );
-    const WS_XML_STRING *to = get_header_name( WS_TO_HEADER );
-    const WS_XML_STRING *action = get_header_name( WS_ACTION_HEADER );
+    static const WS_XML_STRING header = {6, (BYTE *)"Header"};
     HRESULT hr;
     ULONG i;
 
     if ((hr = WsWriteXmlnsAttribute( writer, prefix_addr, ns_addr, FALSE, NULL )) != S_OK) return hr;
     if ((hr = WsWriteStartElement( writer, prefix_env, &header, ns_env, NULL )) != S_OK) return hr;
 
-    if (msg->action)
+    if ((hr = write_action_header( writer, prefix_env, ns_env, prefix_addr, ns_addr, msg->action )) != S_OK)
+        return hr;
+
+    if (msg->init == WS_REPLY_MESSAGE)
     {
-        WS_XML_UTF8_TEXT utf8 = {{WS_XML_TEXT_TYPE_UTF8}, {msg->action->length, msg->action->bytes}};
-        if ((hr = WsWriteStartElement( writer, prefix_addr, action, ns_addr, NULL )) != S_OK) return hr;
-        if ((hr = write_must_understand( writer, prefix_env, ns_env )) != S_OK) return hr;
-        if ((hr = WsWriteText( writer, &utf8.text, NULL )) != S_OK) return hr;
-        if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </a:Action> */
+        if ((hr = write_relatesto_header( writer, prefix_env, ns_env, prefix_addr, ns_addr, &msg->id_req )) != S_OK)
+            return hr;
     }
-    if (msg->addr.length)
+    else if (msg->addr.length)
     {
-        WS_XML_UTF16_TEXT utf16 = {{WS_XML_TEXT_TYPE_UTF16}, (BYTE *)msg->addr.chars,
-                                   msg->addr.length * sizeof(WCHAR)};
-        if ((hr = WsWriteStartElement( writer, prefix_addr, to, ns_addr, NULL )) != S_OK) return hr;
-        if ((hr = write_must_understand( writer, prefix_env, ns_env )) != S_OK) return hr;
-        if ((hr = WsWriteText( writer, &utf16.text, NULL )) != S_OK) return hr;
-        if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </a:To> */
+        if ((hr = write_to_header( writer, prefix_env, ns_env, prefix_addr, ns_addr, &msg->addr )) != S_OK)
+            return hr;
     }
     else
     {
-        WS_XML_UNIQUE_ID_TEXT id;
-        if ((hr = WsWriteStartElement( writer, prefix_addr, msgid, ns_addr, NULL )) != S_OK) return hr;
-        id.text.textType = WS_XML_TEXT_TYPE_UNIQUE_ID;
-        id.value         = msg->id;
-        if ((hr = WsWriteText( writer, &id.text, NULL )) != S_OK) return hr;
-        if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </a:MessageID> */
-
-        if (msg->version_addr == WS_ADDRESSING_VERSION_0_9)
-        {
-            WS_XML_UTF8_TEXT utf8 = {{WS_XML_TEXT_TYPE_UTF8}, {sizeof(anonymous) - 1, (BYTE *)anonymous}};
-            if ((hr = WsWriteStartElement( writer, prefix_addr, replyto, ns_addr, NULL )) != S_OK) return hr;
-            if ((hr = WsWriteStartElement( writer, prefix_addr, &address, ns_addr, NULL )) != S_OK) return hr;
-            if ((hr = WsWriteText( writer, &utf8.text, NULL )) != S_OK) return hr;
-            if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </a:Address> */
-            if ((hr = WsWriteEndElement( writer, NULL )) != S_OK) return hr; /* </a:ReplyTo> */
-        }
+        if ((hr = write_msgid_header( writer, prefix_env, ns_env, prefix_addr, ns_addr, &msg->id )) != S_OK)
+            return hr;
+        if (msg->version_addr == WS_ADDRESSING_VERSION_0_9 &&
+            (hr = write_replyto_header( writer, prefix_env, ns_env, prefix_addr, ns_addr )) != S_OK) return hr;
     }
 
     for (i = 0; i < msg->header_count; i++)
@@ -1869,3 +1922,41 @@ HRESULT message_set_action( WS_MESSAGE *handle, const WS_XML_STRING *action )
     LeaveCriticalSection( &msg->cs );
     return hr;
 }
+
+HRESULT message_get_id( WS_MESSAGE *handle, GUID *id )
+{
+    struct msg *msg = (struct msg *)handle;
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection( &msg->cs );
+
+    if (msg->magic != MSG_MAGIC)
+    {
+        LeaveCriticalSection( &msg->cs );
+        return E_INVALIDARG;
+    }
+
+    *id = msg->id_req;
+
+    LeaveCriticalSection( &msg->cs );
+    return hr;
+}
+
+HRESULT message_set_request_id( WS_MESSAGE *handle, const GUID *id )
+{
+    struct msg *msg = (struct msg *)handle;
+    HRESULT hr = S_OK;
+
+    EnterCriticalSection( &msg->cs );
+
+    if (msg->magic != MSG_MAGIC)
+    {
+        LeaveCriticalSection( &msg->cs );
+        return E_INVALIDARG;
+    }
+
+    msg->id_req = *id;
+
+    LeaveCriticalSection( &msg->cs );
+    return hr;
+}
diff --git a/dlls/webservices/webservices_private.h b/dlls/webservices/webservices_private.h
index da03213..219dd39 100644
--- a/dlls/webservices/webservices_private.h
+++ b/dlls/webservices/webservices_private.h
@@ -148,6 +148,8 @@ HRESULT prop_set( const struct prop *, ULONG, ULONG, const void *, ULONG ) DECLS
 HRESULT prop_get( const struct prop *, ULONG, ULONG, void *, ULONG ) DECLSPEC_HIDDEN;
 
 HRESULT message_set_action( WS_MESSAGE *, const WS_XML_STRING * ) DECLSPEC_HIDDEN;
+HRESULT message_get_id( WS_MESSAGE *, GUID * ) DECLSPEC_HIDDEN;
+HRESULT message_set_request_id( WS_MESSAGE *, const GUID * ) DECLSPEC_HIDDEN;
 void message_set_send_context( WS_MESSAGE *, const WS_PROXY_MESSAGE_CALLBACK_CONTEXT * ) DECLSPEC_HIDDEN;
 void message_set_receive_context( WS_MESSAGE *, const WS_PROXY_MESSAGE_CALLBACK_CONTEXT * ) DECLSPEC_HIDDEN;
 void message_do_send_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN;
-- 
2.1.4




More information about the wine-patches mailing list