[2/8] webservices: Write correct envelope headers for WS_ENVELOPE_VERSION_NONE.
Hans Leidekker
hans at codeweavers.com
Tue Jun 6 02:55:55 CDT 2017
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
---
dlls/webservices/msg.c | 175 ++++++++++++++++++++-----------------------
dlls/webservices/tests/msg.c | 23 ++++++
2 files changed, 105 insertions(+), 93 deletions(-)
diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c
index 3032c83165..156060d50d 100644
--- a/dlls/webservices/msg.c
+++ b/dlls/webservices/msg.c
@@ -31,11 +31,6 @@
WINE_DEFAULT_DEBUG_CHANNEL(webservices);
-static const char ns_env_1_1[] = "http://schemas.xmlsoap.org/soap/envelope/";
-static const char ns_env_1_2[] = "http://www.w3.org/2003/05/soap-envelope";
-static const char ns_addr_0_9[] = "http://schemas.xmlsoap.org/ws/2004/08/addressing";
-static const char ns_addr_1_0[] = "http://www.w3.org/2005/08/addressing";
-
static const struct prop_desc msg_props[] =
{
{ sizeof(WS_MESSAGE_STATE), TRUE }, /* WS_MESSAGE_PROPERTY_STATE */
@@ -78,6 +73,7 @@ struct msg
WS_XML_BUFFER *buf;
WS_XML_WRITER *writer;
WS_XML_WRITER *writer_body;
+ WS_XML_READER *reader;
WS_XML_READER *reader_body;
ULONG header_count;
ULONG header_size;
@@ -160,6 +156,7 @@ static void free_msg( struct msg *msg )
reset_msg( msg );
WsFreeWriter( msg->writer );
+ WsFreeReader( msg->reader );
WsFreeHeap( msg->heap );
heap_free( msg->header );
@@ -219,7 +216,11 @@ HRESULT WINAPI WsCreateMessage( WS_ENVELOPE_VERSION env_version, WS_ADDRESSING_V
TRACE( "%u %u %p %u %p %p\n", env_version, addr_version, properties, count, handle, error );
if (error) FIXME( "ignoring error parameter\n" );
- if (!handle || !env_version || !addr_version) return E_INVALIDARG;
+ if (!handle || !env_version || !addr_version ||
+ (env_version == WS_ENVELOPE_VERSION_NONE && addr_version != WS_ADDRESSING_VERSION_TRANSPORT))
+ {
+ return E_INVALIDARG;
+ }
return create_msg( env_version, addr_version, properties, count, handle );
}
@@ -460,57 +461,40 @@ HRESULT WINAPI WsAddressMessage( WS_MESSAGE *handle, const WS_ENDPOINT_ADDRESS *
return hr;
}
-static HRESULT get_env_namespace( WS_ENVELOPE_VERSION ver, WS_XML_STRING *str )
+static const WS_XML_STRING *get_env_namespace( WS_ENVELOPE_VERSION version )
{
- switch (ver)
+ static const WS_XML_STRING namespaces[] =
{
- case WS_ENVELOPE_VERSION_SOAP_1_1:
- str->bytes = (BYTE *)ns_env_1_1;
- str->length = sizeof(ns_env_1_1)/sizeof(ns_env_1_1[0]) - 1;
- break;
-
- case WS_ENVELOPE_VERSION_SOAP_1_2:
- str->bytes = (BYTE *)ns_env_1_2;
- str->length = sizeof(ns_env_1_2)/sizeof(ns_env_1_2[0]) - 1;
- break;
+ {41, (BYTE *)"http://schemas.xmlsoap.org/soap/envelope/"},
+ {39, (BYTE *)"http://www.w3.org/2003/05/soap-envelope"},
+ {0, NULL},
+ };
- default:
- ERR( "unhandled envelope version %u\n", ver );
- return E_NOTIMPL;
+ if (version < WS_ENVELOPE_VERSION_SOAP_1_1 || version > WS_ENVELOPE_VERSION_NONE)
+ {
+ ERR( "unknown version %u\n", version );
+ return NULL;
}
- str->dictionary = NULL;
- str->id = 0;
- return S_OK;
+ return &namespaces[version - 1];
}
-static HRESULT get_addr_namespace( WS_ADDRESSING_VERSION ver, WS_XML_STRING *str )
+static const WS_XML_STRING *get_addr_namespace( WS_ADDRESSING_VERSION version )
{
- switch (ver)
+ static const WS_XML_STRING namespaces[] =
{
- case WS_ADDRESSING_VERSION_0_9:
- str->bytes = (BYTE *)ns_addr_0_9;
- str->length = sizeof(ns_addr_0_9)/sizeof(ns_addr_0_9[0]) - 1;
- break;
-
- case WS_ADDRESSING_VERSION_1_0:
- str->bytes = (BYTE *)ns_addr_1_0;
- str->length = sizeof(ns_addr_1_0)/sizeof(ns_addr_1_0[0]) - 1;
- break;
-
- case WS_ADDRESSING_VERSION_TRANSPORT:
- str->bytes = NULL;
- str->length = 0;
- break;
+ {48, (BYTE *)"http://schemas.xmlsoap.org/ws/2004/08/addressing"},
+ {36, (BYTE *)"http://www.w3.org/2005/08/addressing"},
+ {55, (BYTE *)"http://schemas.microsoft.com/ws/2005/05/addressing/none"},
+ };
- default:
- ERR( "unhandled addressing version %u\n", ver );
- return E_NOTIMPL;
+ if (version < WS_ADDRESSING_VERSION_0_9 || version > WS_ADDRESSING_VERSION_TRANSPORT)
+ {
+ ERR( "unknown version %u\n", version );
+ return NULL;
}
- str->dictionary = NULL;
- str->id = 0;
- return S_OK;
+ return &namespaces[version - 1];
}
static const WS_XML_STRING *get_header_name( WS_HEADER_TYPE type )
@@ -535,21 +519,22 @@ static const WS_XML_STRING *get_header_name( WS_HEADER_TYPE type )
return &headers[type - 1];
}
-static HRESULT write_headers( struct msg *msg, const WS_XML_STRING *ns_env, const WS_XML_STRING *ns_addr,
- WS_XML_WRITER *writer )
+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 prefix_s = {1, (BYTE *)"s"}, prefix_a = {1, (BYTE *)"a"};
- static const WS_XML_STRING msgid = {9, (BYTE *)"MessageID"}, replyto = {7, (BYTE *)"ReplyTo"};
- static const WS_XML_STRING address = {7, (BYTE *)"Address"}, header = {6, (BYTE *)"Header"};
+ 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 );
WS_XML_UTF8_TEXT urn, addr;
HRESULT hr;
ULONG i;
- if ((hr = WsWriteXmlnsAttribute( writer, &prefix_a, ns_addr, FALSE, NULL )) != S_OK) return hr;
- if ((hr = WsWriteStartElement( writer, &prefix_s, &header, ns_env, NULL )) != S_OK) return hr;
+ 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 ((hr = WsWriteStartElement( writer, &prefix_a, &msgid, ns_addr, NULL )) != S_OK) return hr;
+ if ((hr = WsWriteStartElement( writer, prefix_addr, msgid, ns_addr, NULL )) != S_OK) return hr;
urn.text.textType = WS_XML_TEXT_TYPE_UNIQUE_ID;
memcpy( &urn.value, &msg->id, sizeof(msg->id) );
if ((hr = WsWriteText( writer, &urn.text, NULL )) != S_OK) return hr;
@@ -557,8 +542,8 @@ static HRESULT write_headers( struct msg *msg, const WS_XML_STRING *ns_env, cons
if (msg->version_addr == WS_ADDRESSING_VERSION_0_9)
{
- if ((hr = WsWriteStartElement( writer, &prefix_a, &replyto, ns_addr, NULL )) != S_OK) return hr;
- if ((hr = WsWriteStartElement( writer, &prefix_a, &address, ns_addr, NULL )) != S_OK) return 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;
addr.text.textType = WS_XML_TEXT_TYPE_UTF8;
addr.value.bytes = (BYTE *)anonymous;
@@ -577,14 +562,15 @@ static HRESULT write_headers( struct msg *msg, const WS_XML_STRING *ns_env, cons
return WsWriteEndElement( writer, NULL ); /* </s:Header> */
}
-static HRESULT write_headers_transport( struct msg *msg, const WS_XML_STRING *ns_env, WS_XML_WRITER *writer )
+static HRESULT write_headers_transport( struct msg *msg, WS_XML_WRITER *writer, const WS_XML_STRING *prefix,
+ const WS_XML_STRING *ns )
{
- static const WS_XML_STRING prefix = {1, (BYTE *)"s"}, header = {6, (BYTE *)"Header"};
+ static const WS_XML_STRING header = {6, (BYTE *)"Header"};
HRESULT hr = S_OK;
ULONG i;
if ((msg->header_count || !msg->action.length) &&
- (hr = WsWriteStartElement( writer, &prefix, &header, ns_env, NULL )) != S_OK) return hr;
+ (hr = WsWriteStartElement( writer, prefix, &header, ns, NULL )) != S_OK) return hr;
for (i = 0; i < msg->header_count; i++)
{
@@ -599,21 +585,22 @@ static HRESULT write_headers_transport( struct msg *msg, const WS_XML_STRING *ns
static HRESULT write_envelope_start( struct msg *msg, WS_XML_WRITER *writer )
{
static const WS_XML_STRING envelope = {8, (BYTE *)"Envelope"}, body = {4, (BYTE *)"Body"};
- static const WS_XML_STRING prefix = {1, (BYTE *)"s"};
- WS_XML_STRING ns_env, ns_addr;
+ static const WS_XML_STRING prefix_s = {1, (BYTE *)"s"}, prefix_a = {1, (BYTE *)"a"};
+ const WS_XML_STRING *prefix_env = (msg->version_env == WS_ENVELOPE_VERSION_NONE) ? NULL : &prefix_s;
+ const WS_XML_STRING *prefix_addr = (msg->version_addr == WS_ADDRESSING_VERSION_TRANSPORT) ? NULL : &prefix_a;
+ const WS_XML_STRING *ns_env = get_env_namespace( msg->version_env );
+ const WS_XML_STRING *ns_addr = get_addr_namespace( msg->version_addr );
HRESULT hr;
- if ((hr = get_env_namespace( msg->version_env, &ns_env )) != S_OK) return hr;
- if ((hr = get_addr_namespace( msg->version_addr, &ns_addr )) != S_OK) return hr;
- if ((hr = WsWriteStartElement( writer, &prefix, &envelope, &ns_env, NULL )) != S_OK) return hr;
+ if ((hr = WsWriteStartElement( writer, prefix_env, &envelope, ns_env, NULL )) != S_OK) return hr;
if (msg->version_addr == WS_ADDRESSING_VERSION_TRANSPORT)
- hr = write_headers_transport( msg, &ns_env, writer );
+ hr = write_headers_transport( msg, writer, prefix_env, ns_env );
else
- hr = write_headers( msg, &ns_env, &ns_addr, writer );
+ hr = write_headers( msg, writer, prefix_env, ns_env, prefix_addr, ns_addr );
if (hr != S_OK) return hr;
- return WsWriteStartElement( writer, &prefix, &body, &ns_env, NULL ); /* <s:Body> */
+ return WsWriteStartElement( writer, prefix_env, &body, ns_env, NULL ); /* <s:Body> */
}
static HRESULT write_envelope_end( WS_XML_WRITER *writer )
@@ -986,47 +973,51 @@ static struct header *alloc_header( WS_HEADER_TYPE type, BOOL mapped, const WS_X
return ret;
}
-static HRESULT write_standard_header( WS_XML_WRITER *writer, const WS_XML_STRING *name, WS_TYPE value_type,
+static HRESULT write_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type,
WS_WRITE_OPTION option, const void *value, ULONG size )
{
+ static const WS_XML_STRING ns = {0, NULL}, understand = {14, (BYTE *)"mustUnderstand"};
static const WS_XML_STRING prefix_s = {1, (BYTE *)"s"}, prefix_a = {1, (BYTE *)"a"};
- static const WS_XML_STRING understand = {14, (BYTE *)"mustUnderstand"}, ns = {0, NULL};
+ const WS_XML_STRING *prefix_env = (msg->version_env == WS_ENVELOPE_VERSION_NONE) ? NULL : &prefix_s;
+ const WS_XML_STRING *prefix_addr = (msg->version_addr == WS_ADDRESSING_VERSION_TRANSPORT) ? NULL : &prefix_a;
+ const WS_XML_STRING *localname = get_header_name( type );
WS_XML_INT32_TEXT one = {{WS_XML_TEXT_TYPE_INT32}, 1};
HRESULT hr;
- if ((hr = WsWriteStartElement( writer, &prefix_a, name, &ns, NULL )) != S_OK) return hr;
- if ((hr = WsWriteStartAttribute( writer, &prefix_s, &understand, &ns, FALSE, NULL )) != S_OK) return hr;
- if ((hr = WsWriteText( writer, &one.text, NULL )) != S_OK) return hr;
- if ((hr = WsWriteEndAttribute( writer, NULL )) != S_OK) return hr;
- if ((hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, value_type, NULL, option, value, size,
+ if ((hr = WsWriteStartElement( msg->writer, prefix_addr, localname, &ns, NULL )) != S_OK) return hr;
+ if ((hr = WsWriteStartAttribute( msg->writer, prefix_env, &understand, &ns, FALSE, NULL )) != S_OK) return hr;
+ if ((hr = WsWriteText( msg->writer, &one.text, NULL )) != S_OK) return hr;
+ if ((hr = WsWriteEndAttribute( msg->writer, NULL )) != S_OK) return hr;
+ if (msg->version_addr == WS_ADDRESSING_VERSION_TRANSPORT)
+ {
+ const WS_XML_STRING *ns_addr = get_addr_namespace( WS_ADDRESSING_VERSION_TRANSPORT );
+ if ((hr = WsWriteXmlnsAttribute( msg->writer, NULL, ns_addr, FALSE, NULL )) != S_OK) return hr;
+ }
+ if ((hr = WsWriteType( msg->writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, value_type, NULL, option, value, size,
NULL )) != S_OK) return hr;
- return WsWriteEndElement( writer, NULL );
+ return WsWriteEndElement( msg->writer, NULL );
}
-static HRESULT build_standard_header( WS_HEAP *heap, WS_HEADER_TYPE type, WS_TYPE value_type,
+static HRESULT build_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type,
WS_WRITE_OPTION option, const void *value, ULONG size,
struct header **ret )
{
- const WS_XML_STRING *name = get_header_name( type );
struct header *header;
- WS_XML_WRITER *writer;
WS_XML_BUFFER *buf;
HRESULT hr;
- if (!(header = alloc_header( type, FALSE, name, NULL ))) return E_OUTOFMEMORY;
+ if (!(header = alloc_header( type, FALSE, get_header_name(type), NULL ))) return E_OUTOFMEMORY;
- if ((hr = WsCreateWriter( NULL, 0, &writer, NULL )) != S_OK) goto done;
- if ((hr = WsCreateXmlBuffer( heap, NULL, 0, &buf, NULL )) != S_OK) goto done;
- if ((hr = WsSetOutputToBuffer( writer, buf, NULL, 0, NULL )) != S_OK) goto done;
- if ((hr = write_standard_header( writer, name, value_type, option, value, size )) != S_OK)
- goto done;
+ if (!msg->writer && (hr = WsCreateWriter( NULL, 0, &msg->writer, NULL )) != S_OK) return hr;
+ if ((hr = WsCreateXmlBuffer( msg->heap, NULL, 0, &buf, NULL )) != S_OK) goto done;
+ if ((hr = WsSetOutputToBuffer( msg->writer, buf, NULL, 0, NULL )) != S_OK) goto done;
+ if ((hr = write_standard_header( msg, type, value_type, option, value, size )) != S_OK) goto done;
header->u.buf = buf;
done:
if (hr != S_OK) free_header( header );
else *ret = header;
- WsFreeWriter( writer );
return hr;
}
@@ -1076,7 +1067,7 @@ HRESULT WINAPI WsSetHeader( WS_MESSAGE *handle, WS_HEADER_TYPE type, WS_TYPE val
i = msg->header_count;
}
- if ((hr = build_standard_header( msg->heap, type, value_type, option, value, size, &header )) != S_OK)
+ if ((hr = build_standard_header( msg, type, value_type, option, value, size, &header )) != S_OK)
goto done;
if (!found) msg->header_count++;
@@ -1346,28 +1337,26 @@ static HRESULT write_custom_header( WS_XML_WRITER *writer, const WS_XML_STRING *
return WsWriteEndElement( writer, NULL );
}
-static HRESULT build_custom_header( WS_HEAP *heap, const WS_XML_STRING *name, const WS_XML_STRING *ns,
+static HRESULT build_custom_header( struct msg *msg, const WS_XML_STRING *name, const WS_XML_STRING *ns,
WS_TYPE type, const void *desc, WS_WRITE_OPTION option, const void *value,
ULONG size, struct header **ret )
{
struct header *header;
- WS_XML_WRITER *writer;
WS_XML_BUFFER *buf;
HRESULT hr;
if (!(header = alloc_header( 0, FALSE, name, ns ))) return E_OUTOFMEMORY;
- if ((hr = WsCreateWriter( NULL, 0, &writer, NULL )) != S_OK) goto done;
- if ((hr = WsCreateXmlBuffer( heap, NULL, 0, &buf, NULL )) != S_OK) goto done;
- if ((hr = WsSetOutputToBuffer( writer, buf, NULL, 0, NULL )) != S_OK) goto done;
- if ((hr = write_custom_header( writer, name, ns, type, desc, option, value, size )) != S_OK) goto done;
+ if (!msg->writer && (hr = WsCreateWriter( NULL, 0, &msg->writer, NULL )) != S_OK) return hr;
+ if ((hr = WsCreateXmlBuffer( msg->heap, NULL, 0, &buf, NULL )) != S_OK) goto done;
+ if ((hr = WsSetOutputToBuffer( msg->writer, buf, NULL, 0, NULL )) != S_OK) goto done;
+ if ((hr = write_custom_header( msg->writer, name, ns, type, desc, option, value, size )) != S_OK) goto done;
header->u.buf = buf;
done:
if (hr != S_OK) free_header( header );
else *ret = header;
- WsFreeWriter( writer );
return hr;
}
@@ -1401,7 +1390,7 @@ HRESULT WINAPI WsAddCustomHeader( WS_MESSAGE *handle, const WS_ELEMENT_DESCRIPTI
}
if ((hr = grow_header_array( msg, msg->header_count + 1 )) != S_OK) goto done;
- if ((hr = build_custom_header( msg->heap, desc->elementLocalName, desc->elementNs, desc->type,
+ if ((hr = build_custom_header( msg, desc->elementLocalName, desc->elementNs, desc->type,
desc->typeDescription, option, value, size, &header )) != S_OK) goto done;
msg->header[msg->header_count++] = header;
hr = write_envelope( msg );
diff --git a/dlls/webservices/tests/msg.c b/dlls/webservices/tests/msg.c
index 868ead5a20..4d25265930 100644
--- a/dlls/webservices/tests/msg.c
+++ b/dlls/webservices/tests/msg.c
@@ -340,6 +340,8 @@ static void test_WsWriteEnvelopeStart(void)
"</a:ReplyTo></s:Header><s:Body/></s:Envelope>";
static const char expected3[] =
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Header/><s:Body/></s:Envelope>";
+ static const char expected4[] =
+ "<Envelope><Header/><Body/></Envelope>";
HRESULT hr;
WS_MESSAGE *msg;
WS_XML_WRITER *writer;
@@ -391,8 +393,29 @@ static void test_WsWriteEnvelopeStart(void)
hr = WsWriteEnvelopeStart( msg, writer, NULL, NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
check_output_header( msg, expected3, -1, 0, 0, __LINE__ );
+ WsFreeMessage( msg );
+
+ hr = WsCreateMessage( WS_ENVELOPE_VERSION_NONE, WS_ADDRESSING_VERSION_TRANSPORT, NULL, 0, &msg,
+ NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = set_output( writer );
+ ok( hr == S_OK, "got %08x\n", hr );
+ hr = WsWriteEnvelopeStart( msg, writer, NULL, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ check_output_header( msg, expected4, -1, 0, 0, __LINE__ );
WsFreeMessage( msg );
+
+ hr = WsCreateMessage( WS_ENVELOPE_VERSION_NONE, WS_ADDRESSING_VERSION_0_9, NULL, 0, &msg,
+ NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+ hr = WsCreateMessage( WS_ENVELOPE_VERSION_NONE, WS_ADDRESSING_VERSION_1_0, NULL, 0, &msg,
+ NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
WsFreeWriter( writer );
}
--
2.11.0
More information about the wine-patches
mailing list