webservices: Implement WsDecodeUrl.
Signed-off-by: Hans Leidekker <hans@codeweavers.com> Signed-off-by: Alexandre Julliard <julliard@winehq.org>
This commit is contained in:
parent
084827e901
commit
24bdad63e4
|
@ -7,4 +7,5 @@ C_SRCS = \
|
||||||
main.c \
|
main.c \
|
||||||
proxy.c \
|
proxy.c \
|
||||||
reader.c \
|
reader.c \
|
||||||
|
url.c \
|
||||||
writer.c
|
writer.c
|
||||||
|
|
|
@ -5,4 +5,5 @@ C_SRCS = \
|
||||||
channel.c \
|
channel.c \
|
||||||
proxy.c \
|
proxy.c \
|
||||||
reader.c \
|
reader.c \
|
||||||
|
url.c \
|
||||||
writer.c
|
writer.c
|
||||||
|
|
|
@ -0,0 +1,194 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdio.h>
|
||||||
|
#include "windows.h"
|
||||||
|
#include "webservices.h"
|
||||||
|
#include "wine/test.h"
|
||||||
|
|
||||||
|
static void test_WsDecodeUrl(void)
|
||||||
|
{
|
||||||
|
static WCHAR url1[] = {'h','t','t','p',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url2[] = {'h','t','t','p','s',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url3[] = {'h','t','t','p',':','/','/','h','o','s','t',':','8','0',0};
|
||||||
|
static WCHAR url4[] = {'h','t','t','p','s',':','/','/','h','o','s','t',':','8','0',0};
|
||||||
|
static WCHAR url5[] = {'h','t','t','p',':','/','/','h','o','s','t','/','p','a','t','h',0};
|
||||||
|
static WCHAR url6[] = {'h','t','t','p',':','/','/','h','o','s','t','/','p','a','t','h','?',
|
||||||
|
'q','u','e','r','y',0};
|
||||||
|
static WCHAR url7[] = {'h','t','t','p',':','/','/','h','o','s','t','/','p','a','t','h','?',
|
||||||
|
'q','u','e','r','y','#','f','r','a','g',0};
|
||||||
|
static WCHAR url8[] = {'H','T','T','P',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url9[] = {'h','t','t','q',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url10[] = {'h','t','t','p',':',0};
|
||||||
|
static WCHAR url11[] = {'h','t','t','p',0};
|
||||||
|
static WCHAR url12[] = {'n','e','t','.','t','c','p',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url13[] = {'s','o','a','p','.','u','d','p',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url14[] = {'n','e','t','.','p','i','p','e',':','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url15[] = {'h','t','t','p',':','/','h','o','s','t',0};
|
||||||
|
static WCHAR url16[] = {'h','t','t','p',':','h','o','s','t',0};
|
||||||
|
static WCHAR url17[] = {'h','t','t','p',':','/','/','/','h','o','s','t',0};
|
||||||
|
static WCHAR url18[] = {'h','t','t','p',':','/','/','h','o','s','t','/',0};
|
||||||
|
static WCHAR url19[] = {'h','t','t','p',':','/','/','h','o','s','t',':','/',0};
|
||||||
|
static WCHAR url20[] = {'h','t','t','p',':','/','/','h','o','s','t',':','6','5','5','3','6',0};
|
||||||
|
static WCHAR url21[] = {'h','t','t','p',':','/','/','h','o','s','t','?','q','u','e','r','y',0};
|
||||||
|
static WCHAR url22[] = {'h','t','t','p',':','/','/','h','o','s','t','#','f','r','a','g',0};
|
||||||
|
static WCHAR url23[] = {'h','t','t','p',':','/','/','h','o','s','t','%','2','0','2',0};
|
||||||
|
static WCHAR url24[] = {'h','t','t','p',':','/','/','h','o','s','t','/','p','a','t','h',
|
||||||
|
'%','2','0','2',0};
|
||||||
|
static WCHAR url25[] = {'h','t','t','p',':','/','/','h','o','s','t','?','q','u','e','r','y',
|
||||||
|
'%','2','0','2',0};
|
||||||
|
static WCHAR url26[] = {'h','t','t','p',':','/','/','h','o','s','t','#','f','r','a','g',
|
||||||
|
'%','2','0','2',0};
|
||||||
|
static WCHAR host2[] = {'h','o','s','t',' ','2'};
|
||||||
|
static WCHAR path2[] = {'/','p','a','t','h',' ','2'};
|
||||||
|
static WCHAR query2[] = {'q','u','e','r','y',' ','2'};
|
||||||
|
static WCHAR frag2[] = {'f','r','a','g',' ','2'};
|
||||||
|
static const struct
|
||||||
|
{
|
||||||
|
WCHAR *str;
|
||||||
|
HRESULT hr;
|
||||||
|
WS_URL_SCHEME_TYPE scheme;
|
||||||
|
WCHAR *host;
|
||||||
|
ULONG host_len;
|
||||||
|
USHORT port;
|
||||||
|
WCHAR *port_str;
|
||||||
|
ULONG port_len;
|
||||||
|
WCHAR *path;
|
||||||
|
ULONG path_len;
|
||||||
|
WCHAR *query;
|
||||||
|
ULONG query_len;
|
||||||
|
WCHAR *fragment;
|
||||||
|
ULONG fragment_len;
|
||||||
|
}
|
||||||
|
tests[] =
|
||||||
|
{
|
||||||
|
{ url1, S_OK, WS_URL_HTTP_SCHEME_TYPE, url1 + 7, 4, 80 },
|
||||||
|
{ url2, S_OK, WS_URL_HTTPS_SCHEME_TYPE, url2 + 8, 4, 443 },
|
||||||
|
{ url3, S_OK, WS_URL_HTTP_SCHEME_TYPE, url3 + 7, 4, 80, url3 + 12, 2 },
|
||||||
|
{ url4, S_OK, WS_URL_HTTPS_SCHEME_TYPE, url4 + 8, 4, 80, url4 + 13, 2 },
|
||||||
|
{ url5, S_OK, WS_URL_HTTP_SCHEME_TYPE, url5 + 7, 4, 80, NULL, 0, url5 + 11, 5 },
|
||||||
|
{ url6, S_OK, WS_URL_HTTP_SCHEME_TYPE, url5 + 7, 4, 80, NULL, 0, url6 + 11, 5, url6 + 17, 5 },
|
||||||
|
{ url7, S_OK, WS_URL_HTTP_SCHEME_TYPE, url5 + 7, 4, 80, NULL, 0, url7 + 11, 5, url7 + 17, 5,
|
||||||
|
url7 + 23, 4 },
|
||||||
|
{ url8, S_OK, WS_URL_HTTP_SCHEME_TYPE, url1 + 7, 4, 80 },
|
||||||
|
{ url9, WS_E_INVALID_FORMAT },
|
||||||
|
{ url10, WS_E_INVALID_FORMAT },
|
||||||
|
{ url11, WS_E_INVALID_FORMAT },
|
||||||
|
{ url12, S_OK, WS_URL_NETTCP_SCHEME_TYPE, url12 + 10, 4, 808 },
|
||||||
|
{ url13, S_OK, WS_URL_SOAPUDP_SCHEME_TYPE, url13 + 11, 4, 65535 },
|
||||||
|
{ url14, S_OK, WS_URL_NETPIPE_SCHEME_TYPE, url14 + 11, 4, 65535 },
|
||||||
|
{ url15, WS_E_INVALID_FORMAT },
|
||||||
|
{ url16, WS_E_INVALID_FORMAT },
|
||||||
|
{ url17, WS_E_INVALID_FORMAT },
|
||||||
|
{ url18, S_OK, WS_URL_HTTP_SCHEME_TYPE, url18 + 7, 4, 80, NULL, 0, url18 + 11, 1 },
|
||||||
|
{ url19, S_OK, WS_URL_HTTP_SCHEME_TYPE, url19 + 7, 4, 80, NULL, 0, url19 + 12, 1 },
|
||||||
|
{ url20, WS_E_INVALID_FORMAT },
|
||||||
|
{ url21, S_OK, WS_URL_HTTP_SCHEME_TYPE, url21 + 7, 4, 80, NULL, 0, NULL, 0, url21 + 12, 5 },
|
||||||
|
{ url22, S_OK, WS_URL_HTTP_SCHEME_TYPE, url22 + 7, 4, 80, NULL, 0, NULL, 0, NULL, 0,
|
||||||
|
url22 + 12, 4 },
|
||||||
|
{ url23, S_OK, WS_URL_HTTP_SCHEME_TYPE, host2, 6, 80 },
|
||||||
|
{ url24, S_OK, WS_URL_HTTP_SCHEME_TYPE, url24 + 7, 4, 80, NULL, 0, path2, 7 },
|
||||||
|
{ url25, S_OK, WS_URL_HTTP_SCHEME_TYPE, url24 + 7, 4, 80, NULL, 0, NULL, 0, query2, 7 },
|
||||||
|
{ url26, S_OK, WS_URL_HTTP_SCHEME_TYPE, url24 + 7, 4, 80, NULL, 0, NULL, 0, NULL, 0, frag2, 6 },
|
||||||
|
};
|
||||||
|
WS_HEAP *heap;
|
||||||
|
WS_STRING str;
|
||||||
|
WS_HTTP_URL *url;
|
||||||
|
HRESULT hr;
|
||||||
|
UINT i;
|
||||||
|
|
||||||
|
hr = WsCreateHeap( 1 << 16, 0, NULL, 0, &heap, NULL );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
|
||||||
|
hr = WsDecodeUrl( NULL, 0, heap, (WS_URL **)&url, NULL );
|
||||||
|
ok( hr == E_INVALIDARG, "got %08x\n", hr );
|
||||||
|
|
||||||
|
str.chars = NULL;
|
||||||
|
str.length = 0;
|
||||||
|
hr = WsDecodeUrl( &str, 0, heap, (WS_URL **)&url, NULL );
|
||||||
|
ok( hr == WS_E_INVALID_FORMAT, "got %08x\n", hr );
|
||||||
|
|
||||||
|
str.chars = url1;
|
||||||
|
str.length = lstrlenW( url1 );
|
||||||
|
hr = WsDecodeUrl( &str, 0, NULL, (WS_URL **)&url, NULL );
|
||||||
|
ok( hr == E_INVALIDARG, "got %08x\n", hr );
|
||||||
|
|
||||||
|
for (i = 0; i < sizeof(tests)/sizeof(tests[0]); i++)
|
||||||
|
{
|
||||||
|
static const WCHAR netpipe[] = {'n','e','t','.','p','i','p','e'};
|
||||||
|
|
||||||
|
str.length = lstrlenW( tests[i].str );
|
||||||
|
str.chars = tests[i].str;
|
||||||
|
url = NULL;
|
||||||
|
hr = WsDecodeUrl( &str, 0, heap, (WS_URL **)&url, NULL );
|
||||||
|
ok( hr == tests[i].hr ||
|
||||||
|
broken(hr == WS_E_INVALID_FORMAT && str.length >= 8 && !memcmp(netpipe, str.chars, 8)),
|
||||||
|
"%u: got %08x\n", i, hr );
|
||||||
|
if (hr != S_OK) continue;
|
||||||
|
|
||||||
|
ok( url->url.scheme == tests[i].scheme, "%u: got %u\n", i, url->url.scheme );
|
||||||
|
ok( url->port == tests[i].port, "%u: got %u\n", i, url->port );
|
||||||
|
|
||||||
|
if (tests[i].host)
|
||||||
|
{
|
||||||
|
ok( url->host.length == tests[i].host_len, "%u: got %u\n", i, url->host.length );
|
||||||
|
ok( !memcmp( url->host.chars, tests[i].host, url->host.length * sizeof(WCHAR) ),
|
||||||
|
"%u: got %s\n", i, wine_dbgstr_wn(url->host.chars, url->host.length) );
|
||||||
|
}
|
||||||
|
else ok( !url->host.length, "%u: got %u\n", i, url->host.length );
|
||||||
|
|
||||||
|
if (tests[i].port_str)
|
||||||
|
{
|
||||||
|
ok( url->portAsString.length == tests[i].port_len, "%u: got %u\n", i, url->portAsString.length );
|
||||||
|
ok( !memcmp( url->portAsString.chars, tests[i].port_str, url->portAsString.length * sizeof(WCHAR) ),
|
||||||
|
"%u: got %s\n", i, wine_dbgstr_wn(url->portAsString.chars, url->portAsString.length) );
|
||||||
|
}
|
||||||
|
else ok( !url->portAsString.length, "%u: got %u\n", i, url->portAsString.length );
|
||||||
|
|
||||||
|
if (tests[i].path)
|
||||||
|
{
|
||||||
|
ok( url->path.length == tests[i].path_len, "%u: got %u\n", i, url->path.length );
|
||||||
|
ok( !memcmp( url->path.chars, tests[i].path, url->path.length * sizeof(WCHAR) ),
|
||||||
|
"%u: got %s\n", i, wine_dbgstr_wn(url->path.chars, url->path.length) );
|
||||||
|
}
|
||||||
|
else ok( !url->path.length, "%u: got %u\n", i, url->path.length );
|
||||||
|
|
||||||
|
if (tests[i].query)
|
||||||
|
{
|
||||||
|
ok( url->query.length == tests[i].query_len, "%u: got %u\n", i, url->query.length );
|
||||||
|
ok( !memcmp( url->query.chars, tests[i].query, url->query.length * sizeof(WCHAR) ),
|
||||||
|
"%u: got %s\n", i, wine_dbgstr_wn(url->query.chars, url->query.length) );
|
||||||
|
}
|
||||||
|
else ok( !url->query.length, "%u: got %u\n", i, url->query.length );
|
||||||
|
|
||||||
|
if (tests[i].fragment)
|
||||||
|
{
|
||||||
|
ok( url->fragment.length == tests[i].fragment_len, "%u: got %u\n", i, url->fragment.length );
|
||||||
|
ok( !memcmp( url->fragment.chars, tests[i].fragment, url->fragment.length * sizeof(WCHAR) ),
|
||||||
|
"%u: got %s\n", i, wine_dbgstr_wn(url->fragment.chars, url->fragment.length) );
|
||||||
|
}
|
||||||
|
else ok( !url->fragment.length, "%u: got %u\n", i, url->fragment.length );
|
||||||
|
}
|
||||||
|
|
||||||
|
WsFreeHeap( heap );
|
||||||
|
}
|
||||||
|
|
||||||
|
START_TEST(url)
|
||||||
|
{
|
||||||
|
test_WsDecodeUrl();
|
||||||
|
}
|
|
@ -0,0 +1,214 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2016 Hans Leidekker for CodeWeavers
|
||||||
|
*
|
||||||
|
* This library is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU Lesser General Public
|
||||||
|
* License as published by the Free Software Foundation; either
|
||||||
|
* version 2.1 of the License, or (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This library is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||||
|
* Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public
|
||||||
|
* License along with this library; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <stdarg.h>
|
||||||
|
|
||||||
|
#include "windef.h"
|
||||||
|
#include "winbase.h"
|
||||||
|
#include "winuser.h"
|
||||||
|
#include "webservices.h"
|
||||||
|
|
||||||
|
#include "wine/debug.h"
|
||||||
|
#include "wine/list.h"
|
||||||
|
#include "wine/unicode.h"
|
||||||
|
#include "webservices_private.h"
|
||||||
|
|
||||||
|
WINE_DEFAULT_DEBUG_CHANNEL(webservices);
|
||||||
|
|
||||||
|
static const WCHAR http[] = {'h','t','t','p'};
|
||||||
|
static const WCHAR https[] = {'h','t','t','p','s'};
|
||||||
|
static const WCHAR nettcp[] = {'n','e','t','.','t','c','p'};
|
||||||
|
static const WCHAR soapudp[] = {'s','o','a','p','.','u','d','p'};
|
||||||
|
static const WCHAR netpipe[] = {'n','e','t','.','p','i','p','e'};
|
||||||
|
|
||||||
|
static WS_URL_SCHEME_TYPE scheme_type( const WCHAR *str, ULONG len )
|
||||||
|
{
|
||||||
|
if (len == sizeof(http)/sizeof(http[0]) && !memicmpW( str, http, sizeof(http)/sizeof(http[0]) ))
|
||||||
|
return WS_URL_HTTP_SCHEME_TYPE;
|
||||||
|
|
||||||
|
if (len == sizeof(https)/sizeof(https[0]) && !memicmpW( str, https, sizeof(https)/sizeof(https[0]) ))
|
||||||
|
return WS_URL_HTTPS_SCHEME_TYPE;
|
||||||
|
|
||||||
|
if (len == sizeof(nettcp)/sizeof(nettcp[0]) && !memicmpW( str, nettcp, sizeof(nettcp)/sizeof(nettcp[0]) ))
|
||||||
|
return WS_URL_NETTCP_SCHEME_TYPE;
|
||||||
|
|
||||||
|
if (len == sizeof(soapudp)/sizeof(soapudp[0]) && !memicmpW( str, soapudp, sizeof(soapudp)/sizeof(soapudp[0]) ))
|
||||||
|
return WS_URL_SOAPUDP_SCHEME_TYPE;
|
||||||
|
|
||||||
|
if (len == sizeof(netpipe)/sizeof(netpipe[0]) && !memicmpW( str, netpipe, sizeof(netpipe)/sizeof(netpipe[0]) ))
|
||||||
|
return WS_URL_NETPIPE_SCHEME_TYPE;
|
||||||
|
|
||||||
|
return ~0u;
|
||||||
|
}
|
||||||
|
|
||||||
|
static USHORT default_port( WS_URL_SCHEME_TYPE scheme )
|
||||||
|
{
|
||||||
|
switch (scheme)
|
||||||
|
{
|
||||||
|
case WS_URL_HTTP_SCHEME_TYPE: return 80;
|
||||||
|
case WS_URL_HTTPS_SCHEME_TYPE: return 443;
|
||||||
|
case WS_URL_NETTCP_SCHEME_TYPE: return 808;
|
||||||
|
case WS_URL_SOAPUDP_SCHEME_TYPE:
|
||||||
|
case WS_URL_NETPIPE_SCHEME_TYPE: return 65535;
|
||||||
|
default:
|
||||||
|
ERR( "unhandled scheme %u\n", scheme );
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static WCHAR *url_decode( WCHAR *str, ULONG len, WS_HEAP *heap, ULONG *ret_len )
|
||||||
|
{
|
||||||
|
WCHAR *p = str, *q, *ret;
|
||||||
|
BOOL decode = FALSE;
|
||||||
|
ULONG i, val;
|
||||||
|
|
||||||
|
*ret_len = len;
|
||||||
|
for (i = 0; i < len; i++, p++)
|
||||||
|
{
|
||||||
|
if ((len - i) < 3) break;
|
||||||
|
if (p[0] == '%' && isxdigitW( p[1] ) && isxdigitW( p[2] ))
|
||||||
|
{
|
||||||
|
decode = TRUE;
|
||||||
|
*ret_len -= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (!decode) return str;
|
||||||
|
|
||||||
|
if (!(q = ret = ws_alloc( heap, *ret_len * sizeof(WCHAR) ))) return NULL;
|
||||||
|
p = str;
|
||||||
|
while (len)
|
||||||
|
{
|
||||||
|
if (len >= 3 && p[0] == '%' && isxdigitW( p[1] ) && isxdigitW( p[2] ))
|
||||||
|
{
|
||||||
|
if (p[1] >= '0' && p[1] <= '9') val = (p[1] - '0') * 16;
|
||||||
|
else if (p[1] >= 'a' && p[1] <= 'f') val = (p[1] - 'a') * 16;
|
||||||
|
else val = (p[1] - 'A') * 16;
|
||||||
|
|
||||||
|
if (p[2] >= '0' && p[2] <= '9') val += p[2] - '0';
|
||||||
|
else if (p[1] >= 'a' && p[1] <= 'f') val += p[2] - 'a';
|
||||||
|
else val += p[1] - 'A';
|
||||||
|
|
||||||
|
*q++ = val;
|
||||||
|
p += 3;
|
||||||
|
len -= 3;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
*q++ = *p++;
|
||||||
|
len -= 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**************************************************************************
|
||||||
|
* WsDecodeUrl [webservices.@]
|
||||||
|
*/
|
||||||
|
HRESULT WINAPI WsDecodeUrl( const WS_STRING *str, ULONG flags, WS_HEAP *heap, WS_URL **ret,
|
||||||
|
WS_ERROR *error )
|
||||||
|
{
|
||||||
|
HRESULT hr = WS_E_QUOTA_EXCEEDED;
|
||||||
|
WCHAR *p, *q, *decoded = NULL;
|
||||||
|
WS_HTTP_URL *url = NULL;
|
||||||
|
ULONG len, port = 0;
|
||||||
|
|
||||||
|
TRACE( "%s %08x %p %p %p\n", str ? debugstr_wn(str->chars, str->length) : "null", flags,
|
||||||
|
heap, ret, error );
|
||||||
|
if (error) FIXME( "ignoring error parameter\n" );
|
||||||
|
|
||||||
|
if (!str || !heap) return E_INVALIDARG;
|
||||||
|
if (!str->length) return WS_E_INVALID_FORMAT;
|
||||||
|
if (flags)
|
||||||
|
{
|
||||||
|
FIXME( "unimplemented flags %08x\n", flags );
|
||||||
|
return E_NOTIMPL;
|
||||||
|
}
|
||||||
|
if (!(decoded = url_decode( str->chars, str->length, heap, &len )) ||
|
||||||
|
!(url = ws_alloc( heap, sizeof(*url) ))) goto error;
|
||||||
|
|
||||||
|
hr = WS_E_INVALID_FORMAT;
|
||||||
|
|
||||||
|
p = q = decoded;
|
||||||
|
while (len && *q != ':') { q++; len--; };
|
||||||
|
if (*q != ':') goto error;
|
||||||
|
if ((url->url.scheme = scheme_type( p, q - p )) == ~0u) goto error;
|
||||||
|
|
||||||
|
if (!--len || *++q != '/') goto error;
|
||||||
|
if (!--len || *++q != '/') goto error;
|
||||||
|
|
||||||
|
p = ++q; len--;
|
||||||
|
while (len && *q != '/' && *q != ':' && *q != '?' && *q != '#') { q++; len--; };
|
||||||
|
if (q == p) goto error;
|
||||||
|
url->host.length = q - p;
|
||||||
|
url->host.chars = p;
|
||||||
|
|
||||||
|
if (len && *q == ':')
|
||||||
|
{
|
||||||
|
p = ++q; len--;
|
||||||
|
while (len && isdigitW( *q ))
|
||||||
|
{
|
||||||
|
if ((port = port * 10 + *q - '0') > 65535) goto error;
|
||||||
|
q++; len--;
|
||||||
|
};
|
||||||
|
url->port = port;
|
||||||
|
url->portAsString.length = q - p;
|
||||||
|
url->portAsString.chars = p;
|
||||||
|
}
|
||||||
|
if (!port)
|
||||||
|
{
|
||||||
|
url->port = default_port( url->url.scheme );
|
||||||
|
url->portAsString.length = 0;
|
||||||
|
url->portAsString.chars = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (len && *q == '/')
|
||||||
|
{
|
||||||
|
p = q;
|
||||||
|
while (len && *q != '?') { q++; len--; };
|
||||||
|
url->path.length = q - p;
|
||||||
|
url->path.chars = p;
|
||||||
|
}
|
||||||
|
else url->path.length = 0;
|
||||||
|
|
||||||
|
if (len && *q == '?')
|
||||||
|
{
|
||||||
|
p = ++q; len--;
|
||||||
|
while (len && *q != '#') { q++; len--; };
|
||||||
|
url->query.length = q - p;
|
||||||
|
url->query.chars = p;
|
||||||
|
}
|
||||||
|
else url->query.length = 0;
|
||||||
|
|
||||||
|
if (len && *q == '#')
|
||||||
|
{
|
||||||
|
p = ++q; len--;
|
||||||
|
while (len && *q != '#') { q++; len--; };
|
||||||
|
url->fragment.length = q - p;
|
||||||
|
url->fragment.chars = p;
|
||||||
|
}
|
||||||
|
else url->fragment.length = 0;
|
||||||
|
|
||||||
|
*ret = (WS_URL *)url;
|
||||||
|
return S_OK;
|
||||||
|
|
||||||
|
error:
|
||||||
|
if (decoded != str->chars) ws_free( heap, decoded );
|
||||||
|
ws_free( heap, url );
|
||||||
|
return hr;
|
||||||
|
}
|
|
@ -38,7 +38,7 @@
|
||||||
@ stdcall WsCreateXmlBuffer(ptr ptr long ptr ptr)
|
@ stdcall WsCreateXmlBuffer(ptr ptr long ptr ptr)
|
||||||
@ stub WsCreateXmlSecurityToken
|
@ stub WsCreateXmlSecurityToken
|
||||||
@ stdcall WsDateTimeToFileTime(ptr ptr ptr)
|
@ stdcall WsDateTimeToFileTime(ptr ptr ptr)
|
||||||
@ stub WsDecodeUrl
|
@ stdcall WsDecodeUrl(ptr long ptr ptr ptr)
|
||||||
@ stub WsEncodeUrl
|
@ stub WsEncodeUrl
|
||||||
@ stub WsEndReaderCanonicalization
|
@ stub WsEndReaderCanonicalization
|
||||||
@ stub WsEndWriterCanonicalization
|
@ stub WsEndWriterCanonicalization
|
||||||
|
|
|
@ -59,6 +59,12 @@ typedef struct _WS_CALL_PROPERTY WS_CALL_PROPERTY;
|
||||||
typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION;
|
typedef struct _WS_DOUBLE_DESCRIPTION WS_DOUBLE_DESCRIPTION;
|
||||||
typedef struct _WS_DATETIME WS_DATETIME;
|
typedef struct _WS_DATETIME WS_DATETIME;
|
||||||
typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION;
|
typedef struct _WS_DATETIME_DESCRIPTION WS_DATETIME_DESCRIPTION;
|
||||||
|
typedef struct _WS_URL WS_URL;
|
||||||
|
typedef struct _WS_HTTP_URL WS_HTTP_URL;
|
||||||
|
typedef struct _WS_HTTPS_URL WS_HTTPS_URL;
|
||||||
|
typedef struct _WS_NETTCP_URL WS_NETTCP_URL;
|
||||||
|
typedef struct _WS_SOAPUDP_URL WS_SOAPUDP_URL;
|
||||||
|
typedef struct _WS_NETPIPE_URL WS_NETPIPE_URL;
|
||||||
|
|
||||||
struct _WS_STRUCT_DESCRIPTION;
|
struct _WS_STRUCT_DESCRIPTION;
|
||||||
struct _WS_XML_STRING;
|
struct _WS_XML_STRING;
|
||||||
|
@ -1007,12 +1013,71 @@ struct _WS_DATETIME_DESCRIPTION {
|
||||||
WS_DATETIME maxValue;
|
WS_DATETIME maxValue;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
typedef enum {
|
||||||
|
WS_URL_HTTP_SCHEME_TYPE,
|
||||||
|
WS_URL_HTTPS_SCHEME_TYPE,
|
||||||
|
WS_URL_NETTCP_SCHEME_TYPE,
|
||||||
|
WS_URL_SOAPUDP_SCHEME_TYPE,
|
||||||
|
WS_URL_NETPIPE_SCHEME_TYPE
|
||||||
|
} WS_URL_SCHEME_TYPE;
|
||||||
|
|
||||||
|
enum {
|
||||||
|
WS_URL_FLAGS_ALLOW_HOST_WILDCARDS = 0x1,
|
||||||
|
WS_URL_FLAGS_NO_PATH_COLLAPSE = 0x2,
|
||||||
|
WS_URL_FLAGS_ZERO_TERMINATE = 0x4
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WS_URL {
|
||||||
|
WS_URL_SCHEME_TYPE scheme;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WS_HTTP_URL {
|
||||||
|
WS_URL url;
|
||||||
|
WS_STRING host;
|
||||||
|
USHORT port;
|
||||||
|
WS_STRING portAsString;
|
||||||
|
WS_STRING path;
|
||||||
|
WS_STRING query;
|
||||||
|
WS_STRING fragment;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WS_HTTPS_URL {
|
||||||
|
WS_URL url;
|
||||||
|
WS_STRING host;
|
||||||
|
USHORT port;
|
||||||
|
WS_STRING portAsString;
|
||||||
|
WS_STRING path;
|
||||||
|
WS_STRING query;
|
||||||
|
WS_STRING fragment;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WS_SOAPUDP_URL {
|
||||||
|
WS_URL url;
|
||||||
|
WS_STRING host;
|
||||||
|
USHORT port;
|
||||||
|
WS_STRING portAsString;
|
||||||
|
WS_STRING path;
|
||||||
|
WS_STRING query;
|
||||||
|
WS_STRING fragment;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct _WS_NETPIPE_URL {
|
||||||
|
WS_URL url;
|
||||||
|
WS_STRING host;
|
||||||
|
USHORT port;
|
||||||
|
WS_STRING portAsString;
|
||||||
|
WS_STRING path;
|
||||||
|
WS_STRING query;
|
||||||
|
WS_STRING fragment;
|
||||||
|
};
|
||||||
|
|
||||||
HRESULT WINAPI WsAlloc(WS_HEAP*, SIZE_T, void**, WS_ERROR*);
|
HRESULT WINAPI WsAlloc(WS_HEAP*, SIZE_T, void**, WS_ERROR*);
|
||||||
HRESULT WINAPI WsCall(WS_SERVICE_PROXY*, const WS_OPERATION_DESCRIPTION*, const void**,
|
HRESULT WINAPI WsCall(WS_SERVICE_PROXY*, const WS_OPERATION_DESCRIPTION*, const void**,
|
||||||
WS_HEAP*, const WS_CALL_PROPERTY*, const ULONG, const WS_ASYNC_CONTEXT*,
|
WS_HEAP*, const WS_CALL_PROPERTY*, const ULONG, const WS_ASYNC_CONTEXT*,
|
||||||
WS_ERROR*);
|
WS_ERROR*);
|
||||||
HRESULT WINAPI WsCloseChannel(WS_CHANNEL*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
HRESULT WINAPI WsCloseChannel(WS_CHANNEL*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsCloseServiceProxy(WS_SERVICE_PROXY*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
HRESULT WINAPI WsCloseServiceProxy(WS_SERVICE_PROXY*, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
||||||
|
HRESULT WINAPI WsCombineUrl(const WS_STRING*, const WS_STRING*, ULONG, WS_HEAP*, WS_STRING*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsCreateChannel(WS_CHANNEL_TYPE, WS_CHANNEL_BINDING, const WS_CHANNEL_PROPERTY*,
|
HRESULT WINAPI WsCreateChannel(WS_CHANNEL_TYPE, WS_CHANNEL_BINDING, const WS_CHANNEL_PROPERTY*,
|
||||||
ULONG, const WS_SECURITY_DESCRIPTION*, WS_CHANNEL**, WS_ERROR*);
|
ULONG, const WS_SECURITY_DESCRIPTION*, WS_CHANNEL**, WS_ERROR*);
|
||||||
HRESULT WINAPI WsCreateError(const WS_ERROR_PROPERTY*, ULONG, WS_ERROR**);
|
HRESULT WINAPI WsCreateError(const WS_ERROR_PROPERTY*, ULONG, WS_ERROR**);
|
||||||
|
@ -1034,6 +1099,8 @@ HRESULT WINAPI WsCreateWriter(const WS_XML_WRITER_PROPERTY*, ULONG, WS_XML_WRITE
|
||||||
HRESULT WINAPI WsCreateXmlBuffer(WS_HEAP*, const WS_XML_BUFFER_PROPERTY*, ULONG, WS_XML_BUFFER**,
|
HRESULT WINAPI WsCreateXmlBuffer(WS_HEAP*, const WS_XML_BUFFER_PROPERTY*, ULONG, WS_XML_BUFFER**,
|
||||||
WS_ERROR*);
|
WS_ERROR*);
|
||||||
HRESULT WINAPI WsDateTimeToFileTime(const WS_DATETIME*, FILETIME*, WS_ERROR*);
|
HRESULT WINAPI WsDateTimeToFileTime(const WS_DATETIME*, FILETIME*, WS_ERROR*);
|
||||||
|
HRESULT WINAPI WsDecodeUrl(const WS_STRING*, ULONG, WS_HEAP*, WS_URL**, WS_ERROR*);
|
||||||
|
HRESULT WINAPI WsEncodeUrl(const WS_URL*, ULONG, WS_HEAP*, WS_STRING*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsFileTimeToDateTime(const FILETIME*, WS_DATETIME*, WS_ERROR*);
|
HRESULT WINAPI WsFileTimeToDateTime(const FILETIME*, WS_DATETIME*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsFillReader(WS_XML_READER*, ULONG, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
HRESULT WINAPI WsFillReader(WS_XML_READER*, ULONG, const WS_ASYNC_CONTEXT*, WS_ERROR*);
|
||||||
HRESULT WINAPI WsFindAttribute(WS_XML_READER*, const WS_XML_STRING*, const WS_XML_STRING*, BOOL,
|
HRESULT WINAPI WsFindAttribute(WS_XML_READER*, const WS_XML_STRING*, const WS_XML_STRING*, BOOL,
|
||||||
|
|
Loading…
Reference in New Issue