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
11ca05f6
Commit
11ca05f6
authored
May 29, 2009
by
Jacek Caban
Committed by
Alexandre Julliard
Jun 01, 2009
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wininet: Added support for decompressing gzip encoded content.
parent
26bbf072
Hide whitespace changes
Inline
Side-by-side
Showing
6 changed files
with
289 additions
and
15 deletions
+289
-15
configure
configure
+83
-1
configure.ac
configure.ac
+9
-1
Makefile.in
dlls/wininet/Makefile.in
+1
-1
http.c
dlls/wininet/http.c
+185
-12
internet.h
dlls/wininet/internet.h
+5
-0
config.h.in
include/config.h.in
+6
-0
No files found.
configure
View file @
11ca05f6
...
...
@@ -669,6 +669,7 @@ ALSALIBS
ESDLIBS
ESDINCL
ESDCONFIG
ZLIB
FREETYPEINCL
FREETYPELIBS
ft_devel
...
...
@@ -5778,6 +5779,7 @@ done
for
ac_header
in
\
AudioUnit/AudioUnit.h
\
Carbon/Carbon.h
\
...
...
@@ -5899,7 +5901,8 @@ for ac_header in \
unistd.h
\
utime.h
\
valgrind/memcheck.h
\
valgrind/valgrind.h
valgrind/valgrind.h
\
zlib.h
do
as_ac_Header
=
`
$as_echo
"ac_cv_header_
$ac_header
"
|
$as_tr_sh
`
...
...
@@ -15051,6 +15054,85 @@ done
LIBS
=
"
$ac_wine_check_funcs_save_LIBS
"
if
test
"
$ac_cv_header_zlib_h
"
=
"yes"
then
{
$as_echo
"
$as_me
:
$LINENO
: checking for inflate in -lz"
>
&5
$as_echo_n
"checking for inflate in -lz... "
>
&6
;
}
if
test
"
${
ac_cv_lib_z_inflate
+set
}
"
=
set
;
then
$as_echo_n
"(cached) "
>
&6
else
ac_check_lib_save_LIBS
=
$LIBS
LIBS
=
"-lz
$LIBS
"
cat
>
conftest.
$ac_ext
<<
_ACEOF
/* confdefs.h. */
_ACEOF
cat
confdefs.h
>>
conftest.
$ac_ext
cat
>>
conftest.
$ac_ext
<<
_ACEOF
/* end confdefs.h. */
/* Override any GCC internal prototype to avoid an error.
Use char because int might match the return type of a GCC
builtin and then its argument prototype would still apply. */
#ifdef __cplusplus
extern "C"
#endif
char inflate ();
int
main ()
{
return inflate ();
;
return 0;
}
_ACEOF
rm
-f
conftest.
$ac_objext
conftest
$ac_exeext
if
{
(
ac_try
=
"
$ac_link
"
case
"((
$ac_try
"
in
*
\"
*
|
*
\`
*
|
*
\\
*
)
ac_try_echo
=
\$
ac_try
;;
*
)
ac_try_echo
=
$ac_try
;;
esac
eval
ac_try_echo
=
"
\"\$
as_me:
$LINENO
:
$ac_try_echo
\"
"
$as_echo
"
$ac_try_echo
"
)
>
&5
(
eval
"
$ac_link
"
)
2>conftest.er1
ac_status
=
$?
grep
-v
'^ *+'
conftest.er1
>
conftest.err
rm
-f
conftest.er1
cat
conftest.err
>
&5
$as_echo
"
$as_me
:
$LINENO
:
\$
? =
$ac_status
"
>
&5
(
exit
$ac_status
)
;
}
&&
{
test
-z
"
$ac_c_werror_flag
"
||
test
!
-s
conftest.err
}
&&
test
-s
conftest
$ac_exeext
&&
{
test
"
$cross_compiling
"
=
yes
||
$as_test_x
conftest
$ac_exeext
}
;
then
ac_cv_lib_z_inflate
=
yes
else
$as_echo
"
$as_me
: failed program was:"
>
&5
sed
's/^/| /'
conftest.
$ac_ext
>
&5
ac_cv_lib_z_inflate
=
no
fi
rm
-rf
conftest.dSYM
rm
-f
core conftest.err conftest.
$ac_objext
conftest_ipa8_conftest.oo
\
conftest
$ac_exeext
conftest.
$ac_ext
LIBS
=
$ac_check_lib_save_LIBS
fi
{
$as_echo
"
$as_me
:
$LINENO
: result:
$ac_cv_lib_z_inflate
"
>
&5
$as_echo
"
$ac_cv_lib_z_inflate
"
>
&6
;
}
if
test
"x
$ac_cv_lib_z_inflate
"
=
x
""
yes
;
then
cat
>>
confdefs.h
<<
\
_ACEOF
#define HAVE_ZLIB 1
_ACEOF
ZLIB
=
"-lz"
fi
fi
if
test
"x
$with_esd
"
!=
xno
then
save_CFLAGS
=
"
$CFLAGS
"
...
...
configure.ac
View file @
11ca05f6
...
...
@@ -377,7 +377,8 @@ AC_CHECK_HEADERS(\
unistd.h \
utime.h \
valgrind/memcheck.h \
valgrind/valgrind.h
valgrind/valgrind.h \
zlib.h
)
AC_HEADER_STAT()
...
...
@@ -1172,6 +1173,13 @@ WINE_CHECK_LIB_FUNCS(\
pthread_get_stacksize_np,
[$LIBPTHREAD])
dnl **** Check for zlib ****
if test "$ac_cv_header_zlib_h" = "yes"
then
AC_CHECK_LIB(z,inflate,[AC_DEFINE(HAVE_ZLIB,1,[Define to 1 if you have the `z' library (-lz).])
AC_SUBST(ZLIB,"-lz")])
fi
dnl **** Check for EsounD ****
if test "x$with_esd" != xno
then
...
...
dlls/wininet/Makefile.in
View file @
11ca05f6
...
...
@@ -7,7 +7,7 @@ MODULE = wininet.dll
IMPORTLIB
=
wininet
IMPORTS
=
mpr shlwapi shell32 user32 advapi32 kernel32 ntdll
DELAYIMPORTS
=
secur32 crypt32
EXTRALIBS
=
@SOCKETLIBS@
EXTRALIBS
=
@SOCKETLIBS@
@ZLIB@
C_SRCS
=
\
cookie.c
\
...
...
dlls/wininet/http.c
View file @
11ca05f6
...
...
@@ -48,6 +48,9 @@
#endif
#include <time.h>
#include <assert.h>
#ifdef HAVE_ZLIB
# include <zlib.h>
#endif
#include "windef.h"
#include "winbase.h"
...
...
@@ -162,6 +165,15 @@ struct HttpAuthInfo
BOOL
finished
;
/* finished authenticating */
};
#ifdef HAVE_ZLIB
struct
gzip_stream_t
{
z_stream
zstream
;
BYTE
buf
[
4096
];
};
#endif
static
BOOL
HTTP_OpenConnection
(
LPWININETHTTPREQW
lpwhr
);
static
BOOL
HTTP_GetResponseHeaders
(
LPWININETHTTPREQW
lpwhr
,
BOOL
clear
);
static
BOOL
HTTP_ProcessHeader
(
LPWININETHTTPREQW
lpwhr
,
LPCWSTR
field
,
LPCWSTR
value
,
DWORD
dwModifier
);
...
...
@@ -188,6 +200,57 @@ static LPHTTPHEADERW HTTP_GetHeader(LPWININETHTTPREQW req, LPCWSTR head)
return
&
req
->
pCustHeaders
[
HeaderIndex
];
}
#ifdef HAVE_ZLIB
static
voidpf
wininet_zalloc
(
voidpf
opaque
,
uInt
items
,
uInt
size
)
{
return
HeapAlloc
(
GetProcessHeap
(),
0
,
items
*
size
);
}
static
void
wininet_zfree
(
voidpf
opaque
,
voidpf
address
)
{
HeapFree
(
GetProcessHeap
(),
0
,
address
);
}
static
void
init_gzip_stream
(
WININETHTTPREQW
*
req
)
{
gzip_stream_t
*
gzip_stream
;
int
zres
;
gzip_stream
=
HeapAlloc
(
GetProcessHeap
(),
0
,
sizeof
(
gzip_stream_t
));
gzip_stream
->
zstream
.
zalloc
=
wininet_zalloc
;
gzip_stream
->
zstream
.
zfree
=
wininet_zfree
;
gzip_stream
->
zstream
.
opaque
=
NULL
;
gzip_stream
->
zstream
.
next_in
=
NULL
;
gzip_stream
->
zstream
.
avail_in
=
0
;
zres
=
inflateInit2
(
&
gzip_stream
->
zstream
,
0x1f
);
if
(
zres
!=
Z_OK
)
{
ERR
(
"inflateInit failed: %d
\n
"
,
zres
);
HeapFree
(
GetProcessHeap
(),
0
,
gzip_stream
);
return
;
}
req
->
gzip_stream
=
gzip_stream
;
req
->
dwContentLength
=
~
0u
;
if
(
req
->
read_size
)
{
memcpy
(
gzip_stream
->
buf
,
req
->
read_buf
+
req
->
read_pos
,
req
->
read_size
);
gzip_stream
->
zstream
.
next_in
=
gzip_stream
->
buf
;
gzip_stream
->
zstream
.
avail_in
=
req
->
read_size
;
req
->
read_size
=
0
;
}
}
#else
static
void
init_gzip_stream
(
WININETHTTPREQW
*
req
)
{
ERR
(
"gzip stream not supported, missing zlib.
\n
"
);
}
#endif
/* set the request content length based on the headers */
static
DWORD
set_content_length
(
LPWININETHTTPREQW
lpwhr
)
{
...
...
@@ -208,6 +271,16 @@ static DWORD set_content_length( LPWININETHTTPREQW lpwhr )
lpwhr
->
read_chunked
=
TRUE
;
}
if
(
lpwhr
->
decoding
)
{
int
encoding_idx
;
static
const
WCHAR
gzipW
[]
=
{
'g'
,
'z'
,
'i'
,
'p'
,
0
};
encoding_idx
=
HTTP_GetCustomHeaderIndex
(
lpwhr
,
szContent_Encoding
,
0
,
FALSE
);
if
(
encoding_idx
!=
-
1
&&
!
strcmpiW
(
lpwhr
->
pCustHeaders
[
encoding_idx
].
lpszValue
,
gzipW
))
init_gzip_stream
(
lpwhr
);
}
return
lpwhr
->
dwContentLength
;
}
...
...
@@ -1476,6 +1549,14 @@ static void HTTPREQ_CloseConnection(WININETHANDLEHEADER *hdr)
TRACE
(
"%p
\n
"
,
lpwhr
);
#ifdef HAVE_ZLIB
if
(
lpwhr
->
gzip_stream
)
{
inflateEnd
(
&
lpwhr
->
gzip_stream
->
zstream
);
HeapFree
(
GetProcessHeap
(),
0
,
lpwhr
->
gzip_stream
);
lpwhr
->
gzip_stream
=
NULL
;
}
#endif
if
(
!
NETCON_connected
(
&
lpwhr
->
netConnection
))
return
;
...
...
@@ -1659,26 +1740,95 @@ static DWORD HTTPREQ_SetOption(WININETHANDLEHEADER *hdr, DWORD option, void *buf
HeapFree
(
GetProcessHeap
(),
0
,
req
->
lpHttpSession
->
lpszPassword
);
if
(
!
(
req
->
lpHttpSession
->
lpszPassword
=
WININET_strdupW
(
buffer
)))
return
ERROR_OUTOFMEMORY
;
return
ERROR_SUCCESS
;
case
INTERNET_OPTION_HTTP_DECODING
:
if
(
size
!=
sizeof
(
BOOL
))
return
ERROR_INVALID_PARAMETER
;
req
->
decoding
=
*
(
BOOL
*
)
buffer
;
return
ERROR_SUCCESS
;
}
return
ERROR_INTERNET_INVALID_OPTION
;
}
static
inline
BOOL
is_gzip_buf_empty
(
gzip_stream_t
*
gzip_stream
)
{
#ifdef HAVE_ZLIB
return
gzip_stream
->
zstream
.
avail_in
==
0
;
#else
return
TRUE
;
#endif
}
static
DWORD
read_gzip_data
(
WININETHTTPREQW
*
req
,
BYTE
*
buf
,
int
size
,
int
flags
,
int
*
read_ret
)
{
DWORD
ret
=
ERROR_SUCCESS
;
int
read
=
0
;
#ifdef HAVE_ZLIB
int
res
,
len
,
zres
;
z_stream
*
zstream
;
zstream
=
&
req
->
gzip_stream
->
zstream
;
while
(
read
<
size
)
{
if
(
is_gzip_buf_empty
(
req
->
gzip_stream
))
{
res
=
NETCON_recv
(
&
req
->
netConnection
,
req
->
gzip_stream
->
buf
,
sizeof
(
req
->
gzip_stream
->
buf
),
flags
,
&
len
);
if
(
!
res
)
{
if
(
!
read
)
ret
=
INTERNET_GetLastError
();
break
;
}
zstream
->
next_in
=
req
->
gzip_stream
->
buf
;
zstream
->
avail_in
=
len
;
}
zstream
->
next_out
=
buf
+
read
;
zstream
->
avail_out
=
size
-
read
;
zres
=
inflate
(
zstream
,
Z_FULL_FLUSH
);
read
=
size
-
zstream
->
avail_out
;
if
(
zres
==
Z_STREAM_END
)
{
TRACE
(
"end of data
\n
"
);
req
->
dwContentLength
=
req
->
dwContentRead
+
req
->
read_size
+
read
;
break
;
}
else
if
(
zres
!=
Z_OK
)
{
WARN
(
"inflate failed %d
\n
"
,
zres
);
if
(
!
read
)
ret
=
ERROR_INTERNET_DECODING_FAILED
;
break
;
}
}
#endif
*
read_ret
=
read
;
return
ret
;
}
/* read some more data into the read buffer (the read section must be held) */
static
BOOL
read_more_data
(
WININETHTTPREQW
*
req
,
int
maxlen
)
{
int
len
;
if
(
req
->
read_
size
&&
req
->
read_
pos
)
if
(
req
->
read_pos
)
{
/* move existing data to the start of the buffer */
memmove
(
req
->
read_buf
,
req
->
read_buf
+
req
->
read_pos
,
req
->
read_size
);
if
(
req
->
read_size
)
memmove
(
req
->
read_buf
,
req
->
read_buf
+
req
->
read_pos
,
req
->
read_size
);
req
->
read_pos
=
0
;
}
if
(
maxlen
==
-
1
)
maxlen
=
sizeof
(
req
->
read_buf
);
if
(
!
NETCON_recv
(
&
req
->
netConnection
,
req
->
read_buf
+
req
->
read_size
,
maxlen
-
req
->
read_size
,
0
,
&
len
))
return
FALSE
;
if
(
req
->
gzip_stream
)
{
if
(
read_gzip_data
(
req
,
req
->
read_buf
+
req
->
read_size
,
maxlen
-
req
->
read_size
,
0
,
&
len
)
!=
ERROR_SUCCESS
)
return
FALSE
;
}
else
{
if
(
!
NETCON_recv
(
&
req
->
netConnection
,
req
->
read_buf
+
req
->
read_size
,
maxlen
-
req
->
read_size
,
0
,
&
len
))
return
FALSE
;
}
req
->
read_size
+=
len
;
return
TRUE
;
}
...
...
@@ -1847,6 +1997,7 @@ static void HTTP_ReceiveRequestData(WININETHTTPREQW *req, BOOL first_notif)
static
DWORD
HTTPREQ_Read
(
WININETHTTPREQW
*
req
,
void
*
buffer
,
DWORD
size
,
DWORD
*
read
,
BOOL
sync
)
{
int
len
,
bytes_read
=
0
;
DWORD
ret
=
ERROR_SUCCESS
;
EnterCriticalSection
(
&
req
->
read_section
);
if
(
req
->
read_chunked
&&
(
req
->
dwContentLength
==
~
0u
||
req
->
dwContentLength
==
req
->
dwContentRead
))
...
...
@@ -1862,12 +2013,20 @@ static DWORD HTTPREQ_Read(WININETHTTPREQW *req, void *buffer, DWORD size, DWORD
remove_data
(
req
,
bytes_read
);
}
if
(
size
>
bytes_read
&&
(
!
bytes_read
||
sync
)
)
if
(
size
>
bytes_read
)
{
if
(
NETCON_recv
(
&
req
->
netConnection
,
(
char
*
)
buffer
+
bytes_read
,
size
-
bytes_read
,
sync
?
MSG_WAITALL
:
0
,
&
len
))
bytes_read
+=
len
;
/* always return success, even if the network layer returns an error */
if
(
req
->
gzip_stream
)
{
if
(
is_gzip_buf_empty
(
req
->
gzip_stream
)
||
!
bytes_read
||
sync
)
{
ret
=
read_gzip_data
(
req
,
(
BYTE
*
)
buffer
+
bytes_read
,
size
-
bytes_read
,
sync
?
MSG_WAITALL
:
0
,
&
len
);
if
(
ret
==
ERROR_SUCCESS
)
bytes_read
+=
len
;
}
}
else
if
(
!
bytes_read
||
sync
)
{
if
(
NETCON_recv
(
&
req
->
netConnection
,
(
char
*
)
buffer
+
bytes_read
,
size
-
bytes_read
,
sync
?
MSG_WAITALL
:
0
,
&
len
))
bytes_read
+=
len
;
/* always return success, even if the network layer returns an error */
}
}
done:
req
->
dwContentRead
+=
bytes_read
;
...
...
@@ -1876,7 +2035,7 @@ done:
TRACE
(
"retrieved %u bytes (%u/%u)
\n
"
,
bytes_read
,
req
->
dwContentRead
,
req
->
dwContentLength
);
LeaveCriticalSection
(
&
req
->
read_section
);
if
(
req
->
lpszCacheFile
)
{
if
(
re
t
==
ERROR_SUCCESS
&&
re
q
->
lpszCacheFile
)
{
BOOL
res
;
DWORD
dwBytesWritten
;
...
...
@@ -1888,7 +2047,7 @@ done:
if
(
!
bytes_read
&&
(
req
->
dwContentRead
==
req
->
dwContentLength
))
HTTP_FinishedReading
(
req
);
return
ERROR_SUCCESS
;
return
ret
;
}
...
...
@@ -2101,7 +2260,7 @@ static DWORD HTTPREQ_QueryDataAvailable(WININETHANDLEHEADER *hdr, DWORD *availab
}
done:
if
(
*
available
==
sizeof
(
req
->
read_buf
))
/* check if we have even more pending in the socket */
if
(
*
available
==
sizeof
(
req
->
read_buf
)
&&
!
req
->
gzip_stream
)
/* check if we have even more pending in the socket */
{
DWORD
extra
;
if
(
NETCON_query_data_available
(
&
req
->
netConnection
,
&
extra
))
...
...
@@ -2396,6 +2555,16 @@ static BOOL HTTP_HttpQueryInfoW( LPWININETHTTPREQW lpwhr, DWORD dwInfoLevel,
index
=
HTTP_GetCustomHeaderIndex
(
lpwhr
,
lpBuffer
,
requested_index
,
request_only
);
break
;
case
HTTP_QUERY_CONTENT_LENGTH
:
if
(
lpwhr
->
gzip_stream
)
{
INTERNET_SetLastError
(
ERROR_HTTP_HEADER_NOT_FOUND
);
return
FALSE
;
}
index
=
HTTP_GetCustomHeaderIndex
(
lpwhr
,
header_lookup
[
level
],
requested_index
,
request_only
);
break
;
case
HTTP_QUERY_RAW_HEADERS_CRLF
:
{
LPWSTR
headers
;
...
...
@@ -2504,6 +2673,10 @@ static BOOL HTTP_HttpQueryInfoW( LPWININETHTTPREQW lpwhr, DWORD dwInfoLevel,
return
TRUE
;
}
break
;
case
HTTP_QUERY_CONTENT_ENCODING
:
index
=
HTTP_GetCustomHeaderIndex
(
lpwhr
,
header_lookup
[
lpwhr
->
gzip_stream
?
HTTP_QUERY_CONTENT_TYPE
:
level
],
requested_index
,
request_only
);
break
;
default:
assert
(
LAST_TABLE_HEADER
==
(
HTTP_QUERY_UNLESS_MODIFIED_SINCE
+
1
));
...
...
dlls/wininet/internet.h
View file @
11ca05f6
...
...
@@ -183,6 +183,8 @@ typedef struct
struct
HttpAuthInfo
;
typedef
struct
gzip_stream_t
gzip_stream_t
;
typedef
struct
{
WININETHANDLEHEADER
hdr
;
...
...
@@ -209,6 +211,9 @@ typedef struct
DWORD
read_pos
;
/* current read position in read_buf */
DWORD
read_size
;
/* valid data size in read_buf */
BYTE
read_buf
[
4096
];
/* buffer for already read but not returned data */
BOOL
decoding
;
gzip_stream_t
*
gzip_stream
;
}
WININETHTTPREQW
,
*
LPWININETHTTPREQW
;
...
...
include/config.h.in
View file @
11ca05f6
...
...
@@ -1041,6 +1041,12 @@
/* Define if Xrender has the XRenderSetPictureTransform function */
#undef HAVE_XRENDERSETPICTURETRANSFORM
/* Define to 1 if you have the `z' library (-lz). */
#undef HAVE_ZLIB
/* Define to 1 if you have the <zlib.h> header file. */
#undef HAVE_ZLIB_H
/* Define to 1 if you have the `_pclose' function. */
#undef HAVE__PCLOSE
...
...
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