webservices: Include a RelatesTo header in reply messages.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
ab522ac59b
commit
2946dc71aa
|
@ -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)
|
||||
|
|
|
@ -531,57 +531,110 @@ static HRESULT write_must_understand( WS_XML_WRITER *writer, const WS_XML_STRING
|
|||
return WsWriteEndAttribute( writer, NULL );
|
||||
}
|
||||
|
||||
static HRESULT write_headers( struct msg *msg, WS_XML_WRITER *writer, const WS_XML_STRING *prefix_env,
|
||||
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";
|
||||
static const WS_XML_STRING header = {6, (BYTE *)"Header"}, address = {7, (BYTE *)"Address"};
|
||||
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 );
|
||||
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 );
|
||||
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 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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue