[3/3] winhttp: Convert string data to UTF-8 and add a corresponding content type header.

Hans Leidekker hans at codeweavers.com
Wed Nov 9 08:05:31 CST 2011


Fixes http://bugs.winehq.org/show_bug.cgi?id=29004
---
 dlls/winhttp/request.c       |   40 +++++++++++++++++++++++++++++++---------
 dlls/winhttp/tests/winhttp.c |   20 +++++++++++++++++++-
 2 files changed, 50 insertions(+), 10 deletions(-)

diff --git a/dlls/winhttp/request.c b/dlls/winhttp/request.c
index 51c433e..2dd612f 100644
--- a/dlls/winhttp/request.c
+++ b/dlls/winhttp/request.c
@@ -2871,24 +2871,46 @@ static HRESULT request_send( struct winhttp_request *request )
     DWORD err;
 
     if ((err = request_set_parameters( request ))) return HRESULT_FROM_WIN32( err );
-    VariantInit( &data );
-    if (strcmpW( request->verb, getW ) && VariantChangeType( &data, &request->data, 0, VT_ARRAY|VT_UI1 ) == S_OK)
+    if (strcmpW( request->verb, getW ))
     {
-        SAFEARRAY *sa = V_ARRAY( &data );
-        if ((hr = SafeArrayAccessData( sa, (void **)&ptr )) != S_OK) return hr;
-        if ((hr = SafeArrayGetUBound( sa, 1, &size ) != S_OK))
+        VariantInit( &data );
+        if (V_VT( &request->data ) == VT_BSTR)
         {
-            SafeArrayUnaccessData( sa );
-            return hr;
+            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];
+            const WCHAR *str = V_BSTR( &request->data );
+            int len;
+
+            size = WideCharToMultiByte( CP_UTF8, 0, str, strlenW(str), NULL, 0, NULL, NULL );
+            if (!(ptr = heap_alloc( size ))) return E_OUTOFMEMORY;
+            WideCharToMultiByte( CP_UTF8, 0, str, strlenW(str), ptr, size, NULL, NULL );
+
+            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 );
+        }
+        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 );
     if (!(ret = WinHttpSendRequest( request->hrequest, NULL, 0, ptr, size, size, 0 )))
     {
         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 ((err = wait_for_completion( request ))) return HRESULT_FROM_WIN32( err );
 
diff --git a/dlls/winhttp/tests/winhttp.c b/dlls/winhttp/tests/winhttp.c
index 01b74e3..7c1c755 100644
--- a/dlls/winhttp/tests/winhttp.c
+++ b/dlls/winhttp/tests/winhttp.c
@@ -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 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 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 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 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 dateW[] = {'D','a','t','e',0};
+    static const WCHAR test_dataW[] = {'t','e','s','t','d','a','t','a',235,0};
     HRESULT hr;
     IWinHttpRequest *req;
     BSTR method, url, username, password, response = NULL, status_text = NULL, headers = 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;
     LONG status;
     WCHAR todayW[WINHTTP_TIME_FORMAT_BUFSIZE];
@@ -2140,6 +2145,18 @@ static void test_IWinHttpRequest(void)
     V_VT( &async ) = VT_BOOL;
     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, "got %08x\n", hr );
+
     hr = IWinHttpRequest_Open( req, NULL, NULL, empty );
     ok( hr == E_INVALIDARG, "got %08x\n", hr );
 
@@ -2496,6 +2513,7 @@ static void test_IWinHttpRequest(void)
     SysFreeString( today );
     VariantClear( &proxy_server );
     VariantClear( &bypass_list );
+    VariantClear( &data );
     CoUninitialize();
 }
 
-- 
1.7.5.4






More information about the wine-patches mailing list