winhttp: Convert string data to UTF-8 and add a corresponding content type header.
This commit is contained in:
parent
b9e828df0a
commit
3c9d356bc4
|
@ -2217,6 +2217,7 @@ static void free_request( struct winhttp_request *request )
|
||||||
heap_free( (WCHAR *)request->proxy.lpszProxyBypass );
|
heap_free( (WCHAR *)request->proxy.lpszProxyBypass );
|
||||||
heap_free( request->buffer );
|
heap_free( request->buffer );
|
||||||
heap_free( request->verb );
|
heap_free( request->verb );
|
||||||
|
VariantClear( &request->data );
|
||||||
}
|
}
|
||||||
|
|
||||||
static ULONG WINAPI winhttp_request_Release(
|
static ULONG WINAPI winhttp_request_Release(
|
||||||
|
@ -2860,6 +2861,20 @@ static DWORD request_set_parameters( struct winhttp_request *request )
|
||||||
return ERROR_SUCCESS;
|
return ERROR_SUCCESS;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void request_set_utf8_content_type( struct winhttp_request *request )
|
||||||
|
{
|
||||||
|
static const WCHAR fmtW[] = {'%','s',':',' ','%','s',0};
|
||||||
|
static const WCHAR text_plainW[] = {'t','e','x','t','/','p','l','a','i','n',0};
|
||||||
|
static const WCHAR charset_utf8W[] = {'c','h','a','r','s','e','t','=','u','t','f','-','8',0};
|
||||||
|
WCHAR headerW[64];
|
||||||
|
int len;
|
||||||
|
|
||||||
|
len = sprintfW( headerW, fmtW, attr_content_type, text_plainW );
|
||||||
|
WinHttpAddRequestHeaders( request->hrequest, headerW, len, WINHTTP_ADDREQ_FLAG_ADD_IF_NEW );
|
||||||
|
len = sprintfW( headerW, fmtW, attr_content_type, charset_utf8W );
|
||||||
|
WinHttpAddRequestHeaders( request->hrequest, headerW, len, WINHTTP_ADDREQ_FLAG_COALESCE_WITH_SEMICOLON );
|
||||||
|
}
|
||||||
|
|
||||||
static HRESULT request_send( struct winhttp_request *request )
|
static HRESULT request_send( struct winhttp_request *request )
|
||||||
{
|
{
|
||||||
SAFEARRAY *sa = NULL;
|
SAFEARRAY *sa = NULL;
|
||||||
|
@ -2871,24 +2886,47 @@ static HRESULT request_send( struct winhttp_request *request )
|
||||||
DWORD err;
|
DWORD err;
|
||||||
|
|
||||||
if ((err = request_set_parameters( request ))) return HRESULT_FROM_WIN32( err );
|
if ((err = request_set_parameters( request ))) return HRESULT_FROM_WIN32( err );
|
||||||
VariantInit( &data );
|
if (strcmpW( request->verb, getW ))
|
||||||
if (strcmpW( request->verb, getW ) && VariantChangeType( &data, &request->data, 0, VT_ARRAY|VT_UI1 ) == S_OK)
|
|
||||||
{
|
{
|
||||||
SAFEARRAY *sa = V_ARRAY( &data );
|
VariantInit( &data );
|
||||||
if ((hr = SafeArrayAccessData( sa, (void **)&ptr )) != S_OK) return hr;
|
if (V_VT( &request->data ) == VT_BSTR)
|
||||||
if ((hr = SafeArrayGetUBound( sa, 1, &size ) != S_OK))
|
|
||||||
{
|
{
|
||||||
SafeArrayUnaccessData( sa );
|
UINT i, cp = CP_ACP;
|
||||||
return hr;
|
const WCHAR *str = V_BSTR( &request->data );
|
||||||
|
int len = strlenW( str );
|
||||||
|
|
||||||
|
for (i = 0; i < len; i++)
|
||||||
|
{
|
||||||
|
if (str[i] > 127)
|
||||||
|
{
|
||||||
|
cp = CP_UTF8;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
size = WideCharToMultiByte( cp, 0, str, len, NULL, 0, NULL, NULL );
|
||||||
|
if (!(ptr = heap_alloc( size ))) return E_OUTOFMEMORY;
|
||||||
|
WideCharToMultiByte( cp, 0, str, len, ptr, size, NULL, NULL );
|
||||||
|
if (cp == CP_UTF8) request_set_utf8_content_type( request );
|
||||||
|
}
|
||||||
|
else if (VariantChangeType( &data, &request->data, 0, VT_ARRAY|VT_UI1 ) == S_OK)
|
||||||
|
{
|
||||||
|
sa = V_ARRAY( &data );
|
||||||
|
if ((hr = SafeArrayAccessData( sa, (void **)&ptr )) != S_OK) return hr;
|
||||||
|
if ((hr = SafeArrayGetUBound( sa, 1, &size ) != S_OK))
|
||||||
|
{
|
||||||
|
SafeArrayUnaccessData( sa );
|
||||||
|
return hr;
|
||||||
|
}
|
||||||
|
size++;
|
||||||
}
|
}
|
||||||
size++;
|
|
||||||
}
|
}
|
||||||
wait_set_status_callback( request, WINHTTP_CALLBACK_STATUS_REQUEST_SENT );
|
wait_set_status_callback( request, WINHTTP_CALLBACK_STATUS_REQUEST_SENT );
|
||||||
if (!(ret = WinHttpSendRequest( request->hrequest, NULL, 0, ptr, size, size, 0 )))
|
if (!(ret = WinHttpSendRequest( request->hrequest, NULL, 0, ptr, size, size, 0 )))
|
||||||
{
|
{
|
||||||
err = get_last_error();
|
err = get_last_error();
|
||||||
}
|
}
|
||||||
if (sa && (hr = SafeArrayUnaccessData( sa )) != S_OK) return hr;
|
if (!sa) heap_free( ptr );
|
||||||
|
else if ((hr = SafeArrayUnaccessData( sa )) != S_OK) return hr;
|
||||||
if (!ret) return HRESULT_FROM_WIN32( err );
|
if (!ret) return HRESULT_FROM_WIN32( err );
|
||||||
if ((err = wait_for_completion( request ))) return HRESULT_FROM_WIN32( err );
|
if ((err = wait_for_completion( request ))) return HRESULT_FROM_WIN32( err );
|
||||||
|
|
||||||
|
@ -2914,7 +2952,7 @@ static HRESULT WINAPI winhttp_request_Send(
|
||||||
VARIANT body )
|
VARIANT body )
|
||||||
{
|
{
|
||||||
struct winhttp_request *request = impl_from_IWinHttpRequest( iface );
|
struct winhttp_request *request = impl_from_IWinHttpRequest( iface );
|
||||||
HRESULT hr = S_OK;
|
HRESULT hr;
|
||||||
|
|
||||||
TRACE("%p, %s\n", request, debugstr_variant(&body));
|
TRACE("%p, %s\n", request, debugstr_variant(&body));
|
||||||
|
|
||||||
|
@ -2929,7 +2967,9 @@ static HRESULT WINAPI winhttp_request_Send(
|
||||||
LeaveCriticalSection( &request->cs );
|
LeaveCriticalSection( &request->cs );
|
||||||
return S_OK;
|
return S_OK;
|
||||||
}
|
}
|
||||||
request->data = body;
|
VariantClear( &request->data );
|
||||||
|
if ((hr = VariantCopyInd( &request->data, &body )) != S_OK) return hr;
|
||||||
|
|
||||||
if (request->wait) /* async request */
|
if (request->wait) /* async request */
|
||||||
{
|
{
|
||||||
if (!(request->thread = CreateThread( NULL, 0, send_and_receive_proc, request, 0, NULL )))
|
if (!(request->thread = CreateThread( NULL, 0, send_and_receive_proc, request, 0, NULL )))
|
||||||
|
|
|
@ -2111,17 +2111,22 @@ static void test_IWinHttpRequest(void)
|
||||||
static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
|
static const WCHAR passwordW[] = {'p','a','s','s','w','o','r','d',0};
|
||||||
static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
|
static const WCHAR url1W[] = {'h','t','t','p',':','/','/','w','i','n','e','h','q','.','o','r','g',0};
|
||||||
static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
|
static const WCHAR url2W[] = {'w','i','n','e','h','q','.','o','r','g',0};
|
||||||
|
static const WCHAR url3W[] = {'h','t','t','p',':','/','/','c','r','o','s','s','o','v','e','r','.',
|
||||||
|
'c','o','d','e','w','e','a','v','e','r','s','.','c','o','m','/',
|
||||||
|
'p','o','s','t','t','e','s','t','.','p','h','p',0};
|
||||||
static const WCHAR method1W[] = {'G','E','T',0};
|
static const WCHAR method1W[] = {'G','E','T',0};
|
||||||
static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
|
static const WCHAR method2W[] = {'I','N','V','A','L','I','D',0};
|
||||||
|
static const WCHAR method3W[] = {'P','O','S','T',0};
|
||||||
static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
|
static const WCHAR proxy_serverW[] = {'p','r','o','x','y','s','e','r','v','e','r',0};
|
||||||
static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
|
static const WCHAR bypas_listW[] = {'b','y','p','a','s','s','l','i','s','t',0};
|
||||||
static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
|
static const WCHAR connectionW[] = {'C','o','n','n','e','c','t','i','o','n',0};
|
||||||
static const WCHAR dateW[] = {'D','a','t','e',0};
|
static const WCHAR dateW[] = {'D','a','t','e',0};
|
||||||
|
static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',128,0};
|
||||||
HRESULT hr;
|
HRESULT hr;
|
||||||
IWinHttpRequest *req;
|
IWinHttpRequest *req;
|
||||||
BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
|
BSTR method, url, username, password, response = NULL, status_text = NULL, headers = NULL;
|
||||||
BSTR date, today, connection, value = NULL;
|
BSTR date, today, connection, value = NULL;
|
||||||
VARIANT async, empty, timeout, body, proxy_server, bypass_list;
|
VARIANT async, empty, timeout, body, proxy_server, bypass_list, data;
|
||||||
VARIANT_BOOL succeeded;
|
VARIANT_BOOL succeeded;
|
||||||
LONG status;
|
LONG status;
|
||||||
WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
|
WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
|
||||||
|
@ -2140,6 +2145,20 @@ static void test_IWinHttpRequest(void)
|
||||||
V_VT( &async ) = VT_BOOL;
|
V_VT( &async ) = VT_BOOL;
|
||||||
V_BOOL( &async ) = VARIANT_FALSE;
|
V_BOOL( &async ) = VARIANT_FALSE;
|
||||||
|
|
||||||
|
method = SysAllocString( method3W );
|
||||||
|
url = SysAllocString( url3W );
|
||||||
|
hr = IWinHttpRequest_Open( req, method, url, async );
|
||||||
|
ok( hr == S_OK, "got %08x\n", hr );
|
||||||
|
SysFreeString( method );
|
||||||
|
SysFreeString( url );
|
||||||
|
|
||||||
|
V_VT( &data ) = VT_BSTR;
|
||||||
|
V_BSTR( &data ) = SysAllocString( test_dataW );
|
||||||
|
hr = IWinHttpRequest_Send( req, data );
|
||||||
|
ok( hr == S_OK || broken(hr == HRESULT_FROM_WIN32(ERROR_WINHTTP_INVALID_SERVER_RESPONSE)),
|
||||||
|
"got %08x\n", hr );
|
||||||
|
SysFreeString( V_BSTR( &data ) );
|
||||||
|
|
||||||
hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
|
hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
|
||||||
ok( hr == E_INVALIDARG, "got %08x\n", hr );
|
ok( hr == E_INVALIDARG, "got %08x\n", hr );
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue