Commit 02962d92 authored by Hans Leidekker's avatar Hans Leidekker Committed by Alexandre Julliard

webservices: Add support for mapped HTTP headers.

parent 7236d982
...@@ -330,6 +330,26 @@ static void reset_channel( struct channel *channel ) ...@@ -330,6 +330,26 @@ static void reset_channel( struct channel *channel )
} }
} }
static void free_header_mappings( WS_HTTP_HEADER_MAPPING **mappings, ULONG count )
{
ULONG i;
for (i = 0; i < count; i++) heap_free( mappings[i] );
heap_free( mappings );
}
static void free_message_mapping( const WS_HTTP_MESSAGE_MAPPING *mapping )
{
free_header_mappings( mapping->requestHeaderMappings, mapping->requestHeaderMappingCount );
free_header_mappings( mapping->responseHeaderMappings, mapping->responseHeaderMappingCount );
}
static void free_props( struct channel *channel )
{
struct prop *prop = &channel->prop[WS_CHANNEL_PROPERTY_HTTP_MESSAGE_MAPPING];
WS_HTTP_MESSAGE_MAPPING *mapping = (WS_HTTP_MESSAGE_MAPPING *)prop->value;
free_message_mapping( mapping );
}
static void free_channel( struct channel *channel ) static void free_channel( struct channel *channel )
{ {
reset_channel( channel ); reset_channel( channel );
...@@ -338,6 +358,7 @@ static void free_channel( struct channel *channel ) ...@@ -338,6 +358,7 @@ static void free_channel( struct channel *channel )
WsFreeReader( channel->reader ); WsFreeReader( channel->reader );
heap_free( channel->read_buf ); heap_free( channel->read_buf );
free_props( channel );
channel->send_q.cs.DebugInfo->Spare[0] = 0; channel->send_q.cs.DebugInfo->Spare[0] = 0;
channel->recv_q.cs.DebugInfo->Spare[0] = 0; channel->recv_q.cs.DebugInfo->Spare[0] = 0;
...@@ -348,6 +369,58 @@ static void free_channel( struct channel *channel ) ...@@ -348,6 +369,58 @@ static void free_channel( struct channel *channel )
heap_free( channel ); heap_free( channel );
} }
static WS_HTTP_HEADER_MAPPING *dup_header_mapping( const WS_HTTP_HEADER_MAPPING *src )
{
WS_HTTP_HEADER_MAPPING *dst;
if (!(dst = heap_alloc( sizeof(*dst) + src->headerName.length ))) return NULL;
dst->headerName.bytes = (BYTE *)(dst + 1);
memcpy( dst->headerName.bytes, src->headerName.bytes, src->headerName.length );
dst->headerName.length = src->headerName.length;
dst->headerMappingOptions = src->headerMappingOptions;
return dst;
}
static HRESULT dup_message_mapping( const WS_HTTP_MESSAGE_MAPPING *src, WS_HTTP_MESSAGE_MAPPING *dst )
{
ULONG i, size;
size = src->requestHeaderMappingCount * sizeof(*dst->responseHeaderMappings);
if (!(dst->requestHeaderMappings = heap_alloc( size ))) return E_OUTOFMEMORY;
for (i = 0; i < src->requestHeaderMappingCount; i++)
{
if (!(dst->requestHeaderMappings[i] = dup_header_mapping( src->requestHeaderMappings[i] )))
{
free_header_mappings( dst->requestHeaderMappings, i );
return E_OUTOFMEMORY;
}
}
size = src->responseHeaderMappingCount * sizeof(*dst->responseHeaderMappings);
if (!(dst->responseHeaderMappings = heap_alloc( size )))
{
heap_free( dst->responseHeaderMappings );
return E_OUTOFMEMORY;
}
for (i = 0; i < src->responseHeaderMappingCount; i++)
{
if (!(dst->responseHeaderMappings[i] = dup_header_mapping( src->responseHeaderMappings[i] )))
{
free_header_mappings( dst->responseHeaderMappings, i );
return E_OUTOFMEMORY;
}
}
dst->requestMappingOptions = src->requestMappingOptions;
dst->responseMappingOptions = src->responseMappingOptions;
dst->requestHeaderMappingCount = src->requestHeaderMappingCount;
dst->responseHeaderMappingCount = src->responseHeaderMappingCount;
return S_OK;
}
static HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding, static HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding,
const WS_CHANNEL_PROPERTY *properties, ULONG count, struct channel **ret ) const WS_CHANNEL_PROPERTY *properties, ULONG count, struct channel **ret )
{ {
...@@ -390,25 +463,47 @@ static HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding, ...@@ -390,25 +463,47 @@ static HRESULT create_channel( WS_CHANNEL_TYPE type, WS_CHANNEL_BINDING binding,
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
{ {
TRACE( "property id %u value ptr %p size %u\n", properties[i].id, properties[i].value, const WS_CHANNEL_PROPERTY *prop = &properties[i];
properties[i].valueSize );
if (properties[i].valueSize == sizeof(ULONG) && properties[i].value) TRACE( "property id %u value %p size %u\n", prop->id, prop->value, prop->valueSize );
TRACE( " value %08x\n", *(ULONG *)properties[i].value ); if (prop->valueSize == sizeof(ULONG) && prop->value) TRACE( " value %08x\n", *(ULONG *)prop->value );
switch (properties[i].id) switch (prop->id)
{ {
case WS_CHANNEL_PROPERTY_ENCODING: case WS_CHANNEL_PROPERTY_ENCODING:
if (!properties[i].value || properties[i].valueSize != sizeof(channel->encoding)) if (!prop->value || prop->valueSize != sizeof(channel->encoding))
{
free_channel( channel );
return E_INVALIDARG;
}
channel->encoding = *(WS_ENCODING *)prop->value;
break;
case WS_CHANNEL_PROPERTY_HTTP_MESSAGE_MAPPING:
{
const WS_HTTP_MESSAGE_MAPPING *src = (WS_HTTP_MESSAGE_MAPPING *)prop->value;
WS_HTTP_MESSAGE_MAPPING dst;
if (!prop->value || prop->valueSize != sizeof(*src))
{ {
free_channel( channel ); free_channel( channel );
return E_INVALIDARG; return E_INVALIDARG;
} }
channel->encoding = *(WS_ENCODING *)properties[i].value;
if ((hr = dup_message_mapping( src, &dst )) != S_OK) return hr;
if ((hr = prop_set( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_HTTP_MESSAGE_MAPPING, &dst,
sizeof(dst) )) != S_OK)
{
free_message_mapping( &dst );
free_channel( channel );
return hr;
}
break; break;
}
default: default:
if ((hr = prop_set( channel->prop, channel->prop_count, properties[i].id, properties[i].value, if ((hr = prop_set( channel->prop, channel->prop_count, prop->id, prop->value, prop->valueSize )) != S_OK)
properties[i].valueSize )) != S_OK)
{ {
free_channel( channel ); free_channel( channel );
return hr; return hr;
...@@ -1517,13 +1612,27 @@ static HRESULT init_reader( struct channel *channel ) ...@@ -1517,13 +1612,27 @@ static HRESULT init_reader( struct channel *channel )
return WsSetInput( channel->reader, encoding, input, NULL, 0, NULL ); return WsSetInput( channel->reader, encoding, input, NULL, 0, NULL );
} }
static const WS_HTTP_MESSAGE_MAPPING *get_http_message_mapping( struct channel *channel )
{
const struct prop *prop = &channel->prop[WS_CHANNEL_PROPERTY_HTTP_MESSAGE_MAPPING];
return (const WS_HTTP_MESSAGE_MAPPING *)prop->value;
}
static HRESULT map_http_response_headers( struct channel *channel, WS_MESSAGE *msg )
{
const WS_HTTP_MESSAGE_MAPPING *mapping = get_http_message_mapping( channel );
return message_map_http_response_headers( msg, channel->u.http.request, mapping );
}
#define INITIAL_READ_BUFFER_SIZE 4096 #define INITIAL_READ_BUFFER_SIZE 4096
static HRESULT receive_message_http( struct channel *channel ) static HRESULT receive_message_http( struct channel *channel, WS_MESSAGE *msg )
{ {
DWORD len, bytes_read, offset = 0, size = INITIAL_READ_BUFFER_SIZE; DWORD len, bytes_read, offset = 0, size = INITIAL_READ_BUFFER_SIZE;
ULONG max_len; ULONG max_len;
HRESULT hr; HRESULT hr;
if ((hr = map_http_response_headers( channel, msg )) != S_OK) return hr;
prop_get( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE, prop_get( channel->prop, channel->prop_count, WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE,
&max_len, sizeof(max_len) ); &max_len, sizeof(max_len) );
...@@ -1814,7 +1923,7 @@ static HRESULT receive_message_session( struct channel *channel ) ...@@ -1814,7 +1923,7 @@ static HRESULT receive_message_session( struct channel *channel )
return S_OK; return S_OK;
} }
static HRESULT receive_message_bytes( struct channel *channel ) static HRESULT receive_message_bytes( struct channel *channel, WS_MESSAGE *msg )
{ {
HRESULT hr; HRESULT hr;
if ((hr = connect_channel( channel )) != S_OK) return hr; if ((hr = connect_channel( channel )) != S_OK) return hr;
...@@ -1822,7 +1931,7 @@ static HRESULT receive_message_bytes( struct channel *channel ) ...@@ -1822,7 +1931,7 @@ static HRESULT receive_message_bytes( struct channel *channel )
switch (channel->binding) switch (channel->binding)
{ {
case WS_HTTP_CHANNEL_BINDING: case WS_HTTP_CHANNEL_BINDING:
return receive_message_http( channel ); return receive_message_http( channel, msg );
case WS_TCP_CHANNEL_BINDING: case WS_TCP_CHANNEL_BINDING:
if (channel->type & WS_CHANNEL_TYPE_SESSION) if (channel->type & WS_CHANNEL_TYPE_SESSION)
...@@ -1853,7 +1962,7 @@ static HRESULT receive_message_bytes( struct channel *channel ) ...@@ -1853,7 +1962,7 @@ static HRESULT receive_message_bytes( struct channel *channel )
} }
} }
HRESULT channel_receive_message( WS_CHANNEL *handle ) HRESULT channel_receive_message( WS_CHANNEL *handle, WS_MESSAGE *msg )
{ {
struct channel *channel = (struct channel *)handle; struct channel *channel = (struct channel *)handle;
HRESULT hr; HRESULT hr;
...@@ -1866,7 +1975,7 @@ HRESULT channel_receive_message( WS_CHANNEL *handle ) ...@@ -1866,7 +1975,7 @@ HRESULT channel_receive_message( WS_CHANNEL *handle )
return E_INVALIDARG; return E_INVALIDARG;
} }
if ((hr = receive_message_bytes( channel )) == S_OK) hr = init_reader( channel ); if ((hr = receive_message_bytes( channel, msg )) == S_OK) hr = init_reader( channel );
LeaveCriticalSection( &channel->cs ); LeaveCriticalSection( &channel->cs );
return hr; return hr;
...@@ -1906,7 +2015,7 @@ static HRESULT receive_message( struct channel *channel, WS_MESSAGE *msg, const ...@@ -1906,7 +2015,7 @@ static HRESULT receive_message( struct channel *channel, WS_MESSAGE *msg, const
HRESULT hr; HRESULT hr;
ULONG i; ULONG i;
if ((hr = receive_message_bytes( channel )) != S_OK) return hr; if ((hr = receive_message_bytes( channel, msg )) != S_OK) return hr;
if ((hr = init_reader( channel )) != S_OK) return hr; if ((hr = init_reader( channel )) != S_OK) return hr;
for (i = 0; i < count; i++) for (i = 0; i < count; i++)
...@@ -2148,7 +2257,7 @@ HRESULT WINAPI WsReadMessageStart( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS ...@@ -2148,7 +2257,7 @@ HRESULT WINAPI WsReadMessageStart( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS
return E_INVALIDARG; return E_INVALIDARG;
} }
if ((hr = receive_message_bytes( channel )) == S_OK) if ((hr = receive_message_bytes( channel, msg )) == S_OK)
{ {
if ((hr = init_reader( channel )) == S_OK) if ((hr = init_reader( channel )) == S_OK)
hr = WsReadEnvelopeStart( msg, channel->reader, NULL, NULL, NULL ); hr = WsReadEnvelopeStart( msg, channel->reader, NULL, NULL, NULL );
......
...@@ -455,7 +455,7 @@ static HRESULT receive_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE ...@@ -455,7 +455,7 @@ static HRESULT receive_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE
HRESULT hr; HRESULT hr;
if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr; if ((hr = message_set_action( msg, desc->action )) != S_OK) return hr;
if ((hr = channel_receive_message( channel )) != S_OK) return hr; if ((hr = channel_receive_message( channel, msg )) != S_OK) return hr;
if ((hr = channel_get_reader( channel, &reader )) != S_OK) return hr; if ((hr = channel_get_reader( channel, &reader )) != S_OK) return hr;
return read_message( msg, reader, heap, desc->bodyElementDescription, params, count, args ); return read_message( msg, reader, heap, desc->bodyElementDescription, params, count, args );
} }
......
...@@ -361,13 +361,34 @@ static void test_WsReceiveMessage( int port ) ...@@ -361,13 +361,34 @@ static void test_WsReceiveMessage( int port )
WsFreeMessage( msg ); WsFreeMessage( msg );
} }
static WS_HTTP_HEADER_MAPPING mapped_request_header =
{
{19, (BYTE *)"MappedRequestHeader"}
};
static WS_HTTP_HEADER_MAPPING *request_header_mappings[] =
{
&mapped_request_header
};
static WS_HTTP_HEADER_MAPPING mapped_response_header =
{
{20, (BYTE *)"MappedResponseHeader"}
};
static WS_HTTP_HEADER_MAPPING *response_header_mappings[] =
{
&mapped_response_header
};
static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret ) static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret )
{ {
static const WCHAR fmt[] = static const WCHAR fmt[] =
{'h','t','t','p',':','/','/','1','2','7','.','0','.','0','.','1',':','%','u','/',0}; {'h','t','t','p',':','/','/','1','2','7','.','0','.','0','.','1',':','%','u','/',0};
WS_ENVELOPE_VERSION env_version; WS_ENVELOPE_VERSION env_version;
WS_ADDRESSING_VERSION addr_version; WS_ADDRESSING_VERSION addr_version;
WS_CHANNEL_PROPERTY prop[2]; WS_HTTP_MESSAGE_MAPPING mapping;
WS_CHANNEL_PROPERTY prop[3];
WS_ENDPOINT_ADDRESS addr; WS_ENDPOINT_ADDRESS addr;
WS_SERVICE_PROXY *proxy; WS_SERVICE_PROXY *proxy;
WCHAR url[64]; WCHAR url[64];
...@@ -383,6 +404,17 @@ static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret ) ...@@ -383,6 +404,17 @@ static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret )
prop[1].value = &addr_version; prop[1].value = &addr_version;
prop[1].valueSize = sizeof(addr_version); prop[1].valueSize = sizeof(addr_version);
mapping.requestMappingOptions = 0;
mapping.responseMappingOptions = 0;
mapping.requestHeaderMappings = request_header_mappings;
mapping.requestHeaderMappingCount = ARRAY_SIZE(request_header_mappings);
mapping.responseHeaderMappings = response_header_mappings;
mapping.responseHeaderMappingCount = ARRAY_SIZE(response_header_mappings);
prop[2].id = WS_CHANNEL_PROPERTY_HTTP_MESSAGE_MAPPING;
prop[2].value = &mapping;
prop[2].valueSize = sizeof(mapping);
*ret = NULL; *ret = NULL;
hr = WsCreateServiceProxy( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, NULL, NULL, hr = WsCreateServiceProxy( WS_CHANNEL_TYPE_REQUEST, WS_HTTP_CHANNEL_BINDING, NULL, NULL,
0, prop, ARRAY_SIZE( prop ), &proxy, NULL ); 0, prop, ARRAY_SIZE( prop ), &proxy, NULL );
...@@ -397,6 +429,38 @@ static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret ) ...@@ -397,6 +429,38 @@ static HRESULT create_proxy( int port, WS_SERVICE_PROXY **ret )
return hr; return hr;
} }
static HRESULT set_output( WS_XML_WRITER *writer )
{
WS_XML_WRITER_TEXT_ENCODING text = {{ WS_XML_WRITER_ENCODING_TYPE_TEXT }, WS_CHARSET_UTF8 };
WS_XML_WRITER_BUFFER_OUTPUT buf = {{ WS_XML_WRITER_OUTPUT_TYPE_BUFFER }};
return WsSetOutput( writer, &text.encoding, &buf.output, NULL, 0, NULL );
}
static void check_output_headers( WS_MESSAGE *msg )
{
WS_XML_WRITER *writer;
WS_XML_BUFFER *buf;
WS_BYTES bytes;
HRESULT hr;
hr = WsCreateWriter( NULL, 0, &writer, NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = set_output( writer );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsGetMessageProperty( msg, WS_MESSAGE_PROPERTY_HEADER_BUFFER, &buf, sizeof(buf), NULL );
ok( hr == S_OK, "got %08x\n", hr );
hr = WsWriteXmlBuffer( writer, buf, NULL );
ok( hr == S_OK, "got %08x\n", hr );
memset( &bytes, 0, sizeof(bytes) );
hr = WsGetWriterProperty( writer, WS_XML_WRITER_PROPERTY_BYTES, &bytes, sizeof(bytes), NULL );
ok( hr == S_OK, "got %08x\n", hr );
WsFreeWriter( writer );
}
static const char req_test2[] = static const char req_test2[] =
"<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>" "<s:Envelope xmlns:s=\"http://schemas.xmlsoap.org/soap/envelope/\"><s:Body>"
"<req_test2 xmlns=\"ns\"><val>1</val><str>test</str><str>test2</str></req_test2>" "<req_test2 xmlns=\"ns\"><val>1</val><str>test</str><str>test2</str></req_test2>"
...@@ -407,6 +471,32 @@ static const char resp_test2[] = ...@@ -407,6 +471,32 @@ static const char resp_test2[] =
"<resp_test2 xmlns=\"ns\"><str>test</str><val>1</val><val>2</val></resp_test2>" "<resp_test2 xmlns=\"ns\"><str>test</str><val>1</val><val>2</val></resp_test2>"
"</s:Body></s:Envelope>"; "</s:Body></s:Envelope>";
static HRESULT CALLBACK send_callback( WS_MESSAGE *msg, WS_HEAP *heap, void *state, WS_ERROR *error )
{
static const WS_XML_STRING header = {19, (BYTE *)"MappedRequestHeader"}, value = {5, (BYTE *)"value"};
HRESULT hr;
hr = WsAddMappedHeader( msg, &header, WS_XML_STRING_TYPE, WS_WRITE_REQUIRED_VALUE, &value, sizeof(value), NULL );
ok( hr == S_OK, "got %08x\n", hr );
check_output_headers( msg );
return S_OK;
}
static HRESULT CALLBACK recv_callback( WS_MESSAGE *msg, WS_HEAP *heap, void *state, WS_ERROR *error )
{
static const WS_XML_STRING header = {20, (BYTE *)"MappedResponseHeader"};
static const WCHAR valueW[] = {'v','a','l','u','e',0};
WCHAR *str;
HRESULT hr;
check_output_headers( msg );
hr = WsGetMappedHeader( msg, &header, WS_SINGLETON_HEADER, 0, WS_WSZ_TYPE, WS_READ_OPTIONAL_POINTER, heap,
&str, sizeof(str), NULL );
ok( hr == S_OK, "got %08x\n", hr );
ok( !lstrcmpW(str, valueW), "wrong value %s\n", wine_dbgstr_w(str) );
return S_OK;
}
static void test_WsCall( int port ) static void test_WsCall( int port )
{ {
static const WCHAR testW[] = {'t','e','s','t',0}, test2W[] = {'t','e','s','t','2',0}; static const WCHAR testW[] = {'t','e','s','t',0}, test2W[] = {'t','e','s','t','2',0};
...@@ -421,6 +511,9 @@ static void test_WsCall( int port ) ...@@ -421,6 +511,9 @@ static void test_WsCall( int port )
WS_XML_STRING ns = {2, (BYTE *)"ns"}; WS_XML_STRING ns = {2, (BYTE *)"ns"};
HRESULT hr; HRESULT hr;
WS_SERVICE_PROXY *proxy; WS_SERVICE_PROXY *proxy;
WS_PROXY_MESSAGE_CALLBACK_CONTEXT ctx_send;
WS_PROXY_MESSAGE_CALLBACK_CONTEXT ctx_recv;
WS_CALL_PROPERTY prop[2];
WS_OPERATION_DESCRIPTION op; WS_OPERATION_DESCRIPTION op;
WS_MESSAGE_DESCRIPTION input_msg, output_msg; WS_MESSAGE_DESCRIPTION input_msg, output_msg;
WS_ELEMENT_DESCRIPTION input_elem, output_elem; WS_ELEMENT_DESCRIPTION input_elem, output_elem;
...@@ -511,7 +604,21 @@ static void test_WsCall( int port ) ...@@ -511,7 +604,21 @@ static void test_WsCall( int port )
args[4] = &val_ptr; args[4] = &val_ptr;
args[5] = &count_ptr; args[5] = &count_ptr;
hr = WsCall( proxy, &op, args, heap, NULL, 0, NULL, NULL ); ctx_send.callback = send_callback;
ctx_send.state = NULL;
prop[0].id = WS_CALL_PROPERTY_SEND_MESSAGE_CONTEXT;
prop[0].value = &ctx_send;
prop[0].valueSize = sizeof(ctx_send);
ctx_recv.callback = recv_callback;
ctx_recv.state = NULL;
prop[1].id = WS_CALL_PROPERTY_RECEIVE_MESSAGE_CONTEXT;
prop[1].value = &ctx_recv;
prop[1].valueSize = sizeof(ctx_recv);
hr = WsCall( proxy, &op, args, heap, prop, ARRAY_SIZE(prop), NULL, NULL );
ok( hr == S_OK, "got %08x\n", hr ); ok( hr == S_OK, "got %08x\n", hr );
ok( !lstrcmpW( out.str, testW ), "wrong data\n" ); ok( !lstrcmpW( out.str, testW ), "wrong data\n" );
ok( out.count == 2, "got %u\n", out.count ); ok( out.count == 2, "got %u\n", out.count );
...@@ -616,7 +723,7 @@ tests[] = ...@@ -616,7 +723,7 @@ tests[] =
static void send_response( int c, const char *status, const char *data, unsigned int len ) static void send_response( int c, const char *status, const char *data, unsigned int len )
{ {
static const char headers[] = static const char headers[] =
"Content-Type: text/xml; charset=utf-8\r\nConnection: close\r\n"; "Content-Type: text/xml; charset=utf-8\r\nConnection: close\r\nMappedResponseHeader: value\r\n";
static const char fmt[] = static const char fmt[] =
"Content-Length: %u\r\n\r\n"; "Content-Length: %u\r\n\r\n";
char buf[128]; char buf[128];
...@@ -694,10 +801,11 @@ static DWORD CALLBACK server_proc( void *arg ) ...@@ -694,10 +801,11 @@ static DWORD CALLBACK server_proc( void *arg )
if (tests[j].req_data) if (tests[j].req_data)
{ {
int data_len = strlen( buf ); int data_len = strlen( buf );
ok( tests[j].req_len == data_len, "%u: unexpected data length %u %u\n", ok( tests[j].req_len == data_len, "%u: got data length %u expected %u\n",
j, data_len, tests[j].req_len ); j, data_len, tests[j].req_len );
if (tests[j].req_len == data_len) if (tests[j].req_len == data_len)
ok( !memcmp( tests[j].req_data, buf, tests[j].req_len ), "%u: unexpected data %s\n", j, buf ); ok( !memcmp( tests[j].req_data, buf, tests[j].req_len ),
"%u: got data '%s' expected '%s'\n", j, buf, tests[j].req_data );
} }
send_response( c, tests[j].resp_status, tests[j].resp_data, tests[j].resp_len ); send_response( c, tests[j].resp_status, tests[j].resp_data, tests[j].resp_len );
break; break;
......
...@@ -70,7 +70,7 @@ ...@@ -70,7 +70,7 @@
@ stub WsGetHeaderAttributes @ stub WsGetHeaderAttributes
@ stdcall WsGetHeapProperty(ptr long ptr long ptr) @ stdcall WsGetHeapProperty(ptr long ptr long ptr)
@ stdcall WsGetListenerProperty(ptr long ptr long ptr) @ stdcall WsGetListenerProperty(ptr long ptr long ptr)
@ stub WsGetMappedHeader @ stdcall WsGetMappedHeader(ptr ptr long long long long ptr ptr long ptr)
@ stdcall WsGetMessageProperty(ptr long ptr long ptr) @ stdcall WsGetMessageProperty(ptr long ptr long ptr)
@ stub WsGetMetadataEndpoints @ stub WsGetMetadataEndpoints
@ stub WsGetMetadataProperty @ stub WsGetMetadataProperty
......
...@@ -161,9 +161,10 @@ void message_set_receive_context( WS_MESSAGE *, const WS_PROXY_MESSAGE_CALLBACK_ ...@@ -161,9 +161,10 @@ void message_set_receive_context( WS_MESSAGE *, const WS_PROXY_MESSAGE_CALLBACK_
void message_do_send_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN; void message_do_send_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN;
void message_do_receive_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN; void message_do_receive_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN;
HRESULT message_insert_http_headers( WS_MESSAGE *, HINTERNET ) DECLSPEC_HIDDEN; HRESULT message_insert_http_headers( WS_MESSAGE *, HINTERNET ) DECLSPEC_HIDDEN;
HRESULT message_map_http_response_headers( WS_MESSAGE *, HINTERNET, const WS_HTTP_MESSAGE_MAPPING * ) DECLSPEC_HIDDEN;
HRESULT channel_send_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN; HRESULT channel_send_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN;
HRESULT channel_receive_message( WS_CHANNEL * ) DECLSPEC_HIDDEN; HRESULT channel_receive_message( WS_CHANNEL *, WS_MESSAGE * ) DECLSPEC_HIDDEN;
HRESULT channel_get_reader( WS_CHANNEL *, WS_XML_READER ** ) DECLSPEC_HIDDEN; HRESULT channel_get_reader( WS_CHANNEL *, WS_XML_READER ** ) DECLSPEC_HIDDEN;
HRESULT parse_url( const WS_STRING *, WS_URL_SCHEME_TYPE *, WCHAR **, USHORT * ) DECLSPEC_HIDDEN; HRESULT parse_url( const WS_STRING *, WS_URL_SCHEME_TYPE *, WCHAR **, USHORT * ) DECLSPEC_HIDDEN;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment