webservices: Implement WsGetCustomHeader.

Signed-off-by: Hans Leidekker <hans@codeweavers.com>
Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
Hans Leidekker 2017-06-06 09:55:57 +02:00 committed by Alexandre Julliard
parent 64d029a811
commit 03a63781fa
3 changed files with 149 additions and 12 deletions

View File

@ -1081,23 +1081,16 @@ done:
return hr; return hr;
} }
static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type, static HRESULT find_header( WS_XML_READER *reader, const WS_XML_STRING *localname, const WS_XML_STRING *ns )
WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size )
{ {
const WS_XML_STRING *localname = get_header_name( type );
const WS_XML_STRING *ns = get_addr_namespace( msg->version_addr );
const WS_XML_ELEMENT_NODE *elem;
const WS_XML_NODE *node; const WS_XML_NODE *node;
const WS_XML_ELEMENT_NODE *elem;
HRESULT hr; HRESULT hr;
if (!heap) heap = msg->heap;
if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr;
if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr;
for (;;) for (;;)
{ {
if ((hr = WsReadNode( msg->reader, NULL )) != S_OK) return hr; if ((hr = WsReadNode( reader, NULL )) != S_OK) return hr;
if ((hr = WsGetReaderNode( msg->reader, &node, NULL )) != S_OK) return hr; if ((hr = WsGetReaderNode( reader, &node, NULL )) != S_OK) return hr;
if (node->nodeType == WS_XML_NODE_TYPE_EOF) return WS_E_INVALID_FORMAT; if (node->nodeType == WS_XML_NODE_TYPE_EOF) return WS_E_INVALID_FORMAT;
if (node->nodeType != WS_XML_NODE_TYPE_ELEMENT) continue; if (node->nodeType != WS_XML_NODE_TYPE_ELEMENT) continue;
@ -1106,6 +1099,21 @@ static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYP
WsXmlStringEquals( elem->ns, ns, NULL ) == S_OK) break; WsXmlStringEquals( elem->ns, ns, NULL ) == S_OK) break;
} }
return S_OK;
}
static HRESULT get_standard_header( struct msg *msg, WS_HEADER_TYPE type, WS_TYPE value_type,
WS_READ_OPTION option, WS_HEAP *heap, void *value, ULONG size )
{
const WS_XML_STRING *localname = get_header_name( type );
const WS_XML_STRING *ns = get_addr_namespace( msg->version_addr );
HRESULT hr;
if (!heap) heap = msg->heap;
if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr;
if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr;
if ((hr = find_header( msg->reader, localname, ns )) != S_OK) return hr;
return read_header( msg->reader, localname, ns, value_type, NULL, option, heap, value, size ); return read_header( msg->reader, localname, ns, value_type, NULL, option, heap, value, size );
} }
@ -1463,6 +1471,67 @@ done:
return hr; return hr;
} }
static HRESULT get_custom_header( struct msg *msg, const WS_ELEMENT_DESCRIPTION *desc, WS_READ_OPTION option,
WS_HEAP *heap, void *value, ULONG size )
{
HRESULT hr;
if (!heap) heap = msg->heap;
if (!msg->reader && (hr = WsCreateReader( NULL, 0, &msg->reader, NULL )) != S_OK) return hr;
if ((hr = WsSetInputToBuffer( msg->reader, msg->buf, NULL, 0, NULL )) != S_OK) return hr;
if ((hr = find_header( msg->reader, desc->elementLocalName, desc->elementNs )) != S_OK) return hr;
return read_header( msg->reader, desc->elementLocalName, desc->elementNs, desc->type, desc->typeDescription,
option, heap, value, size );
}
/**************************************************************************
* WsGetCustomHeader [webservices.@]
*/
HRESULT WINAPI WsGetCustomHeader( WS_MESSAGE *handle, const WS_ELEMENT_DESCRIPTION *desc,
WS_REPEATING_HEADER_OPTION repeat_option, ULONG index, WS_READ_OPTION option,
WS_HEAP *heap, void *value, ULONG size, ULONG *attrs, WS_ERROR *error )
{
struct msg *msg = (struct msg *)handle;
HRESULT hr;
TRACE( "%p %p %08x %u %08x %p %p %u %p %p\n", handle, desc, repeat_option, index, option, heap, value,
size, attrs, error );
if (error) FIXME( "ignoring error parameter\n" );
if (!msg || !desc || repeat_option < WS_REPEATING_HEADER || repeat_option > WS_SINGLETON_HEADER ||
(repeat_option == WS_SINGLETON_HEADER && index)) return E_INVALIDARG;
if (repeat_option == WS_REPEATING_HEADER)
{
FIXME( "repeating header not supported\n" );
return E_NOTIMPL;
}
if (attrs)
{
FIXME( "attributes not supported\n" );
return E_NOTIMPL;
}
EnterCriticalSection( &msg->cs );
if (msg->magic != MSG_MAGIC)
{
LeaveCriticalSection( &msg->cs );
return E_INVALIDARG;
}
if (msg->state < WS_MESSAGE_STATE_INITIALIZED)
{
LeaveCriticalSection( &msg->cs );
return WS_E_INVALID_OPERATION;
}
hr = get_custom_header( msg, desc, option, heap, value, size );
LeaveCriticalSection( &msg->cs );
return hr;
}
/************************************************************************** /**************************************************************************
* WsRemoveCustomHeader [webservices.@] * WsRemoveCustomHeader [webservices.@]
*/ */

View File

@ -1268,6 +1268,73 @@ static void test_WsGetHeader(void)
WsFreeMessage( msg ); WsFreeMessage( msg );
} }
static void test_WsGetCustomHeader(void)
{
static char expected[] =
"<Envelope><Header><Custom xmlns=\"ns\">value</Custom></Header><Body/></Envelope>";
static WS_XML_STRING custom = {6, (BYTE *)"Custom"}, ns = {2, (BYTE *)"ns"};
static WCHAR valueW[] = {'v','a','l','u','e',0};
WS_ELEMENT_DESCRIPTION desc;
WS_STRUCT_DESCRIPTION s;
WS_FIELD_DESCRIPTION f, *fields[1];
WS_MESSAGE *msg;
HRESULT hr;
struct header
{
const WCHAR *value;
} test;
hr = WsGetCustomHeader( NULL, NULL, 0, 0, 0, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
hr = WsCreateMessage( WS_ENVELOPE_VERSION_NONE, WS_ADDRESSING_VERSION_TRANSPORT, NULL, 0, &msg, NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsGetCustomHeader( msg, NULL, 0, 0, 0, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
hr = WsInitializeMessage( msg, WS_REQUEST_MESSAGE, NULL, NULL );
ok( hr == S_OK, "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 = &custom;
desc.elementNs = &ns;
desc.type = WS_STRUCT_TYPE;
desc.typeDescription = &s;
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, 0, 0, __LINE__ );
hr = WsGetCustomHeader( msg, &desc, 0, 0, 0, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
hr = WsGetCustomHeader( msg, &desc, WS_SINGLETON_HEADER, 1, 0, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
hr = WsGetCustomHeader( msg, &desc, WS_SINGLETON_HEADER, 0, WS_READ_REQUIRED_VALUE, NULL, NULL, 0, NULL, NULL );
ok( hr == E_INVALIDARG, "got %08x\n", hr );
memset( &test, 0, sizeof(test) );
hr = WsGetCustomHeader( msg, &desc, WS_SINGLETON_HEADER, 0, WS_READ_REQUIRED_VALUE, NULL, &test, sizeof(test),
NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( test.value != NULL, "value not set\n" );
ok( !memcmp( test.value, valueW, sizeof(valueW) ), "wrong value\n" );
WsFreeMessage( msg );
}
START_TEST(msg) START_TEST(msg)
{ {
test_WsCreateMessage(); test_WsCreateMessage();
@ -1288,4 +1355,5 @@ START_TEST(msg)
test_WsReadBody(); test_WsReadBody();
test_WsResetMessage(); test_WsResetMessage();
test_WsGetHeader(); test_WsGetHeader();
test_WsGetCustomHeader();
} }

View File

@ -60,7 +60,7 @@
@ stdcall WsFreeServiceProxy(ptr) @ stdcall WsFreeServiceProxy(ptr)
@ stdcall WsFreeWriter(ptr) @ stdcall WsFreeWriter(ptr)
@ stdcall WsGetChannelProperty(ptr long ptr long ptr) @ stdcall WsGetChannelProperty(ptr long ptr long ptr)
@ stub WsGetCustomHeader @ stdcall WsGetCustomHeader(ptr ptr long long long ptr ptr long ptr ptr)
@ stdcall WsGetDictionary(long ptr ptr) @ stdcall WsGetDictionary(long ptr ptr)
@ stdcall WsGetErrorProperty(ptr long ptr long) @ stdcall WsGetErrorProperty(ptr long ptr long)
@ stdcall WsGetErrorString(ptr long ptr) @ stdcall WsGetErrorString(ptr long ptr)