Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-winehq
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Registry
Registry
Wiki
Wiki
Snippets
Snippets
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
wine
wine-winehq
Commits
79be5ad4
Commit
79be5ad4
authored
Apr 20, 2017
by
Hans Leidekker
Committed by
Alexandre Julliard
Apr 20, 2017
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
webservices: Reuse the message read buffer.
Signed-off-by:
Hans Leidekker
<
hans@codeweavers.com
>
Signed-off-by:
Alexandre Julliard
<
julliard@winehq.org
>
parent
99e24f00
Hide whitespace changes
Inline
Side-by-side
Showing
3 changed files
with
77 additions
and
59 deletions
+77
-59
channel.c
dlls/webservices/channel.c
+72
-46
proxy.c
dlls/webservices/proxy.c
+3
-11
webservices_private.h
dlls/webservices/webservices_private.h
+2
-2
No files found.
dlls/webservices/channel.c
View file @
79be5ad4
...
...
@@ -98,6 +98,9 @@ struct channel
HINTERNET
http_session
;
HINTERNET
http_connect
;
HINTERNET
http_request
;
char
*
read_buf
;
ULONG
read_buflen
;
ULONG
read_size
;
ULONG
prop_count
;
struct
prop
prop
[
sizeof
(
channel_props
)
/
sizeof
(
channel_props
[
0
])];
};
...
...
@@ -134,6 +137,8 @@ static void reset_channel( struct channel *channel )
channel
->
http_connect
=
NULL
;
WinHttpCloseHandle
(
channel
->
http_session
);
channel
->
http_session
=
NULL
;
channel
->
read_size
=
0
;
}
static
void
free_channel
(
struct
channel
*
channel
)
...
...
@@ -143,6 +148,8 @@ static void free_channel( struct channel *channel )
WsFreeWriter
(
channel
->
writer
);
WsFreeReader
(
channel
->
reader
);
heap_free
(
channel
->
read_buf
);
channel
->
cs
.
DebugInfo
->
Spare
[
0
]
=
0
;
DeleteCriticalSection
(
&
channel
->
cs
);
heap_free
(
channel
);
...
...
@@ -629,57 +636,72 @@ done:
return
hr
;
}
static
HRESULT
resize_read_buffer
(
struct
channel
*
channel
,
ULONG
size
)
{
if
(
!
channel
->
read_buf
)
{
if
(
!
(
channel
->
read_buf
=
heap_alloc
(
size
)))
return
E_OUTOFMEMORY
;
channel
->
read_buflen
=
size
;
return
S_OK
;
}
if
(
channel
->
read_buflen
<
size
)
{
char
*
tmp
;
ULONG
new_size
=
max
(
size
,
channel
->
read_buflen
*
2
);
if
(
!
(
tmp
=
heap_realloc
(
channel
->
read_buf
,
new_size
)))
return
E_OUTOFMEMORY
;
channel
->
read_buf
=
tmp
;
channel
->
read_buflen
=
new_size
;
}
return
S_OK
;
}
#define INITIAL_READ_BUFFER_SIZE 4096
static
HRESULT
receive_message
(
struct
channel
*
channel
,
ULONG
max_len
,
char
**
ret
,
ULONG
*
ret_len
)
static
HRESULT
receive_message
(
struct
channel
*
channel
)
{
DWORD
len
,
bytes_read
,
offset
=
0
,
size
=
INITIAL_READ_BUFFER_SIZE
;
char
*
buf
;
DWORD
len
,
max_len
,
bytes_read
,
offset
=
0
,
size
=
INITIAL_READ_BUFFER_SIZE
;
HRESULT
hr
;
prop_get
(
channel
->
prop
,
channel
->
prop_count
,
WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE
,
&
max_len
,
sizeof
(
max_len
)
);
if
((
hr
=
resize_read_buffer
(
channel
,
size
))
!=
S_OK
)
return
hr
;
channel
->
read_size
=
0
;
if
(
!
(
buf
=
heap_alloc
(
size
)))
return
E_OUTOFMEMORY
;
*
ret_len
=
0
;
for
(;;)
{
if
(
!
WinHttpQueryDataAvailable
(
channel
->
http_request
,
&
len
))
{
heap_free
(
buf
);
return
HRESULT_FROM_WIN32
(
GetLastError
()
);
}
if
(
!
len
)
break
;
if
(
*
ret_len
+
len
>
max_len
)
{
heap_free
(
buf
);
return
WS_E_QUOTA_EXCEEDED
;
}
if
(
*
ret_len
+
len
>
size
)
{
char
*
tmp
;
DWORD
new_size
=
max
(
*
ret_len
+
len
,
size
*
2
);
if
(
!
(
tmp
=
heap_realloc
(
buf
,
new_size
)))
{
heap_free
(
buf
);
return
E_OUTOFMEMORY
;
}
buf
=
tmp
;
size
=
new_size
;
}
if
(
!
WinHttpReadData
(
channel
->
http_request
,
buf
+
offset
,
len
,
&
bytes_read
))
if
(
channel
->
read_size
+
len
>
max_len
)
return
WS_E_QUOTA_EXCEEDED
;
if
((
hr
=
resize_read_buffer
(
channel
,
channel
->
read_size
+
len
))
!=
S_OK
)
return
hr
;
if
(
!
WinHttpReadData
(
channel
->
http_request
,
channel
->
read_buf
+
offset
,
len
,
&
bytes_read
))
{
heap_free
(
buf
);
return
HRESULT_FROM_WIN32
(
GetLastError
()
);
}
if
(
!
bytes_read
)
break
;
*
ret_len
+=
bytes_read
;
channel
->
read_size
+=
bytes_read
;
offset
+=
bytes_read
;
}
*
ret
=
buf
;
return
S_OK
;
}
HRESULT
channel_receive_message
(
WS_CHANNEL
*
handle
,
char
**
buf
,
ULONG
*
len
)
static
HRESULT
set_input
(
WS_XML_READER
*
reader
,
char
*
data
,
ULONG
size
)
{
WS_XML_READER_TEXT_ENCODING
text
=
{{
WS_XML_READER_ENCODING_TYPE_TEXT
},
WS_CHARSET_UTF8
};
WS_XML_READER_BUFFER_INPUT
buf
;
buf
.
input
.
inputType
=
WS_XML_READER_INPUT_TYPE_BUFFER
;
buf
.
encodedData
=
data
;
buf
.
encodedDataSize
=
size
;
return
WsSetInput
(
reader
,
&
text
.
encoding
,
&
buf
.
input
,
NULL
,
0
,
NULL
);
}
HRESULT
channel_receive_message
(
WS_CHANNEL
*
handle
)
{
struct
channel
*
channel
=
(
struct
channel
*
)
handle
;
ULONG
max_len
;
HRESULT
hr
;
EnterCriticalSection
(
&
channel
->
cs
);
...
...
@@ -690,22 +712,31 @@ HRESULT channel_receive_message( WS_CHANNEL *handle, char **buf, ULONG *len )
return
E_INVALIDARG
;
}
WsGetChannelProperty
(
handle
,
WS_CHANNEL_PROPERTY_MAX_BUFFERED_MESSAGE_SIZE
,
&
max_len
,
sizeof
(
max_len
),
NULL
);
hr
=
receive_message
(
channel
,
max_len
,
buf
,
len
);
if
((
hr
=
receive_message
(
channel
))
!=
S_OK
)
goto
done
;
if
(
!
channel
->
reader
&&
(
hr
=
WsCreateReader
(
NULL
,
0
,
&
channel
->
reader
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
set_input
(
channel
->
reader
,
channel
->
read_buf
,
channel
->
read_size
))
!=
S_OK
)
goto
done
;
done:
LeaveCriticalSection
(
&
channel
->
cs
);
return
hr
;
}
HRESULT
set_input
(
WS_XML_READER
*
reader
,
char
*
data
,
ULONG
size
)
HRESULT
channel_get_reader
(
WS_CHANNEL
*
handle
,
WS_XML_READER
**
reader
)
{
WS_XML_READER_TEXT_ENCODING
text
=
{{
WS_XML_READER_ENCODING_TYPE_TEXT
},
WS_CHARSET_UTF8
};
WS_XML_READER_BUFFER_INPUT
buf
;
struct
channel
*
channel
=
(
struct
channel
*
)
handle
;
buf
.
input
.
inputType
=
WS_XML_READER_INPUT_TYPE_BUFFER
;
buf
.
encodedData
=
data
;
buf
.
encodedDataSize
=
size
;
return
WsSetInput
(
reader
,
&
text
.
encoding
,
&
buf
.
input
,
NULL
,
0
,
NULL
);
EnterCriticalSection
(
&
channel
->
cs
);
if
(
channel
->
magic
!=
CHANNEL_MAGIC
)
{
LeaveCriticalSection
(
&
channel
->
cs
);
return
E_INVALIDARG
;
}
*
reader
=
channel
->
reader
;
LeaveCriticalSection
(
&
channel
->
cs
);
return
S_OK
;
}
static
HRESULT
read_message
(
WS_MESSAGE
*
handle
,
WS_XML_READER
*
reader
,
const
WS_ELEMENT_DESCRIPTION
*
desc
,
...
...
@@ -725,8 +756,6 @@ HRESULT WINAPI WsReceiveMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_M
void
*
value
,
ULONG
size
,
ULONG
*
index
,
const
WS_ASYNC_CONTEXT
*
ctx
,
WS_ERROR
*
error
)
{
struct
channel
*
channel
=
(
struct
channel
*
)
handle
;
char
*
buf
=
NULL
;
ULONG
len
;
HRESULT
hr
;
TRACE
(
"%p %p %p %u %08x %08x %p %p %u %p %p %p
\n
"
,
handle
,
msg
,
desc
,
count
,
option
,
read_option
,
heap
,
...
...
@@ -751,23 +780,20 @@ HRESULT WINAPI WsReceiveMessage( WS_CHANNEL *handle, WS_MESSAGE *msg, const WS_M
if
(
!
channel
||
!
msg
||
!
desc
||
!
count
)
return
E_INVALIDARG
;
if
((
hr
=
channel_receive_message
(
handle
,
&
buf
,
&
len
))
!=
S_OK
)
return
hr
;
EnterCriticalSection
(
&
channel
->
cs
);
if
(
channel
->
magic
!=
CHANNEL_MAGIC
)
{
heap_free
(
buf
);
LeaveCriticalSection
(
&
channel
->
cs
);
return
E_INVALIDARG
;
}
if
((
hr
=
receive_message
(
channel
))
!=
S_OK
)
goto
done
;
if
(
!
channel
->
reader
&&
(
hr
=
WsCreateReader
(
NULL
,
0
,
&
channel
->
reader
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
set_input
(
channel
->
reader
,
buf
,
len
))
!=
S_OK
)
goto
done
;
if
((
hr
=
set_input
(
channel
->
reader
,
channel
->
read_buf
,
channel
->
read_size
))
!=
S_OK
)
goto
done
;
hr
=
read_message
(
msg
,
channel
->
reader
,
desc
[
0
]
->
bodyElementDescription
,
read_option
,
heap
,
value
,
size
);
done:
heap_free
(
buf
);
LeaveCriticalSection
(
&
channel
->
cs
);
return
hr
;
}
dlls/webservices/proxy.c
View file @
79be5ad4
...
...
@@ -433,20 +433,12 @@ static HRESULT receive_message( WS_CHANNEL *channel, WS_MESSAGE *msg, WS_MESSAGE
WS_PARAMETER_DESCRIPTION
*
params
,
ULONG
count
,
WS_HEAP
*
heap
,
const
void
**
args
)
{
WS_XML_READER
*
reader
;
char
*
buf
;
ULONG
len
;
HRESULT
hr
;
if
((
hr
=
message_set_action
(
msg
,
desc
->
action
))
!=
S_OK
)
return
hr
;
if
((
hr
=
channel_receive_message
(
channel
,
&
buf
,
&
len
))
!=
S_OK
)
return
hr
;
if
((
hr
=
WsCreateReader
(
NULL
,
0
,
&
reader
,
NULL
))
!=
S_OK
)
goto
done
;
if
((
hr
=
set_input
(
reader
,
buf
,
len
))
!=
S_OK
)
goto
done
;
hr
=
read_message
(
msg
,
reader
,
heap
,
desc
->
bodyElementDescription
,
params
,
count
,
args
);
done:
WsFreeReader
(
reader
);
heap_free
(
buf
);
return
hr
;
if
((
hr
=
channel_receive_message
(
channel
))
!=
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
);
}
static
HRESULT
create_input_message
(
WS_CHANNEL
*
channel
,
const
WS_CALL_PROPERTY
*
properties
,
...
...
dlls/webservices/webservices_private.h
View file @
79be5ad4
...
...
@@ -43,7 +43,6 @@ WS_TYPE map_value_type( WS_VALUE_TYPE ) DECLSPEC_HIDDEN;
BOOL
set_fpword
(
unsigned
short
,
unsigned
short
*
)
DECLSPEC_HIDDEN
;
void
restore_fpword
(
unsigned
short
)
DECLSPEC_HIDDEN
;
HRESULT
set_output
(
WS_XML_WRITER
*
)
DECLSPEC_HIDDEN
;
HRESULT
set_input
(
WS_XML_READER
*
,
char
*
,
ULONG
)
DECLSPEC_HIDDEN
;
ULONG
get_type_size
(
WS_TYPE
,
const
WS_STRUCT_DESCRIPTION
*
)
DECLSPEC_HIDDEN
;
#define INVALID_PARAMETER_INDEX 0xffff
...
...
@@ -119,7 +118,8 @@ void message_do_receive_callback( WS_MESSAGE * ) DECLSPEC_HIDDEN;
HRESULT
message_insert_http_headers
(
WS_MESSAGE
*
,
HINTERNET
)
DECLSPEC_HIDDEN
;
HRESULT
channel_send_message
(
WS_CHANNEL
*
,
WS_MESSAGE
*
)
DECLSPEC_HIDDEN
;
HRESULT
channel_receive_message
(
WS_CHANNEL
*
,
char
**
,
ULONG
*
)
DECLSPEC_HIDDEN
;
HRESULT
channel_receive_message
(
WS_CHANNEL
*
)
DECLSPEC_HIDDEN
;
HRESULT
channel_get_reader
(
WS_CHANNEL
*
,
WS_XML_READER
**
)
DECLSPEC_HIDDEN
;
#define TICKS_PER_SEC 10000000
#define TICKS_PER_MIN (60 * (ULONGLONG)TICKS_PER_SEC)
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment