Hans Leidekker : webservices: Implement WsAddCustomHeader.
Alexandre Julliard
julliard at winehq.org
Wed Aug 31 11:02:42 CDT 2016
Module: wine
Branch: master
Commit: 147cd6b35b094b03bed3c3351bdc9a911638a10f
URL: http://source.winehq.org/git/wine.git/?a=commit;h=147cd6b35b094b03bed3c3351bdc9a911638a10f
Author: Hans Leidekker <hans at codeweavers.com>
Date: Wed Aug 31 14:35:28 2016 +0200
webservices: Implement WsAddCustomHeader.
Signed-off-by: Hans Leidekker <hans at codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard at winehq.org>
---
dlls/webservices/msg.c | 81 +++++++++++++++++++++++++++++++++++++++
dlls/webservices/tests/msg.c | 67 ++++++++++++++++++++++++++++++++
dlls/webservices/webservices.spec | 2 +-
3 files changed, 149 insertions(+), 1 deletion(-)
diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c
index 67b157e..ffe19f9 100644
--- a/dlls/webservices/msg.c
+++ b/dlls/webservices/msg.c
@@ -881,3 +881,84 @@ HRESULT WINAPI WsRemoveMappedHeader( WS_MESSAGE *handle, const WS_XML_STRING *na
return S_OK;
}
+
+static HRESULT write_custom_header( WS_XML_WRITER *writer, 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 )
+{
+ HRESULT hr;
+ if ((hr = WsWriteStartElement( writer, NULL, name, ns, NULL )) != S_OK) return hr;
+ if ((hr = WsWriteType( writer, WS_ELEMENT_CONTENT_TYPE_MAPPING, type, desc, option, value, size,
+ NULL )) != S_OK) return hr;
+ return WsWriteEndElement( writer, NULL );
+}
+
+static HRESULT build_custom_header( WS_HEAP *heap, 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;
+
+ header->u.buf = buf;
+
+done:
+ if (hr != S_OK) free_header( header );
+ else *ret = header;
+ WsFreeWriter( writer );
+ return hr;
+}
+
+/**************************************************************************
+ * WsAddCustomHeader [webservices.@]
+ */
+HRESULT WINAPI WsAddCustomHeader( WS_MESSAGE *handle, const WS_ELEMENT_DESCRIPTION *desc, WS_WRITE_OPTION option,
+ const void *value, ULONG size, ULONG attrs, WS_ERROR *error )
+{
+ struct msg *msg = (struct msg *)handle;
+ struct header *header;
+ BOOL found = FALSE;
+ HRESULT hr;
+ ULONG i;
+
+ TRACE( "%p %p %08x %p %u %08x %p\n", handle, desc, option, value, size, attrs, error );
+ if (error) FIXME( "ignoring error parameter\n" );
+
+ if (!handle || !desc) return E_INVALIDARG;
+ if (msg->state < WS_MESSAGE_STATE_INITIALIZED) return WS_E_INVALID_OPERATION;
+
+ for (i = 0; i < msg->header_count; i++)
+ {
+ if (msg->header[i]->type || msg->header[i]->mapped) continue;
+ if (WsXmlStringEquals( desc->elementLocalName, &msg->header[i]->name, NULL ) &&
+ WsXmlStringEquals( desc->elementNs, &msg->header[i]->ns, NULL ) == S_OK)
+ {
+ found = TRUE;
+ break;
+ }
+ }
+
+ if (!found)
+ {
+ if ((hr = grow_header_array( msg, msg->header_count + 1 )) != S_OK) return hr;
+ i = msg->header_count;
+ }
+
+ if ((hr = build_custom_header( msg->heap, desc->elementLocalName, desc->elementNs, desc->type,
+ desc->typeDescription, option, value, size, &header )) != S_OK) return hr;
+
+ if (!found) msg->header_count++;
+ else free_header( msg->header[i] );
+
+ msg->header[i] = header;
+ return write_envelope( msg );
+}
diff --git a/dlls/webservices/tests/msg.c b/dlls/webservices/tests/msg.c
index 73fcfd6..a038d66 100644
--- a/dlls/webservices/tests/msg.c
+++ b/dlls/webservices/tests/msg.c
@@ -737,6 +737,72 @@ static void test_WsRemoveMappedHeader(void)
WsFreeMessage( msg );
}
+static void test_WsAddCustomHeader(void)
+{
+ static const char expected[] =
+ "<s:Envelope xmlns:a=\"http://www.w3.org/2005/08/addressing\" "
+ "xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header>"
+ "<a:MessageID>urn:uuid:00000000-0000-0000-0000-000000000000</a:MessageID>"
+ "<header xmlns=\"ns\">value</header></s:Header><s:Body/></s:Envelope>";
+ static const char expected2[] =
+ "<s:Envelope xmlns:a=\"http://www.w3.org/2005/08/addressing\" "
+ "xmlns:s=\"http://www.w3.org/2003/05/soap-envelope\"><s:Header>"
+ "<a:MessageID>urn:uuid:00000000-0000-0000-0000-000000000000</a:MessageID>"
+ "</s:Header><s:Body/></s:Envelope>";
+ static WS_XML_STRING header = {6, (BYTE *)"header"}, ns = {2, (BYTE *)"ns"};
+ static WCHAR valueW[] = {'v','a','l','u','e',0};
+ HRESULT hr;
+ WS_MESSAGE *msg;
+ WS_ELEMENT_DESCRIPTION desc;
+ WS_STRUCT_DESCRIPTION s;
+ WS_FIELD_DESCRIPTION f, *fields[1];
+ struct header
+ {
+ const WCHAR *value;
+ } test;
+
+ hr = WsAddCustomHeader( NULL, NULL, 0, NULL, 0, 0, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ hr = WsCreateMessage( WS_ADDRESSING_VERSION_1_0, WS_ENVELOPE_VERSION_SOAP_1_2, NULL, 0, &msg, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+
+ hr = WsAddCustomHeader( msg, NULL, 0, NULL, 0, 0, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ memset( &f, 0, sizeof(f) );
+ f.mapping = WS_TEXT_FIELD_MAPPING;
+ f.type = WS_WSZ_TYPE;
+ fields[0] = &f;
+
+ memset( &s, 0, sizeof(s) );
+ s.size = sizeof(struct header);
+ s.alignment = TYPE_ALIGNMENT(struct header);
+ s.fields = fields;
+ s.fieldCount = 1;
+
+ desc.elementLocalName = &header;
+ desc.elementNs = &ns;
+ desc.type = WS_STRUCT_TYPE;
+ desc.typeDescription = &s;
+ hr = WsAddCustomHeader( msg, &desc, 0, NULL, 0, 0, NULL );
+ ok( hr == WS_E_INVALID_OPERATION, "got %08x\n", hr );
+
+ hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ check_output_header( msg, expected2, -1, strstr(expected2, "urn:uuid:") - expected2, 46, __LINE__ );
+
+ test.value = valueW;
+ hr = WsAddCustomHeader( msg, &desc, WS_WRITE_REQUIRED_VALUE, &test, sizeof(test), 0, NULL );
+ ok( hr == S_OK, "got %08x\n", hr );
+ check_output_header( msg, expected, -1, strstr(expected, "urn:uuid:") - expected, 46, __LINE__ );
+
+ hr = WsAddCustomHeader( msg, &desc, WS_WRITE_REQUIRED_VALUE, NULL, 0, 0, NULL );
+ ok( hr == E_INVALIDARG, "got %08x\n", hr );
+
+ WsFreeMessage( msg );
+}
+
START_TEST(msg)
{
test_WsCreateMessage();
@@ -750,4 +816,5 @@ START_TEST(msg)
test_WsRemoveHeader();
test_WsAddMappedHeader();
test_WsRemoveMappedHeader();
+ test_WsAddCustomHeader();
}
diff --git a/dlls/webservices/webservices.spec b/dlls/webservices/webservices.spec
index acf5167..1ac3b75 100644
--- a/dlls/webservices/webservices.spec
+++ b/dlls/webservices/webservices.spec
@@ -5,7 +5,7 @@
@ stub WsAbortServiceHost
@ stub WsAbortServiceProxy
@ stub WsAcceptChannel
-@ stub WsAddCustomHeader
+@ stdcall WsAddCustomHeader(ptr ptr long ptr long long ptr)
@ stub WsAddErrorString
@ stdcall WsAddMappedHeader(ptr ptr long long ptr long ptr)
@ stdcall WsAddressMessage(ptr ptr ptr)
More information about the wine-cvs
mailing list