From c94ccee16af71d8cfcfa157fc804e4998eb5a71a Mon Sep 17 00:00:00 2001 From: Hans Leidekker Date: Fri, 25 Aug 2017 11:51:40 +0200 Subject: [PATCH] webservices: Create a new HTTP request for each message. Signed-off-by: Hans Leidekker Signed-off-by: Alexandre Julliard --- dlls/webservices/channel.c | 49 +++++++++++++++++++++----------------- dlls/webservices/msg.c | 14 +++++++---- 2 files changed, 36 insertions(+), 27 deletions(-) diff --git a/dlls/webservices/channel.c b/dlls/webservices/channel.c index 09cfd8075e4..3451bea6e20 100644 --- a/dlls/webservices/channel.c +++ b/dlls/webservices/channel.c @@ -113,6 +113,8 @@ struct channel HINTERNET session; HINTERNET connect; HINTERNET request; + WCHAR *path; + DWORD flags; } http; struct { @@ -169,6 +171,9 @@ static void reset_channel( struct channel *channel ) channel->u.http.connect = NULL; WinHttpCloseHandle( channel->u.http.session ); channel->u.http.session = NULL; + heap_free( channel->u.http.path ); + channel->u.http.path = NULL; + channel->u.http.flags = 0; break; case WS_TCP_CHANNEL_BINDING: @@ -587,34 +592,29 @@ static HRESULT connect_channel_http( struct channel *channel ) { static const WCHAR agentW[] = {'M','S','-','W','e','b','S','e','r','v','i','c','e','s','/','1','.','0',0}; - static const WCHAR postW[] = - {'P','O','S','T',0}; - HINTERNET ses = NULL, con = NULL, req = NULL; - WCHAR *path; + HINTERNET ses = NULL, con = NULL; URL_COMPONENTS uc; - DWORD flags = 0; HRESULT hr; - if (channel->u.http.request) return S_OK; + if (channel->u.http.connect) return S_OK; if ((hr = parse_http_url( channel->addr.url.chars, channel->addr.url.length, &uc )) != S_OK) return hr; - if (!uc.dwExtraInfoLength) path = uc.lpszUrlPath; - else if (!(path = heap_alloc( (uc.dwUrlPathLength + uc.dwExtraInfoLength + 1) * sizeof(WCHAR) ))) + if (!(channel->u.http.path = heap_alloc( (uc.dwUrlPathLength + uc.dwExtraInfoLength + 1) * sizeof(WCHAR) ))) { hr = E_OUTOFMEMORY; goto done; } else { - strcpyW( path, uc.lpszUrlPath ); - strcatW( path, uc.lpszExtraInfo ); + strcpyW( channel->u.http.path, uc.lpszUrlPath ); + if (uc.dwExtraInfoLength) strcatW( channel->u.http.path, uc.lpszExtraInfo ); } switch (uc.nScheme) { case INTERNET_SCHEME_HTTP: break; case INTERNET_SCHEME_HTTPS: - flags |= WINHTTP_FLAG_SECURE; + channel->u.http.flags |= WINHTTP_FLAG_SECURE; break; default: @@ -632,29 +632,19 @@ static HRESULT connect_channel_http( struct channel *channel ) hr = HRESULT_FROM_WIN32( GetLastError() ); goto done; } - if (!(req = WinHttpOpenRequest( con, postW, path, NULL, NULL, NULL, flags ))) - { - hr = HRESULT_FROM_WIN32( GetLastError() ); - goto done; - } - - if ((hr = message_insert_http_headers( channel->msg, req )) != S_OK) goto done; channel->u.http.session = ses; channel->u.http.connect = con; - channel->u.http.request = req; done: if (hr != S_OK) { - WinHttpCloseHandle( req ); WinHttpCloseHandle( con ); WinHttpCloseHandle( ses ); } heap_free( uc.lpszHostName ); heap_free( uc.lpszUrlPath ); heap_free( uc.lpszExtraInfo ); - if (path != uc.lpszUrlPath) heap_free( path ); return hr; } @@ -762,7 +752,7 @@ static HRESULT write_message( WS_MESSAGE *handle, WS_XML_WRITER *writer, const W return WsWriteEnvelopeEnd( handle, NULL ); } -static HRESULT send_message_http( HANDLE request, BYTE *data, ULONG len ) +static HRESULT send_message_http( HINTERNET request, BYTE *data, ULONG len ) { if (!WinHttpSendRequest( request, NULL, 0, data, len, len, 0 )) return HRESULT_FROM_WIN32( GetLastError() ); @@ -984,6 +974,14 @@ static HRESULT send_sized_envelope( struct channel *channel, BYTE *data, ULONG l return send_bytes( channel->u.tcp.socket, data, len ); } +static HRESULT open_http_request( struct channel *channel, HINTERNET *req ) +{ + static const WCHAR postW[] = {'P','O','S','T',0}; + if ((*req = WinHttpOpenRequest( channel->u.http.connect, postW, channel->u.http.path, + NULL, NULL, NULL, channel->u.http.flags ))) return S_OK; + return HRESULT_FROM_WIN32( GetLastError() ); +} + static HRESULT send_message( struct channel *channel, WS_MESSAGE *msg ) { WS_XML_WRITER *writer; @@ -999,6 +997,13 @@ static HRESULT send_message( struct channel *channel, WS_MESSAGE *msg ) switch (channel->binding) { case WS_HTTP_CHANNEL_BINDING: + if (channel->u.http.request) + { + WinHttpCloseHandle( channel->u.http.request ); + channel->u.http.request = NULL; + } + if ((hr = open_http_request( channel, &channel->u.http.request )) != S_OK) return hr; + if ((hr = message_insert_http_headers( msg, channel->u.http.request )) != S_OK) return hr; return send_message_http( channel->u.http.request, buf.bytes, buf.length ); case WS_TCP_CHANNEL_BINDING: diff --git a/dlls/webservices/msg.c b/dlls/webservices/msg.c index 02cb22b88fc..d6f01448cb4 100644 --- a/dlls/webservices/msg.c +++ b/dlls/webservices/msg.c @@ -1610,9 +1610,13 @@ HRESULT WINAPI WsRemoveCustomHeader( WS_MESSAGE *handle, const WS_XML_STRING *na static WCHAR *build_http_header( const WCHAR *name, const WCHAR *value, ULONG *ret_len ) { - static const WCHAR fmtW[] = {'%','s',':',' ','%','s',0}; - WCHAR *ret = heap_alloc( (strlenW(name) + strlenW(value) + 3) * sizeof(WCHAR) ); - if (ret) *ret_len = sprintfW( ret, fmtW, name, value ); + int len_name = strlenW( name ), len_value = strlenW( value ); + WCHAR *ret = heap_alloc( (len_name + len_value) * sizeof(WCHAR) ); + + if (!ret) return NULL; + memcpy( ret, name, len_name * sizeof(WCHAR) ); + memcpy( ret + len_name, value, len_value * sizeof(WCHAR) ); + *ret_len = len_name + len_value; return ret; } @@ -1625,7 +1629,7 @@ static inline HRESULT insert_http_header( HINTERNET req, const WCHAR *header, UL HRESULT message_insert_http_headers( WS_MESSAGE *handle, HINTERNET req ) { static const WCHAR contenttypeW[] = - {'C','o','n','t','e','n','t','-','T','y','p','e',0}; + {'C','o','n','t','e','n','t','-','T','y','p','e',':',' ',0}; static const WCHAR soapxmlW[] = {'a','p','p','l','i','c','a','t','i','o','n','/','s','o','a','p','+','x','m','l',0}; static const WCHAR textxmlW[] = @@ -1675,7 +1679,7 @@ HRESULT message_insert_http_headers( WS_MESSAGE *handle, HINTERNET req ) { case WS_ENVELOPE_VERSION_SOAP_1_1: { - static const WCHAR soapactionW[] = {'S','O','A','P','A','c','t','i','o','n',0}; + static const WCHAR soapactionW[] = {'S','O','A','P','A','c','t','i','o','n',':',' ',0}; if (!(len = msg->action.length)) break;