Skip to content
Projects
Groups
Snippets
Help
This project
Loading...
Sign in / Register
Toggle navigation
W
wine-cw
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-cw
Commits
8a1df203
Commit
8a1df203
authored
May 10, 2011
by
Jacek Caban
Committed by
Alexandre Julliard
May 10, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
wininet: Added support for persistent HTTP connections.
parent
28c8e228
Hide whitespace changes
Inline
Side-by-side
Showing
7 changed files
with
546 additions
and
407 deletions
+546
-407
protocol.c
dlls/urlmon/tests/protocol.c
+1
-1
url.c
dlls/urlmon/tests/url.c
+11
-15
http.c
dlls/wininet/http.c
+416
-264
internet.c
dlls/wininet/internet.c
+1
-1
internet.h
dlls/wininet/internet.h
+32
-11
netconnection.c
dlls/wininet/netconnection.c
+80
-88
http.c
dlls/wininet/tests/http.c
+5
-27
No files found.
dlls/urlmon/tests/protocol.c
View file @
8a1df203
...
...
@@ -574,7 +574,7 @@ static void call_continue(PROTOCOLDATA *protocol_data)
CLEAR_CALLED
(
ReportProgress_FINDINGRESOURCE
);
CLEAR_CALLED
(
ReportProgress_CONNECTING
);
CLEAR_CALLED
(
ReportProgress_PROXYDETECTING
);
}
else
todo_wine
{
}
else
{
CHECK_NOT_CALLED
(
ReportProgress_FINDINGRESOURCE
);
/* IE7 does call this */
CLEAR_CALLED
(
ReportProgress_CONNECTING
);
...
...
dlls/urlmon/tests/url.c
View file @
8a1df203
...
...
@@ -1795,7 +1795,7 @@ static HRESULT WINAPI statusclb_OnStopBinding(IBindStatusCallbackEx *iface, HRES
if
(
filedwl_api
)
ok
(
SUCCEEDED
(
hresult
),
"binding failed: %08x
\n
"
,
hresult
);
else
if
(
invalid_cn_accepted
)
todo_wine
ok
(
hresult
==
binding_hres
,
"binding failed: %08x, expected %08x
\n
"
,
hresult
,
binding_hres
);
ok
(
hresult
==
binding_hres
,
"binding failed: %08x, expected %08x
\n
"
,
hresult
,
binding_hres
);
else
ok
(
hresult
==
binding_hres
,
"binding failed: %08x, expected %08x
\n
"
,
hresult
,
binding_hres
);
ok
(
szError
==
NULL
,
"szError should be NULL
\n
"
);
...
...
@@ -2876,14 +2876,12 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t)
ok
(
hres
==
binding_hres
,
"Got %08x
\n
"
,
hres
);
ok
(
unk
==
NULL
,
"Got %p
\n
"
,
unk
);
}
else
if
((
flags
&
BINDTEST_INVALID_CN
)
&&
invalid_cn_accepted
)
{
todo_wine
{
ok
(
hres
==
S_OK
,
"IMoniker_BindToStorage failed: %08x
\n
"
,
hres
);
ok
(
unk
!=
NULL
,
"unk == NULL
\n
"
);
if
(
unk
==
NULL
)
{
ok
(
0
,
"Expected security problem to be ignored.
\n
"
);
invalid_cn_accepted
=
FALSE
;
binding_hres
=
INET_E_INVALID_CERTIFICATE
;
}
ok
(
hres
==
S_OK
,
"IMoniker_BindToStorage failed: %08x
\n
"
,
hres
);
ok
(
unk
!=
NULL
,
"unk == NULL
\n
"
);
if
(
unk
==
NULL
)
{
ok
(
0
,
"Expected security problem to be ignored.
\n
"
);
invalid_cn_accepted
=
FALSE
;
binding_hres
=
INET_E_INVALID_CERTIFICATE
;
}
}
else
{
ok
(
hres
==
S_OK
,
"IMoniker_BindToStorage failed: %08x
\n
"
,
hres
);
...
...
@@ -2958,11 +2956,9 @@ static void test_BindToStorage(int protocol, DWORD flags, DWORD t)
CLEAR_CALLED
(
OnProgress_CONNECTING
);
}
}
else
if
(
!
abort_start
)
{
todo_wine
{
CHECK_NOT_CALLED
(
OnProgress_FINDINGRESOURCE
);
/* IE7 does call this */
CLEAR_CALLED
(
OnProgress_CONNECTING
);
}
CHECK_NOT_CALLED
(
OnProgress_FINDINGRESOURCE
);
/* IE7 does call this */
CLEAR_CALLED
(
OnProgress_CONNECTING
);
}
if
((
flags
&
BINDTEST_INVALID_CN
)
&&
!
invalid_cn_accepted
)
{
CHECK_CALLED
(
QueryInterface_IHttpSecurity
);
...
...
@@ -3186,7 +3182,7 @@ static void test_BindToObject(int protocol, DWORD flags)
if
(
http_is_first
)
{
CHECK_CALLED
(
Obj_OnProgress_FINDINGRESOURCE
);
CHECK_CALLED
(
Obj_OnProgress_CONNECTING
);
}
else
todo_wine
{
}
else
{
CHECK_NOT_CALLED
(
Obj_OnProgress_FINDINGRESOURCE
);
/* IE7 does call this */
CLEAR_CALLED
(
Obj_OnProgress_CONNECTING
);
...
...
dlls/wininet/http.c
View file @
8a1df203
...
...
@@ -155,6 +155,8 @@ static const WCHAR szWWW_Authenticate[] = { 'W','W','W','-','A','u','t','h','e',
#define HTTP_ADDHDR_FLAG_REPLACE 0x80000000
#define HTTP_ADDHDR_FLAG_REQ 0x02000000
#define COLLECT_TIME 60000
#define ARRAYSIZE(array) (sizeof(array)/sizeof((array)[0]))
struct
HttpAuthInfo
...
...
@@ -207,7 +209,6 @@ static CRITICAL_SECTION_DEBUG critsect_debug =
};
static
CRITICAL_SECTION
authcache_cs
=
{
&
critsect_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
DWORD
HTTP_OpenConnection
(
http_request_t
*
req
);
static
BOOL
HTTP_GetResponseHeaders
(
http_request_t
*
req
,
BOOL
clear
);
static
DWORD
HTTP_ProcessHeader
(
http_request_t
*
req
,
LPCWSTR
field
,
LPCWSTR
value
,
DWORD
dwModifier
);
static
LPWSTR
*
HTTP_InterpretHttpHeader
(
LPCWSTR
buffer
);
...
...
@@ -219,8 +220,123 @@ static DWORD HTTP_HttpQueryInfoW(http_request_t*, DWORD, LPVOID, LPDWORD, LPDWOR
static
LPWSTR
HTTP_GetRedirectURL
(
http_request_t
*
req
,
LPCWSTR
lpszUrl
);
static
UINT
HTTP_DecodeBase64
(
LPCWSTR
base64
,
LPSTR
bin
);
static
BOOL
HTTP_VerifyValidHeader
(
http_request_t
*
req
,
LPCWSTR
field
);
static
void
HTTP_DrainContent
(
http_request_t
*
req
);
static
BOOL
HTTP_FinishedReading
(
http_request_t
*
req
);
static
CRITICAL_SECTION
connection_pool_cs
;
static
CRITICAL_SECTION_DEBUG
connection_pool_debug
=
{
0
,
0
,
&
connection_pool_cs
,
{
&
critsect_debug
.
ProcessLocksList
,
&
critsect_debug
.
ProcessLocksList
},
0
,
0
,
{
(
DWORD_PTR
)(
__FILE__
": connection_pool_cs"
)
}
};
static
CRITICAL_SECTION
connection_pool_cs
=
{
&
connection_pool_debug
,
-
1
,
0
,
0
,
0
,
0
};
static
struct
list
connection_pool
=
LIST_INIT
(
connection_pool
);
static
BOOL
collector_running
;
void
server_addref
(
server_t
*
server
)
{
InterlockedIncrement
(
&
server
->
ref
);
}
void
server_release
(
server_t
*
server
)
{
if
(
InterlockedDecrement
(
&
server
->
ref
))
return
;
if
(
!
server
->
ref
)
server
->
keep_until
=
GetTickCount64
()
+
COLLECT_TIME
;
}
static
server_t
*
get_server
(
const
WCHAR
*
name
,
INTERNET_PORT
port
)
{
server_t
*
iter
,
*
server
=
NULL
;
EnterCriticalSection
(
&
connection_pool_cs
);
LIST_FOR_EACH_ENTRY
(
iter
,
&
connection_pool
,
server_t
,
entry
)
{
if
(
iter
->
port
==
port
&&
!
strcmpW
(
iter
->
name
,
name
))
{
server
=
iter
;
server_addref
(
server
);
break
;
}
}
if
(
!
server
)
{
server
=
heap_alloc
(
sizeof
(
*
server
));
if
(
server
)
{
server
->
addr_len
=
0
;
server
->
ref
=
1
;
server
->
port
=
port
;
list_init
(
&
server
->
conn_pool
);
server
->
name
=
heap_strdupW
(
name
);
if
(
server
->
name
)
{
list_add_head
(
&
connection_pool
,
&
server
->
entry
);
}
else
{
heap_free
(
server
);
server
=
NULL
;
}
}
}
LeaveCriticalSection
(
&
connection_pool_cs
);
return
server
;
}
BOOL
collect_connections
(
BOOL
collect_all
)
{
netconn_t
*
netconn
,
*
netconn_safe
;
server_t
*
server
,
*
server_safe
;
BOOL
remaining
=
FALSE
;
DWORD64
now
;
now
=
GetTickCount64
();
LIST_FOR_EACH_ENTRY_SAFE
(
server
,
server_safe
,
&
connection_pool
,
server_t
,
entry
)
{
LIST_FOR_EACH_ENTRY_SAFE
(
netconn
,
netconn_safe
,
&
server
->
conn_pool
,
netconn_t
,
pool_entry
)
{
if
(
collect_all
||
netconn
->
keep_until
<
now
)
{
TRACE
(
"freeing %p
\n
"
,
netconn
);
list_remove
(
&
netconn
->
pool_entry
);
free_netconn
(
netconn
);
}
else
{
remaining
=
TRUE
;
}
}
if
(
!
server
->
ref
)
{
if
(
collect_all
||
server
->
keep_until
<
now
)
{
list_remove
(
&
server
->
entry
);
heap_free
(
server
->
name
);
heap_free
(
server
);
}
else
{
remaining
=
TRUE
;
}
}
}
return
remaining
;
}
static
DWORD
WINAPI
collect_connections_proc
(
void
*
arg
)
{
BOOL
remaining_conns
;
do
{
/* FIXME: Use more sophisticated method */
Sleep
(
5000
);
EnterCriticalSection
(
&
connection_pool_cs
);
remaining_conns
=
collect_connections
(
FALSE
);
if
(
!
remaining_conns
)
collector_running
=
FALSE
;
LeaveCriticalSection
(
&
connection_pool_cs
);
}
while
(
remaining_conns
);
FreeLibraryAndExitThread
(
WININET_hModule
,
0
);
}
static
LPHTTPHEADERW
HTTP_GetHeader
(
http_request_t
*
req
,
LPCWSTR
head
)
{
...
...
@@ -242,6 +358,7 @@ struct data_stream_vtbl_t {
DWORD
(
*
get_avail_data
)(
data_stream_t
*
,
http_request_t
*
);
BOOL
(
*
end_of_data
)(
data_stream_t
*
,
http_request_t
*
);
DWORD
(
*
read
)(
data_stream_t
*
,
http_request_t
*
,
BYTE
*
,
DWORD
,
DWORD
*
,
read_mode_t
);
BOOL
(
*
drain_content
)(
data_stream_t
*
,
http_request_t
*
);
void
(
*
destroy
)(
data_stream_t
*
);
};
...
...
@@ -357,6 +474,12 @@ static DWORD gzip_read(data_stream_t *stream, http_request_t *req, BYTE *buf, DW
return
res
;
}
static
BOOL
gzip_drain_content
(
data_stream_t
*
stream
,
http_request_t
*
req
)
{
gzip_stream_t
*
gzip_stream
=
(
gzip_stream_t
*
)
stream
;
return
gzip_stream
->
parent_stream
->
vtbl
->
drain_content
(
gzip_stream
->
parent_stream
,
req
);
}
static
void
gzip_destroy
(
data_stream_t
*
stream
)
{
gzip_stream_t
*
gzip_stream
=
(
gzip_stream_t
*
)
stream
;
...
...
@@ -372,6 +495,7 @@ static const data_stream_vtbl_t gzip_stream_vtbl = {
gzip_get_avail_data
,
gzip_end_of_data
,
gzip_read
,
gzip_drain_content
,
gzip_destroy
};
...
...
@@ -1603,44 +1727,42 @@ static BOOL HTTP_DealWithProxy(appinfo_t *hIC, http_session_t *session, http_req
return
TRUE
;
}
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
static
DWORD
HTTP_ResolveName
(
http_request_t
*
request
)
static
DWORD
HTTP_ResolveName
(
http_request_t
*
request
,
server_t
*
server
)
{
char
szaddr
[
INET6_ADDRSTRLEN
];
http_session_t
*
session
=
request
->
session
;
socklen_t
addr_len
;
const
void
*
addr
;
if
(
server
->
addr_len
)
return
ERROR_SUCCESS
;
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_RESOLVING_NAME
,
se
ssion
->
serverN
ame
,
(
strlenW
(
se
ssion
->
serverN
ame
)
+
1
)
*
sizeof
(
WCHAR
));
se
rver
->
n
ame
,
(
strlenW
(
se
rver
->
n
ame
)
+
1
)
*
sizeof
(
WCHAR
));
session
->
sa_len
=
sizeof
(
session
->
socketAddress
);
if
(
!
GetAddress
(
session
->
serverName
,
session
->
serverPort
,
(
struct
sockaddr
*
)
&
session
->
socketAddress
,
&
session
->
sa_len
))
addr_len
=
sizeof
(
server
->
addr
);
if
(
!
GetAddress
(
server
->
name
,
server
->
port
,
(
struct
sockaddr
*
)
&
server
->
addr
,
&
addr_len
))
return
ERROR_INTERNET_NAME_NOT_RESOLVED
;
switch
(
session
->
socketAddress
.
ss_family
)
{
switch
(
server
->
addr
.
ss_family
)
{
case
AF_INET
:
addr
=
&
((
struct
sockaddr_in
*
)
&
se
ssion
->
socketAddress
)
->
sin_addr
;
addr
=
&
((
struct
sockaddr_in
*
)
&
se
rver
->
addr
)
->
sin_addr
;
break
;
case
AF_INET6
:
addr
=
&
((
struct
sockaddr_in6
*
)
&
se
ssion
->
socketAddress
)
->
sin6_addr
;
addr
=
&
((
struct
sockaddr_in6
*
)
&
se
rver
->
addr
)
->
sin6_addr
;
break
;
default:
WARN
(
"unsupported family %d
\n
"
,
se
ssion
->
socketAddress
.
ss_family
);
WARN
(
"unsupported family %d
\n
"
,
se
rver
->
addr
.
ss_family
);
return
ERROR_INTERNET_NAME_NOT_RESOLVED
;
}
inet_ntop
(
session
->
socketAddress
.
ss_family
,
addr
,
szaddr
,
sizeof
(
szaddr
));
server
->
addr_len
=
addr_len
;
inet_ntop
(
server
->
addr
.
ss_family
,
addr
,
server
->
addr_str
,
sizeof
(
server
->
addr_str
));
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_NAME_RESOLVED
,
s
zaddr
,
strlen
(
szadd
r
)
+
1
);
s
erver
->
addr_str
,
strlen
(
server
->
addr_st
r
)
+
1
);
TRACE
(
"resolved %s to %s
\n
"
,
debugstr_w
(
se
ssion
->
serverName
),
szadd
r
);
TRACE
(
"resolved %s to %s
\n
"
,
debugstr_w
(
se
rver
->
name
),
server
->
addr_st
r
);
return
ERROR_SUCCESS
;
}
...
...
@@ -1721,24 +1843,72 @@ static void HTTPREQ_Destroy(object_header_t *hdr)
HeapFree
(
GetProcessHeap
(),
0
,
request
->
custHeaders
);
}
static
void
HTTPREQ_CloseConnection
(
object_header_t
*
hdr
)
static
void
http_release_netconn
(
http_request_t
*
req
,
BOOL
reuse
)
{
http_request_t
*
request
=
(
http_request_t
*
)
hdr
;
TRACE
(
"%p %p
\n
"
,
req
,
req
->
netconn
);
if
(
!
req
->
netconn
)
return
;
if
(
reuse
&&
req
->
netconn
->
keep_alive
)
{
BOOL
run_collector
;
EnterCriticalSection
(
&
connection_pool_cs
);
TRACE
(
"%p
\n
"
,
request
);
list_add_head
(
&
req
->
netconn
->
server
->
conn_pool
,
&
req
->
netconn
->
pool_entry
);
req
->
netconn
->
keep_until
=
GetTickCount64
()
+
COLLECT_TIME
;
req
->
netconn
=
NULL
;
if
(
!
NETCON_connected
(
&
request
->
netConnection
))
run_collector
=
!
collector_running
;
collector_running
=
TRUE
;
LeaveCriticalSection
(
&
connection_pool_cs
);
if
(
run_collector
)
{
HANDLE
thread
=
NULL
;
HMODULE
module
;
GetModuleHandleExW
(
GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS
,
(
const
WCHAR
*
)
WININET_hModule
,
&
module
);
if
(
module
)
thread
=
CreateThread
(
NULL
,
0
,
collect_connections_proc
,
NULL
,
0
,
NULL
);
if
(
!
thread
)
{
EnterCriticalSection
(
&
connection_pool_cs
);
collector_running
=
FALSE
;
LeaveCriticalSection
(
&
connection_pool_cs
);
if
(
module
)
FreeLibrary
(
module
);
}
}
return
;
}
INTERNET_SendCallback
(
&
req
uest
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_SendCallback
(
&
req
->
hdr
,
req
->
hdr
.
dwContext
,
INTERNET_STATUS_CLOSING_CONNECTION
,
0
,
0
);
NETCON_close
(
&
request
->
netConnection
);
free_netconn
(
req
->
netconn
);
req
->
netconn
=
NULL
;
INTERNET_SendCallback
(
&
req
uest
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_SendCallback
(
&
req
->
hdr
,
req
->
hdr
.
dwContext
,
INTERNET_STATUS_CONNECTION_CLOSED
,
0
,
0
);
}
static
void
drain_content
(
http_request_t
*
req
)
{
BOOL
try_reuse
;
if
(
!
req
->
netconn
)
return
;
if
(
req
->
contentLength
==
-
1
)
try_reuse
=
FALSE
;
else
if
(
!
strcmpW
(
req
->
verb
,
szHEAD
))
try_reuse
=
TRUE
;
else
try_reuse
=
req
->
data_stream
->
vtbl
->
drain_content
(
req
->
data_stream
,
req
);
http_release_netconn
(
req
,
try_reuse
);
}
static
BOOL
HTTP_KeepAlive
(
http_request_t
*
request
)
{
WCHAR
szVersion
[
10
];
...
...
@@ -1764,6 +1934,13 @@ static BOOL HTTP_KeepAlive(http_request_t *request)
return
keepalive
;
}
static
void
HTTPREQ_CloseConnection
(
object_header_t
*
hdr
)
{
http_request_t
*
req
=
(
http_request_t
*
)
hdr
;
drain_content
(
req
);
}
static
DWORD
HTTPREQ_QueryOption
(
object_header_t
*
hdr
,
DWORD
option
,
void
*
buffer
,
DWORD
*
size
,
BOOL
unicode
)
{
http_request_t
*
req
=
(
http_request_t
*
)
hdr
;
...
...
@@ -1791,7 +1968,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
info
->
Flags
|=
IDSI_FLAG_KEEP_ALIVE
;
if
(
session
->
appInfo
->
proxy
&&
session
->
appInfo
->
proxy
[
0
]
!=
0
)
info
->
Flags
|=
IDSI_FLAG_PROXY
;
if
(
req
->
net
Connection
.
useSSL
)
if
(
req
->
net
conn
->
useSSL
)
info
->
Flags
|=
IDSI_FLAG_SECURE
;
return
ERROR_SUCCESS
;
...
...
@@ -1800,7 +1977,6 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
case
INTERNET_OPTION_SECURITY_FLAGS
:
{
DWORD
flags
;
int
bits
;
if
(
*
size
<
sizeof
(
ULONG
))
return
ERROR_INSUFFICIENT_BUFFER
;
...
...
@@ -1809,14 +1985,16 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
flags
=
0
;
if
(
req
->
hdr
.
dwFlags
&
INTERNET_FLAG_SECURE
)
flags
|=
SECURITY_FLAG_SECURE
;
flags
|=
req
->
netConnection
.
security_flags
;
bits
=
NETCON_GetCipherStrength
(
&
req
->
netConnection
);
if
(
bits
>=
128
)
flags
|=
SECURITY_FLAG_STRENGTH_STRONG
;
else
if
(
bits
>=
56
)
flags
|=
SECURITY_FLAG_STRENGTH_MEDIUM
;
else
flags
|=
SECURITY_FLAG_STRENGTH_WEAK
;
flags
|=
req
->
security_flags
;
if
(
req
->
netconn
)
{
int
bits
=
NETCON_GetCipherStrength
(
req
->
netconn
);
if
(
bits
>=
128
)
flags
|=
SECURITY_FLAG_STRENGTH_STRONG
;
else
if
(
bits
>=
56
)
flags
|=
SECURITY_FLAG_STRENGTH_MEDIUM
;
else
flags
|=
SECURITY_FLAG_STRENGTH_WEAK
;
}
*
(
DWORD
*
)
buffer
=
flags
;
return
ERROR_SUCCESS
;
}
...
...
@@ -1940,7 +2118,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
return
ERROR_INSUFFICIENT_BUFFER
;
}
context
=
(
PCCERT_CONTEXT
)
NETCON_GetCert
(
&
(
req
->
netConnection
)
);
context
=
(
PCCERT_CONTEXT
)
NETCON_GetCert
(
req
->
netconn
);
if
(
context
)
{
INTERNET_CERTIFICATE_INFOA
*
info
=
(
INTERNET_CERTIFICATE_INFOA
*
)
buffer
;
DWORD
len
;
...
...
@@ -1962,7 +2140,7 @@ static DWORD HTTPREQ_QueryOption(object_header_t *hdr, DWORD option, void *buffe
CertNameToStrA
(
context
->
dwCertEncodingType
,
&
context
->
pCertInfo
->
Issuer
,
CERT_SIMPLE_NAME_STR
,
info
->
lpszIssuerInfo
,
len
);
info
->
dwKeySize
=
NETCON_GetCipherStrength
(
&
req
->
netConnectio
n
);
info
->
dwKeySize
=
NETCON_GetCipherStrength
(
req
->
netcon
n
);
CertFreeCertificateContext
(
context
);
return
ERROR_SUCCESS
;
}
...
...
@@ -1985,7 +2163,9 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer,
return
ERROR_INVALID_PARAMETER
;
flags
=
*
(
DWORD
*
)
buffer
;
TRACE
(
"%08x
\n
"
,
flags
);
req
->
netConnection
.
security_flags
=
flags
;
req
->
security_flags
=
flags
;
if
(
req
->
netconn
)
req
->
netconn
->
security_flags
=
flags
;
return
ERROR_SUCCESS
;
}
case
INTERNET_OPTION_SEND_TIMEOUT
:
...
...
@@ -1995,12 +2175,12 @@ static DWORD HTTPREQ_SetOption(object_header_t *hdr, DWORD option, void *buffer,
if
(
size
!=
sizeof
(
DWORD
))
return
ERROR_INVALID_PARAMETER
;
if
(
NETCON_connected
(
&
req
->
netConnection
)
)
{
if
(
!
req
->
netconn
)
{
FIXME
(
"unsupported without active connection
\n
"
);
return
ERROR_SUCCESS
;
}
return
NETCON_set_timeout
(
&
req
->
netConnectio
n
,
option
==
INTERNET_OPTION_SEND_TIMEOUT
,
return
NETCON_set_timeout
(
req
->
netcon
n
,
option
==
INTERNET_OPTION_SEND_TIMEOUT
,
*
(
DWORD
*
)
buffer
);
case
INTERNET_OPTION_USERNAME
:
...
...
@@ -2038,7 +2218,7 @@ static DWORD read_more_data( http_request_t *req, int maxlen )
if
(
maxlen
==
-
1
)
maxlen
=
sizeof
(
req
->
read_buf
);
res
=
NETCON_recv
(
&
req
->
netConnectio
n
,
req
->
read_buf
+
req
->
read_size
,
res
=
NETCON_recv
(
req
->
netcon
n
,
req
->
read_buf
+
req
->
read_size
,
maxlen
-
req
->
read_size
,
0
,
&
len
);
if
(
res
==
ERROR_SUCCESS
)
req
->
read_size
+=
len
;
...
...
@@ -2079,7 +2259,7 @@ static BOOL read_line( http_request_t *req, LPSTR buffer, DWORD *len )
if
((
res
=
read_more_data
(
req
,
-
1
))
!=
ERROR_SUCCESS
||
!
req
->
read_size
)
{
*
len
=
0
;
TRACE
(
"returning empty string
\n
"
);
TRACE
(
"returning empty string
%u
\n
"
,
res
);
LeaveCriticalSection
(
&
req
->
read_section
);
INTERNET_SetLastError
(
res
);
return
FALSE
;
...
...
@@ -2133,16 +2313,20 @@ static DWORD get_avail_data( http_request_t *req )
static
DWORD
netconn_get_avail_data
(
data_stream_t
*
stream
,
http_request_t
*
req
)
{
netconn_stream_t
*
netconn_stream
=
(
netconn_stream_t
*
)
stream
;
DWORD
avail
=
0
;
NETCON_query_data_available
(
&
req
->
netConnection
,
&
avail
);
return
avail
;
if
(
req
->
netconn
)
NETCON_query_data_available
(
req
->
netconn
,
&
avail
);
return
netconn_stream
->
content_length
==
~
0u
?
avail
:
min
(
avail
,
netconn_stream
->
content_length
-
netconn_stream
->
content_read
);
}
static
BOOL
netconn_end_of_data
(
data_stream_t
*
stream
,
http_request_t
*
req
)
{
netconn_stream_t
*
netconn_stream
=
(
netconn_stream_t
*
)
stream
;
return
netconn_stream
->
content_read
==
netconn_stream
->
content_length
||
!
NETCON_connected
(
&
req
->
netConnection
)
;
return
netconn_stream
->
content_read
==
netconn_stream
->
content_length
||
!
req
->
netconn
;
}
static
DWORD
netconn_read
(
data_stream_t
*
stream
,
http_request_t
*
req
,
BYTE
*
buf
,
DWORD
size
,
...
...
@@ -2156,8 +2340,8 @@ static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
if
(
read_mode
==
READMODE_NOBLOCK
)
size
=
min
(
size
,
netconn_get_avail_data
(
stream
,
req
));
if
(
size
)
{
if
(
NETCON_recv
(
&
req
->
netConnectio
n
,
buf
,
size
,
read_mode
==
READMODE_SYNC
?
MSG_WAITALL
:
0
,
&
len
)
!=
ERROR_SUCCESS
)
if
(
size
&&
req
->
netconn
)
{
if
(
NETCON_recv
(
req
->
netcon
n
,
buf
,
size
,
read_mode
==
READMODE_SYNC
?
MSG_WAITALL
:
0
,
&
len
)
!=
ERROR_SUCCESS
)
len
=
0
;
}
...
...
@@ -2166,6 +2350,30 @@ static DWORD netconn_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
return
ERROR_SUCCESS
;
}
static
BOOL
netconn_drain_content
(
data_stream_t
*
stream
,
http_request_t
*
req
)
{
netconn_stream_t
*
netconn_stream
=
(
netconn_stream_t
*
)
stream
;
BYTE
buf
[
1024
];
DWORD
avail
;
int
len
;
if
(
netconn_end_of_data
(
stream
,
req
))
return
TRUE
;
do
{
avail
=
netconn_get_avail_data
(
stream
,
req
);
if
(
!
avail
)
return
FALSE
;
if
(
NETCON_recv
(
req
->
netconn
,
buf
,
min
(
avail
,
sizeof
(
buf
)),
0
,
&
len
)
!=
ERROR_SUCCESS
)
return
FALSE
;
netconn_stream
->
content_read
+=
len
;
}
while
(
netconn_stream
->
content_read
<
netconn_stream
->
content_length
);
return
TRUE
;
}
static
void
netconn_destroy
(
data_stream_t
*
stream
)
{
}
...
...
@@ -2174,6 +2382,7 @@ static const data_stream_vtbl_t netconn_stream_vtbl = {
netconn_get_avail_data
,
netconn_end_of_data
,
netconn_read
,
netconn_drain_content
,
netconn_destroy
};
...
...
@@ -2193,7 +2402,7 @@ static DWORD read_more_chunked_data(chunked_stream_t *stream, http_request_t *re
if
(
maxlen
==
-
1
)
maxlen
=
sizeof
(
stream
->
buf
);
res
=
NETCON_recv
(
&
req
->
netConnectio
n
,
stream
->
buf
+
stream
->
buf_size
,
res
=
NETCON_recv
(
req
->
netcon
n
,
stream
->
buf
+
stream
->
buf_size
,
maxlen
-
stream
->
buf_size
,
0
,
&
len
);
if
(
res
==
ERROR_SUCCESS
)
stream
->
buf_size
+=
len
;
...
...
@@ -2302,7 +2511,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
if
(
read_mode
==
READMODE_NOBLOCK
)
{
DWORD
avail
;
if
(
!
NETCON_query_data_available
(
&
req
->
netConnectio
n
,
&
avail
)
||
!
avail
)
if
(
!
NETCON_query_data_available
(
req
->
netcon
n
,
&
avail
)
||
!
avail
)
break
;
if
(
read_bytes
>
avail
)
read_bytes
=
avail
;
...
...
@@ -2312,7 +2521,7 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
break
;
}
res
=
NETCON_recv
(
&
req
->
netConnectio
n
,
(
char
*
)
buf
+
ret_read
,
read_bytes
,
0
,
(
int
*
)
&
read_bytes
);
res
=
NETCON_recv
(
req
->
netcon
n
,
(
char
*
)
buf
+
ret_read
,
read_bytes
,
0
,
(
int
*
)
&
read_bytes
);
if
(
res
!=
ERROR_SUCCESS
)
break
;
}
...
...
@@ -2336,6 +2545,14 @@ static DWORD chunked_read(data_stream_t *stream, http_request_t *req, BYTE *buf,
return
res
;
}
static
BOOL
chunked_drain_content
(
data_stream_t
*
stream
,
http_request_t
*
req
)
{
chunked_stream_t
*
chunked_stream
=
(
chunked_stream_t
*
)
stream
;
/* FIXME: we can do better */
return
!
chunked_stream
->
chunk_size
;
}
static
void
chunked_destroy
(
data_stream_t
*
stream
)
{
chunked_stream_t
*
chunked_stream
=
(
chunked_stream_t
*
)
stream
;
...
...
@@ -2346,6 +2563,7 @@ static const data_stream_vtbl_t chunked_stream_vtbl = {
chunked_get_avail_data
,
chunked_end_of_data
,
chunked_read
,
chunked_drain_content
,
chunked_destroy
};
...
...
@@ -2464,7 +2682,7 @@ static DWORD HTTPREQ_Read(http_request_t *req, void *buffer, DWORD size, DWORD *
}
if
(
end_of_read_data
(
req
))
HTTP_FinishedReading
(
req
);
http_release_netconn
(
req
,
TRUE
);
return
res
;
}
...
...
@@ -2710,7 +2928,7 @@ static DWORD HTTPREQ_WriteFile(object_header_t *hdr, const void *buffer, DWORD s
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_SENDING_REQUEST
,
NULL
,
0
);
*
written
=
0
;
res
=
NETCON_send
(
&
request
->
netConnectio
n
,
buffer
,
size
,
0
,
(
LPINT
)
written
);
res
=
NETCON_send
(
request
->
netcon
n
,
buffer
,
size
,
0
,
(
LPINT
)
written
);
if
(
res
==
ERROR_SUCCESS
)
request
->
bytesWritten
+=
*
written
;
...
...
@@ -2795,15 +3013,12 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
LPCWSTR
lpszReferrer
,
LPCWSTR
*
lpszAcceptTypes
,
DWORD
dwFlags
,
DWORD_PTR
dwContext
,
HINTERNET
*
ret
)
{
appinfo_t
*
hIC
=
NULL
;
appinfo_t
*
hIC
=
session
->
appInfo
;
http_request_t
*
request
;
DWORD
len
,
res
;
DWORD
len
,
res
=
ERROR_SUCCESS
;
TRACE
(
"-->
\n
"
);
assert
(
session
->
hdr
.
htype
==
WH_HHTTPSESSION
);
hIC
=
session
->
appInfo
;
request
=
alloc_object
(
&
session
->
hdr
,
&
HTTPREQVtbl
,
sizeof
(
http_request_t
));
if
(
!
request
)
return
ERROR_OUTOFMEMORY
;
...
...
@@ -2822,12 +3037,10 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
request
->
session
=
session
;
list_add_head
(
&
session
->
hdr
.
children
,
&
request
->
hdr
.
entry
);
if
((
res
=
NETCON_init
(
&
request
->
netConnection
,
dwFlags
&
INTERNET_FLAG_SECURE
))
!=
ERROR_SUCCESS
)
goto
lend
;
if
(
dwFlags
&
INTERNET_FLAG_IGNORE_CERT_CN_INVALID
)
request
->
netConnection
.
security_flags
|=
SECURITY_FLAG_IGNORE_CERT_CN_INVALID
;
request
->
security_flags
|=
SECURITY_FLAG_IGNORE_CERT_CN_INVALID
;
if
(
dwFlags
&
INTERNET_FLAG_IGNORE_CERT_DATE_INVALID
)
request
->
netConnection
.
security_flags
|=
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
;
request
->
security_flags
|=
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
;
if
(
lpszObjectName
&&
*
lpszObjectName
)
{
HRESULT
rc
;
...
...
@@ -2901,7 +3114,7 @@ static DWORD HTTP_HttpOpenRequestW(http_session_t *session,
INTERNET_DEFAULT_HTTPS_PORT
:
INTERNET_DEFAULT_HTTP_PORT
);
if
(
NULL
!=
hIC
->
proxy
&&
hIC
->
proxy
[
0
]
!=
0
)
if
(
hIC
->
proxy
&&
hIC
->
proxy
[
0
]
)
HTTP_DealWithProxy
(
hIC
,
session
,
request
);
INTERNET_SendCallback
(
&
session
->
hdr
,
dwContext
,
...
...
@@ -2977,29 +3190,6 @@ lend:
return
handle
;
}
/* read any content returned by the server so that the connection can be
* reused */
static
void
HTTP_DrainContent
(
http_request_t
*
req
)
{
DWORD
bytes_read
;
if
(
!
NETCON_connected
(
&
req
->
netConnection
))
return
;
if
(
req
->
contentLength
==
-
1
)
{
NETCON_close
(
&
req
->
netConnection
);
return
;
}
if
(
!
strcmpW
(
req
->
verb
,
szHEAD
))
return
;
do
{
char
buffer
[
2048
];
if
(
HTTPREQ_Read
(
req
,
buffer
,
sizeof
(
buffer
),
&
bytes_read
,
TRUE
)
!=
ERROR_SUCCESS
)
return
;
}
while
(
bytes_read
);
}
static
const
LPCWSTR
header_lookup
[]
=
{
szMime_Version
,
/* HTTP_QUERY_MIME_VERSION = 0 */
szContent_Type
,
/* HTTP_QUERY_CONTENT_TYPE = 1 */
...
...
@@ -3653,29 +3843,15 @@ static DWORD HTTP_HandleRedirect(http_request_t *request, LPCWSTR lpszUrl)
if
(
userName
[
0
])
session
->
userName
=
heap_strdupW
(
userName
);
if
(
!
using_proxy
)
{
if
(
strcmpiW
(
session
->
serverName
,
hostName
)
||
session
->
serverPort
!=
urlComponents
.
nPort
)
{
DWORD
res
;
reset_data_stream
(
request
);
if
(
!
using_proxy
)
{
if
(
strcmpiW
(
session
->
serverName
,
hostName
))
{
HeapFree
(
GetProcessHeap
(),
0
,
session
->
serverName
);
session
->
serverName
=
heap_strdupW
(
hostName
);
session
->
serverPort
=
urlComponents
.
nPort
;
NETCON_close
(
&
request
->
netConnection
);
if
((
res
=
HTTP_ResolveName
(
request
))
!=
ERROR_SUCCESS
)
return
res
;
res
=
NETCON_init
(
&
request
->
netConnection
,
request
->
hdr
.
dwFlags
&
INTERNET_FLAG_SECURE
);
if
(
res
!=
ERROR_SUCCESS
)
return
res
;
reset_data_stream
(
request
);
}
session
->
serverPort
=
urlComponents
.
nPort
;
}
else
TRACE
(
"Redirect through proxy
\n
"
);
}
HeapFree
(
GetProcessHeap
(),
0
,
request
->
path
);
...
...
@@ -3762,7 +3938,7 @@ static DWORD HTTP_SecureProxyConnect(http_request_t *request)
TRACE
(
"full request -> %s
\n
"
,
debugstr_an
(
ascii_req
,
len
)
);
res
=
NETCON_send
(
&
request
->
netConnectio
n
,
ascii_req
,
len
,
0
,
&
cnt
);
res
=
NETCON_send
(
request
->
netcon
n
,
ascii_req
,
len
,
0
,
&
cnt
);
HeapFree
(
GetProcessHeap
(),
0
,
ascii_req
);
if
(
res
!=
ERROR_SUCCESS
)
return
res
;
...
...
@@ -4189,6 +4365,17 @@ static void HTTP_ProcessLastModified(http_request_t *request)
}
}
static
void
http_process_keep_alive
(
http_request_t
*
req
)
{
int
index
;
index
=
HTTP_GetCustomHeaderIndex
(
req
,
szConnection
,
0
,
FALSE
);
if
(
index
!=
-
1
)
req
->
netconn
->
keep_alive
=
!
strcmpiW
(
req
->
custHeaders
[
index
].
lpszValue
,
szKeepAlive
);
else
req
->
netconn
->
keep_alive
=
!
strcmpiW
(
req
->
version
,
g_szHttp1_1
);
}
static
void
HTTP_CacheRequest
(
http_request_t
*
request
)
{
WCHAR
url
[
INTERNET_MAX_URL_LENGTH
];
...
...
@@ -4218,6 +4405,105 @@ static void HTTP_CacheRequest(http_request_t *request)
}
}
static
DWORD
open_http_connection
(
http_request_t
*
request
,
BOOL
*
reusing
)
{
const
BOOL
is_https
=
(
request
->
hdr
.
dwFlags
&
INTERNET_FLAG_SECURE
)
!=
0
;
http_session_t
*
session
=
request
->
session
;
netconn_t
*
netconn
=
NULL
;
server_t
*
server
;
DWORD
res
;
assert
(
!
request
->
netconn
);
reset_data_stream
(
request
);
server
=
get_server
(
session
->
serverName
,
session
->
serverPort
);
if
(
!
server
)
return
ERROR_OUTOFMEMORY
;
res
=
HTTP_ResolveName
(
request
,
server
);
if
(
res
!=
ERROR_SUCCESS
)
{
server_release
(
server
);
return
res
;
}
EnterCriticalSection
(
&
connection_pool_cs
);
while
(
!
list_empty
(
&
server
->
conn_pool
))
{
netconn
=
LIST_ENTRY
(
list_head
(
&
server
->
conn_pool
),
netconn_t
,
pool_entry
);
list_remove
(
&
netconn
->
pool_entry
);
if
(
NETCON_is_alive
(
netconn
))
break
;
TRACE
(
"connection %p closed during idle
\n
"
,
netconn
);
free_netconn
(
netconn
);
netconn
=
NULL
;
}
LeaveCriticalSection
(
&
connection_pool_cs
);
if
(
netconn
)
{
TRACE
(
"<-- reusing %p netconn
\n
"
,
netconn
);
request
->
netconn
=
netconn
;
*
reusing
=
TRUE
;
return
ERROR_SUCCESS
;
}
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_CONNECTING_TO_SERVER
,
server
->
addr_str
,
strlen
(
server
->
addr_str
)
+
1
);
res
=
create_netconn
(
is_https
,
server
,
request
->
security_flags
,
&
netconn
);
server_release
(
server
);
if
(
res
!=
ERROR_SUCCESS
)
{
ERR
(
"create_netconn failed: %u
\n
"
,
res
);
return
res
;
}
request
->
netconn
=
netconn
;
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_CONNECTED_TO_SERVER
,
server
->
addr_str
,
strlen
(
server
->
addr_str
)
+
1
);
if
(
is_https
)
{
/* Note: we differ from Microsoft's WinINet here. they seem to have
* a bug that causes no status callbacks to be sent when starting
* a tunnel to a proxy server using the CONNECT verb. i believe our
* behaviour to be more correct and to not cause any incompatibilities
* because using a secure connection through a proxy server is a rare
* case that would be hard for anyone to depend on */
if
(
session
->
appInfo
->
proxy
)
res
=
HTTP_SecureProxyConnect
(
request
);
if
(
res
==
ERROR_SUCCESS
)
res
=
NETCON_secure_connect
(
request
->
netconn
,
session
->
hostName
);
if
(
res
!=
ERROR_SUCCESS
)
{
WARN
(
"Couldn't connect securely to host
\n
"
);
if
((
request
->
hdr
.
ErrorMask
&
INTERNET_ERROR_MASK_COMBINED_SEC_CERT
)
&&
(
res
==
ERROR_INTERNET_SEC_CERT_DATE_INVALID
||
res
==
ERROR_INTERNET_INVALID_CA
||
res
==
ERROR_INTERNET_SEC_CERT_NO_REV
||
res
==
ERROR_INTERNET_SEC_CERT_REV_FAILED
||
res
==
ERROR_INTERNET_SEC_CERT_REVOKED
||
res
==
ERROR_INTERNET_SEC_INVALID_CERT
||
res
==
ERROR_INTERNET_SEC_CERT_CN_INVALID
))
res
=
ERROR_INTERNET_SEC_CERT_ERRORS
;
}
}
if
(
res
!=
ERROR_SUCCESS
)
{
http_release_netconn
(
request
,
FALSE
);
return
res
;
}
*
reusing
=
FALSE
;
TRACE
(
"Created connection to %s: %p
\n
"
,
debugstr_w
(
server
->
name
),
netconn
);
return
ERROR_SUCCESS
;
}
/***********************************************************************
* HTTP_HttpSendRequestW (internal)
*
...
...
@@ -4293,7 +4579,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
/* like native, just in case the caller forgot to call InternetReadFile
* for all the data */
HTTP_DrainC
ontent
(
request
);
drain_c
ontent
(
request
);
if
(
redirected
)
{
request
->
contentLength
=
~
0u
;
request
->
bytesToWrite
=
0
;
...
...
@@ -4335,14 +4621,8 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
TRACE
(
"Request header -> %s
\n
"
,
debugstr_w
(
requestString
)
);
/* Send the request and store the results */
if
(
NETCON_connected
(
&
request
->
netConnection
))
reusing_connection
=
TRUE
;
else
reusing_connection
=
FALSE
;
if
((
res
=
HTTP_OpenConnection
(
request
))
!=
ERROR_SUCCESS
)
goto
lend
;
if
((
res
=
open_http_connection
(
request
,
&
reusing_connection
))
!=
ERROR_SUCCESS
)
break
;
/* send the request as ASCII, tack on the optional data */
if
(
!
lpOptional
||
redirected
)
...
...
@@ -4361,8 +4641,16 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_SENDING_REQUEST
,
NULL
,
0
);
res
=
NETCON_send
(
&
request
->
netConnectio
n
,
ascii_req
,
len
,
0
,
&
cnt
);
res
=
NETCON_send
(
request
->
netcon
n
,
ascii_req
,
len
,
0
,
&
cnt
);
HeapFree
(
GetProcessHeap
(),
0
,
ascii_req
);
if
(
res
!=
ERROR_SUCCESS
)
{
TRACE
(
"send failed: %u
\n
"
,
res
);
if
(
!
reusing_connection
)
break
;
http_release_netconn
(
request
,
FALSE
);
loop_next
=
TRUE
;
continue
;
}
request
->
bytesWritten
=
dwOptionalLength
;
...
...
@@ -4378,22 +4666,21 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_RECEIVING_RESPONSE
,
NULL
,
0
);
if
(
res
!=
ERROR_SUCCESS
)
goto
lend
;
responseLen
=
HTTP_GetResponseHeaders
(
request
,
TRUE
);
/* FIXME: We should know that connection is closed before sending
* headers. Otherwise wrong callbacks are executed */
if
(
!
responseLen
&&
reusing_connection
)
{
TRACE
(
"Connection closed by server, reconnecting
\n
"
);
http_release_netconn
(
request
,
FALSE
);
loop_next
=
TRUE
;
continue
;
}
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_RESPONSE_RECEIVED
,
&
responseLen
,
sizeof
(
DWORD
));
http_process_keep_alive
(
request
);
HTTP_ProcessCookies
(
request
);
HTTP_ProcessExpires
(
request
);
HTTP_ProcessLastModified
(
request
);
...
...
@@ -4402,7 +4689,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
if
(
res
!=
ERROR_SUCCESS
)
goto
lend
;
if
(
!
request
->
contentLength
)
HTTP_FinishedReading
(
request
);
http_release_netconn
(
request
,
TRUE
);
dwBufferSize
=
sizeof
(
dwStatusCode
);
if
(
HTTP_HttpQueryInfoW
(
request
,
HTTP_QUERY_FLAG_NUMBER
|
HTTP_QUERY_STATUS_CODE
,
...
...
@@ -4424,7 +4711,7 @@ static DWORD HTTP_HttpSendRequestW(http_request_t *request, LPCWSTR lpszHeaders,
HeapFree
(
GetProcessHeap
(),
0
,
request
->
verb
);
request
->
verb
=
heap_strdupW
(
szGET
);
}
HTTP_DrainC
ontent
(
request
);
drain_c
ontent
(
request
);
if
((
new_url
=
HTTP_GetRedirectURL
(
request
,
szNewLocation
)))
{
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_REDIRECT
,
...
...
@@ -4562,13 +4849,14 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
INTERNET_STATUS_RESPONSE_RECEIVED
,
&
responseLen
,
sizeof
(
DWORD
));
/* process cookies here. Is this right? */
http_process_keep_alive
(
request
);
HTTP_ProcessCookies
(
request
);
HTTP_ProcessExpires
(
request
);
HTTP_ProcessLastModified
(
request
);
if
((
res
=
set_content_length
(
request
))
==
ERROR_SUCCESS
)
{
if
(
!
request
->
contentLength
)
HTTP_FinishedReading
(
request
);
http_release_netconn
(
request
,
TRUE
);
}
if
(
res
==
ERROR_SUCCESS
&&
!
(
request
->
hdr
.
dwFlags
&
INTERNET_FLAG_NO_AUTO_REDIRECT
))
...
...
@@ -4589,7 +4877,7 @@ static DWORD HTTP_HttpEndRequestW(http_request_t *request, DWORD dwFlags, DWORD_
HeapFree
(
GetProcessHeap
(),
0
,
request
->
verb
);
request
->
verb
=
heap_strdupW
(
szGET
);
}
HTTP_DrainC
ontent
(
request
);
drain_c
ontent
(
request
);
if
((
new_url
=
HTTP_GetRedirectURL
(
request
,
szNewLocation
)))
{
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_REDIRECT
,
...
...
@@ -5128,117 +5416,6 @@ DWORD HTTP_Connect(appinfo_t *hIC, LPCWSTR lpszServerName,
return
ERROR_SUCCESS
;
}
/***********************************************************************
* HTTP_OpenConnection (internal)
*
* Connect to a web server
*
* RETURNS
*
* TRUE on success
* FALSE on failure
*/
static
DWORD
HTTP_OpenConnection
(
http_request_t
*
request
)
{
http_session_t
*
session
;
appinfo_t
*
hIC
=
NULL
;
char
szaddr
[
INET6_ADDRSTRLEN
];
const
void
*
addr
;
DWORD
res
=
ERROR_SUCCESS
;
TRACE
(
"-->
\n
"
);
if
(
request
->
hdr
.
htype
!=
WH_HHTTPREQ
)
{
res
=
ERROR_INVALID_PARAMETER
;
goto
lend
;
}
if
(
NETCON_connected
(
&
request
->
netConnection
))
goto
lend
;
if
((
res
=
HTTP_ResolveName
(
request
))
!=
ERROR_SUCCESS
)
goto
lend
;
session
=
request
->
session
;
hIC
=
session
->
appInfo
;
switch
(
session
->
socketAddress
.
ss_family
)
{
case
AF_INET
:
addr
=
&
((
struct
sockaddr_in
*
)
&
session
->
socketAddress
)
->
sin_addr
;
break
;
case
AF_INET6
:
addr
=
&
((
struct
sockaddr_in6
*
)
&
session
->
socketAddress
)
->
sin6_addr
;
break
;
default:
WARN
(
"unsupported family %d
\n
"
,
session
->
socketAddress
.
ss_family
);
return
ERROR_INTERNET_NAME_NOT_RESOLVED
;
}
inet_ntop
(
session
->
socketAddress
.
ss_family
,
addr
,
szaddr
,
sizeof
(
szaddr
));
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_CONNECTING_TO_SERVER
,
szaddr
,
strlen
(
szaddr
)
+
1
);
res
=
NETCON_create
(
&
request
->
netConnection
,
session
->
socketAddress
.
ss_family
,
SOCK_STREAM
,
0
);
if
(
res
!=
ERROR_SUCCESS
)
{
WARN
(
"Socket creation failed: %u
\n
"
,
res
);
goto
lend
;
}
res
=
NETCON_connect
(
&
request
->
netConnection
,
(
struct
sockaddr
*
)
&
session
->
socketAddress
,
session
->
sa_len
);
if
(
res
!=
ERROR_SUCCESS
)
goto
lend
;
INTERNET_SendCallback
(
&
request
->
hdr
,
request
->
hdr
.
dwContext
,
INTERNET_STATUS_CONNECTED_TO_SERVER
,
szaddr
,
strlen
(
szaddr
)
+
1
);
if
(
request
->
hdr
.
dwFlags
&
INTERNET_FLAG_SECURE
)
{
/* Note: we differ from Microsoft's WinINet here. they seem to have
* a bug that causes no status callbacks to be sent when starting
* a tunnel to a proxy server using the CONNECT verb. i believe our
* behaviour to be more correct and to not cause any incompatibilities
* because using a secure connection through a proxy server is a rare
* case that would be hard for anyone to depend on */
if
(
hIC
->
proxy
&&
(
res
=
HTTP_SecureProxyConnect
(
request
))
!=
ERROR_SUCCESS
)
{
HTTPREQ_CloseConnection
(
&
request
->
hdr
);
goto
lend
;
}
res
=
NETCON_secure_connect
(
&
request
->
netConnection
,
session
->
hostName
);
if
(
res
!=
ERROR_SUCCESS
)
{
WARN
(
"Couldn't connect securely to host
\n
"
);
if
((
request
->
hdr
.
ErrorMask
&
INTERNET_ERROR_MASK_COMBINED_SEC_CERT
)
&&
(
res
==
ERROR_INTERNET_SEC_CERT_DATE_INVALID
||
res
==
ERROR_INTERNET_INVALID_CA
||
res
==
ERROR_INTERNET_SEC_CERT_NO_REV
||
res
==
ERROR_INTERNET_SEC_CERT_REV_FAILED
||
res
==
ERROR_INTERNET_SEC_CERT_REVOKED
||
res
==
ERROR_INTERNET_SEC_INVALID_CERT
||
res
==
ERROR_INTERNET_SEC_CERT_CN_INVALID
))
res
=
ERROR_INTERNET_SEC_CERT_ERRORS
;
HTTPREQ_CloseConnection
(
&
request
->
hdr
);
goto
lend
;
}
}
lend:
reset_data_stream
(
request
);
TRACE
(
"%d <--
\n
"
,
res
);
return
res
;
}
/***********************************************************************
* HTTP_clear_response_headers (internal)
*
...
...
@@ -5288,7 +5465,7 @@ static INT HTTP_GetResponseHeaders(http_request_t *request, BOOL clear)
TRACE
(
"-->
\n
"
);
if
(
!
NETCON_connected
(
&
request
->
netConnection
)
)
if
(
!
request
->
netconn
)
goto
lend
;
do
{
...
...
@@ -5623,31 +5800,6 @@ static DWORD HTTP_ProcessHeader(http_request_t *request, LPCWSTR field, LPCWSTR
return
res
;
}
/***********************************************************************
* HTTP_FinishedReading (internal)
*
* Called when all content from server has been read by client.
*
*/
static
BOOL
HTTP_FinishedReading
(
http_request_t
*
request
)
{
BOOL
keepalive
=
HTTP_KeepAlive
(
request
);
TRACE
(
"
\n
"
);
if
(
!
keepalive
)
{
HTTPREQ_CloseConnection
(
&
request
->
hdr
);
}
/* FIXME: store data in the URL cache here */
return
TRUE
;
}
/***********************************************************************
* HTTP_GetCustomHeaderIndex (internal)
*
...
...
dlls/wininet/internet.c
View file @
8a1df203
...
...
@@ -308,7 +308,7 @@ BOOL WINAPI DllMain (HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
break
;
case
DLL_PROCESS_DETACH
:
collect_connections
(
TRUE
);
NETCON_unload
();
URLCacheContainers_DeleteAll
();
...
...
dlls/wininet/internet.h
View file @
8a1df203
...
...
@@ -49,13 +49,40 @@
extern
HMODULE
WININET_hModule
;
#ifndef INET6_ADDRSTRLEN
#define INET6_ADDRSTRLEN 46
#endif
typedef
struct
{
WCHAR
*
name
;
INTERNET_PORT
port
;
struct
sockaddr_storage
addr
;
socklen_t
addr_len
;
char
addr_str
[
INET6_ADDRSTRLEN
];
LONG
ref
;
DWORD64
keep_until
;
struct
list
entry
;
struct
list
conn_pool
;
}
server_t
;
void
server_addref
(
server_t
*
);
void
server_release
(
server_t
*
);
BOOL
collect_connections
(
BOOL
);
/* used for netconnection.c stuff */
typedef
struct
{
BOOL
useSSL
;
int
socketFD
;
void
*
ssl_s
;
server_t
*
server
;
DWORD
security_flags
;
BOOL
keep_alive
;
DWORD64
keep_until
;
struct
list
pool_entry
;
}
netconn_t
;
static
inline
void
*
__WINE_ALLOC_SIZE
(
1
)
heap_alloc
(
size_t
len
)
...
...
@@ -228,7 +255,6 @@ typedef struct
DWORD
accessType
;
}
appinfo_t
;
typedef
struct
{
object_header_t
hdr
;
...
...
@@ -239,8 +265,6 @@ typedef struct
LPWSTR
password
;
INTERNET_PORT
hostPort
;
/* the final destination port of the request */
INTERNET_PORT
serverPort
;
/* the port of the server we directly connect to */
struct
sockaddr_storage
socketAddress
;
socklen_t
sa_len
;
}
http_session_t
;
#define HDR_ISREQUEST 0x0001
...
...
@@ -279,7 +303,8 @@ typedef struct
LPWSTR
path
;
LPWSTR
verb
;
LPWSTR
rawHeaders
;
netconn_t
netConnection
;
netconn_t
*
netconn
;
DWORD
security_flags
;
LPWSTR
version
;
LPWSTR
statusText
;
DWORD
bytesToWrite
;
...
...
@@ -487,20 +512,16 @@ VOID INTERNET_SendCallback(object_header_t *hdr, DWORD_PTR dwContext,
DWORD
dwStatusInfoLength
)
DECLSPEC_HIDDEN
;
BOOL
INTERNET_FindProxyForProtocol
(
LPCWSTR
szProxy
,
LPCWSTR
proto
,
WCHAR
*
foundProxy
,
DWORD
*
foundProxyLen
)
DECLSPEC_HIDDEN
;
BOOL
NETCON_connected
(
netconn_t
*
connection
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_init
(
netconn_t
*
connnection
,
BOOL
useSSL
)
DECLSPEC_HIDDEN
;
DWORD
create_netconn
(
BOOL
,
server_t
*
,
DWORD
,
netconn_t
**
)
DECLSPEC_HIDDEN
;
void
free_netconn
(
netconn_t
*
)
DECLSPEC_HIDDEN
;
void
NETCON_unload
(
void
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_create
(
netconn_t
*
connection
,
int
domain
,
int
type
,
int
protocol
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_close
(
netconn_t
*
connection
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_connect
(
netconn_t
*
connection
,
const
struct
sockaddr
*
serv_addr
,
unsigned
int
addrlen
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_secure_connect
(
netconn_t
*
connection
,
LPWSTR
hostname
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_send
(
netconn_t
*
connection
,
const
void
*
msg
,
size_t
len
,
int
flags
,
int
*
sent
/* out */
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_recv
(
netconn_t
*
connection
,
void
*
buf
,
size_t
len
,
int
flags
,
int
*
recvd
/* out */
)
DECLSPEC_HIDDEN
;
BOOL
NETCON_query_data_available
(
netconn_t
*
connection
,
DWORD
*
available
)
DECLSPEC_HIDDEN
;
BOOL
NETCON_is_alive
(
netconn_t
*
)
DECLSPEC_HIDDEN
;
LPCVOID
NETCON_GetCert
(
netconn_t
*
connection
)
DECLSPEC_HIDDEN
;
int
NETCON_GetCipherStrength
(
netconn_t
*
)
DECLSPEC_HIDDEN
;
DWORD
NETCON_set_timeout
(
netconn_t
*
connection
,
BOOL
send
,
int
value
)
DECLSPEC_HIDDEN
;
...
...
dlls/wininet/netconnection.c
View file @
8a1df203
...
...
@@ -70,6 +70,7 @@
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include "wine/library.h"
#include "windef.h"
...
...
@@ -493,22 +494,64 @@ static DWORD init_openssl(void)
#endif
}
DWORD
NETCON_init
(
netconn_t
*
connection
,
BOOL
useSSL
)
DWORD
create_netconn
(
BOOL
useSSL
,
server_t
*
server
,
DWORD
security_flags
,
netconn_t
**
ret
)
{
DWORD
res
=
ERROR_SUCCESS
;
netconn_t
*
netconn
;
int
result
;
connection
->
useSSL
=
useSSL
;
connection
->
socketFD
=
-
1
;
if
(
useSSL
)
{
DWORD
res
;
if
(
useSSL
)
{
TRACE
(
"using SSL connection
\n
"
);
EnterCriticalSection
(
&
init_ssl_cs
);
res
=
init_openssl
();
LeaveCriticalSection
(
&
init_ssl_cs
);
if
(
res
!=
ERROR_SUCCESS
)
return
res
;
}
return
res
;
netconn
=
heap_alloc_zero
(
sizeof
(
*
netconn
));
if
(
!
netconn
)
return
ERROR_OUTOFMEMORY
;
netconn
->
useSSL
=
useSSL
;
netconn
->
socketFD
=
-
1
;
netconn
->
security_flags
=
security_flags
;
list_init
(
&
netconn
->
pool_entry
);
assert
(
server
->
addr_len
);
result
=
netconn
->
socketFD
=
socket
(
server
->
addr
.
ss_family
,
SOCK_STREAM
,
0
);
if
(
result
!=
-
1
)
{
result
=
connect
(
netconn
->
socketFD
,
(
struct
sockaddr
*
)
&
server
->
addr
,
server
->
addr_len
);
if
(
result
==
-
1
)
closesocket
(
netconn
->
socketFD
);
}
if
(
result
==
-
1
)
{
heap_free
(
netconn
);
return
sock_get_error
(
errno
);
}
server_addref
(
server
);
netconn
->
server
=
server
;
*
ret
=
netconn
;
return
ERROR_SUCCESS
;
}
void
free_netconn
(
netconn_t
*
netconn
)
{
server_release
(
netconn
->
server
);
#ifdef SONAME_LIBSSL
if
(
netconn
->
ssl_s
)
{
pSSL_shutdown
(
netconn
->
ssl_s
);
pSSL_free
(
netconn
->
ssl_s
);
}
#endif
closesocket
(
netconn
->
socketFD
);
heap_free
(
netconn
);
}
void
NETCON_unload
(
void
)
...
...
@@ -534,11 +577,6 @@ void NETCON_unload(void)
#endif
}
BOOL
NETCON_connected
(
netconn_t
*
connection
)
{
return
connection
->
socketFD
!=
-
1
;
}
/* translate a unix error code into a winsock one */
int
sock_get_error
(
int
err
)
{
...
...
@@ -607,52 +645,6 @@ int sock_get_error( int err )
}
/******************************************************************************
* NETCON_create
* Basically calls 'socket()'
*/
DWORD
NETCON_create
(
netconn_t
*
connection
,
int
domain
,
int
type
,
int
protocol
)
{
#ifdef SONAME_LIBSSL
if
(
connection
->
ssl_s
)
return
ERROR_NOT_SUPPORTED
;
#endif
connection
->
socketFD
=
socket
(
domain
,
type
,
protocol
);
if
(
connection
->
socketFD
==
-
1
)
return
sock_get_error
(
errno
);
return
ERROR_SUCCESS
;
}
/******************************************************************************
* NETCON_close
* Basically calls 'close()' unless we should use SSL
*/
DWORD
NETCON_close
(
netconn_t
*
connection
)
{
int
result
;
if
(
!
NETCON_connected
(
connection
))
return
ERROR_SUCCESS
;
#ifdef SONAME_LIBSSL
if
(
connection
->
ssl_s
)
{
pSSL_shutdown
(
connection
->
ssl_s
);
pSSL_free
(
connection
->
ssl_s
);
connection
->
ssl_s
=
NULL
;
}
#endif
result
=
closesocket
(
connection
->
socketFD
);
connection
->
socketFD
=
-
1
;
if
(
result
==
-
1
)
return
sock_get_error
(
errno
);
return
ERROR_SUCCESS
;
}
/******************************************************************************
* NETCON_secure_connect
* Initiates a secure connection over an existing plaintext connection.
*/
...
...
@@ -722,28 +714,6 @@ fail:
}
/******************************************************************************
* NETCON_connect
* Connects to the specified address.
*/
DWORD
NETCON_connect
(
netconn_t
*
connection
,
const
struct
sockaddr
*
serv_addr
,
unsigned
int
addrlen
)
{
int
result
;
result
=
connect
(
connection
->
socketFD
,
serv_addr
,
addrlen
);
if
(
result
==
-
1
)
{
WARN
(
"Unable to connect to host (%s)
\n
"
,
strerror
(
errno
));
closesocket
(
connection
->
socketFD
);
connection
->
socketFD
=
-
1
;
return
sock_get_error
(
errno
);
}
return
ERROR_SUCCESS
;
}
/******************************************************************************
* NETCON_send
* Basically calls 'send()' unless we should use SSL
* number of chars send is put in *sent
...
...
@@ -751,7 +721,6 @@ DWORD NETCON_connect(netconn_t *connection, const struct sockaddr *serv_addr,
DWORD
NETCON_send
(
netconn_t
*
connection
,
const
void
*
msg
,
size_t
len
,
int
flags
,
int
*
sent
/* out */
)
{
if
(
!
NETCON_connected
(
connection
))
return
ERROR_INTERNET_CONNECTION_ABORTED
;
if
(
!
connection
->
useSSL
)
{
*
sent
=
send
(
connection
->
socketFD
,
msg
,
len
,
flags
);
...
...
@@ -787,14 +756,11 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags,
int
*
recvd
/* out */
)
{
*
recvd
=
0
;
if
(
!
NETCON_connected
(
connection
))
return
ERROR_INTERNET_CONNECTION_ABORTED
;
if
(
!
len
)
return
ERROR_SUCCESS
;
if
(
!
connection
->
useSSL
)
{
*
recvd
=
recv
(
connection
->
socketFD
,
buf
,
len
,
flags
);
if
(
!*
recvd
)
NETCON_close
(
connection
);
return
*
recvd
==
-
1
?
sock_get_error
(
errno
)
:
ERROR_SUCCESS
;
}
else
...
...
@@ -808,10 +774,8 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags,
/* Check if EOF was received */
if
(
!*
recvd
&&
(
pSSL_get_error
(
connection
->
ssl_s
,
*
recvd
)
==
SSL_ERROR_ZERO_RETURN
||
pSSL_get_error
(
connection
->
ssl_s
,
*
recvd
)
==
SSL_ERROR_SYSCALL
))
{
NETCON_close
(
connection
);
||
pSSL_get_error
(
connection
->
ssl_s
,
*
recvd
)
==
SSL_ERROR_SYSCALL
))
return
ERROR_SUCCESS
;
}
return
*
recvd
>
0
?
ERROR_SUCCESS
:
ERROR_INTERNET_CONNECTION_ABORTED
;
#else
...
...
@@ -828,8 +792,6 @@ DWORD NETCON_recv(netconn_t *connection, void *buf, size_t len, int flags,
BOOL
NETCON_query_data_available
(
netconn_t
*
connection
,
DWORD
*
available
)
{
*
available
=
0
;
if
(
!
NETCON_connected
(
connection
))
return
FALSE
;
if
(
!
connection
->
useSSL
)
{
...
...
@@ -852,6 +814,36 @@ BOOL NETCON_query_data_available(netconn_t *connection, DWORD *available)
return
TRUE
;
}
BOOL
NETCON_is_alive
(
netconn_t
*
netconn
)
{
#ifdef MSG_DONTWAIT
ssize_t
len
;
BYTE
b
;
len
=
recv
(
netconn
->
socketFD
,
&
b
,
1
,
MSG_PEEK
|
MSG_DONTWAIT
);
return
len
==
1
||
(
len
==
-
1
&&
errno
==
EWOULDBLOCK
);
#elif defined(__MINGW32__) || defined(_MSC_VER)
ULONG
mode
;
int
len
;
char
b
;
mode
=
1
;
if
(
!
ioctlsocket
(
netconn
->
socketFD
,
FIONBIO
,
&
mode
))
return
FALSE
;
len
=
recv
(
netconn
->
socketFD
,
&
b
,
1
,
MSG_PEEK
);
mode
=
0
;
if
(
!
ioctlsocket
(
netconn
->
socketFD
,
FIONBIO
,
&
mode
))
return
FALSE
;
return
len
==
1
||
(
len
==
-
1
&&
errno
==
WSAEWOULDBLOCK
);
#else
FIXME
(
"not supported on this platform
\n
"
);
return
TRUE
;
#endif
}
LPCVOID
NETCON_GetCert
(
netconn_t
*
connection
)
{
#ifdef SONAME_LIBSSL
...
...
dlls/wininet/tests/http.c
View file @
8a1df203
...
...
@@ -386,17 +386,8 @@ static void InternetReadFile_test(int flags, const test_data_t *test)
{
SET_EXPECT
(
INTERNET_STATUS_RESOLVING_NAME
);
SET_EXPECT
(
INTERNET_STATUS_NAME_RESOLVED
);
SET_WINE_ALLOW
(
INTERNET_STATUS_RESOLVING_NAME
);
SET_WINE_ALLOW
(
INTERNET_STATUS_NAME_RESOLVED
);
}
else
{
SET_WINE_ALLOW2
(
INTERNET_STATUS_RESOLVING_NAME
,
2
);
SET_WINE_ALLOW2
(
INTERNET_STATUS_NAME_RESOLVED
,
2
);
}
SET_WINE_ALLOW
(
INTERNET_STATUS_CONNECTING_TO_SERVER
);
SET_EXPECT
(
INTERNET_STATUS_CONNECTING_TO_SERVER
);
SET_WINE_ALLOW
(
INTERNET_STATUS_CONNECTED_TO_SERVER
);
SET_EXPECT
(
INTERNET_STATUS_CONNECTED_TO_SERVER
);
SET_EXPECT2
(
INTERNET_STATUS_SENDING_REQUEST
,
(
test
->
flags
&
TESTF_REDIRECT
)
?
2
:
1
);
SET_EXPECT2
(
INTERNET_STATUS_REQUEST_SENT
,
(
test
->
flags
&
TESTF_REDIRECT
)
?
2
:
1
);
...
...
@@ -461,7 +452,7 @@ static void InternetReadFile_test(int flags, const test_data_t *test)
CLEAR_NOTIFIED
(
INTERNET_STATUS_NAME_RESOLVED
);
}
}
else
todo_wine
else
{
CHECK_NOT_NOTIFIED
(
INTERNET_STATUS_RESOLVING_NAME
);
CHECK_NOT_NOTIFIED
(
INTERNET_STATUS_NAME_RESOLVED
);
...
...
@@ -582,8 +573,6 @@ abort:
trace
(
"aborting
\n
"
);
SET_EXPECT2
(
INTERNET_STATUS_HANDLE_CLOSING
,
(
hor
!=
0x0
)
+
(
hic
!=
0x0
));
if
(
hor
!=
0x0
)
{
SET_WINE_ALLOW
(
INTERNET_STATUS_CLOSING_CONNECTION
);
SET_WINE_ALLOW
(
INTERNET_STATUS_CONNECTION_CLOSED
);
SetLastError
(
0xdeadbeef
);
trace
(
"closing
\n
"
);
res
=
InternetCloseHandle
(
hor
);
...
...
@@ -608,7 +597,7 @@ abort:
Sleep
(
100
);
}
CHECK_NOTIFIED2
(
INTERNET_STATUS_HANDLE_CLOSING
,
(
hor
!=
0x0
)
+
(
hic
!=
0x0
));
if
(
hor
!=
0x0
)
todo_wine
if
(
hor
!=
0x0
)
{
CHECK_NOT_NOTIFIED
(
INTERNET_STATUS_CLOSING_CONNECTION
);
CHECK_NOT_NOTIFIED
(
INTERNET_STATUS_CONNECTION_CLOSED
);
...
...
@@ -791,17 +780,8 @@ static void InternetReadFileExA_test(int flags)
{
SET_EXPECT
(
INTERNET_STATUS_RESOLVING_NAME
);
SET_EXPECT
(
INTERNET_STATUS_NAME_RESOLVED
);
SET_WINE_ALLOW
(
INTERNET_STATUS_RESOLVING_NAME
);
SET_WINE_ALLOW
(
INTERNET_STATUS_NAME_RESOLVED
);
}
else
{
SET_WINE_ALLOW2
(
INTERNET_STATUS_RESOLVING_NAME
,
2
);
SET_WINE_ALLOW2
(
INTERNET_STATUS_NAME_RESOLVED
,
2
);
}
SET_WINE_ALLOW
(
INTERNET_STATUS_CONNECTING_TO_SERVER
);
SET_EXPECT
(
INTERNET_STATUS_CONNECTING_TO_SERVER
);
SET_WINE_ALLOW
(
INTERNET_STATUS_CONNECTED_TO_SERVER
);
SET_EXPECT
(
INTERNET_STATUS_CONNECTED_TO_SERVER
);
SET_EXPECT2
(
INTERNET_STATUS_SENDING_REQUEST
,
2
);
SET_EXPECT2
(
INTERNET_STATUS_REQUEST_SENT
,
2
);
...
...
@@ -836,7 +816,7 @@ static void InternetReadFileExA_test(int flags)
CHECK_NOTIFIED
(
INTERNET_STATUS_RESOLVING_NAME
);
CHECK_NOTIFIED
(
INTERNET_STATUS_NAME_RESOLVED
);
}
else
todo_wine
else
{
CHECK_NOT_NOTIFIED
(
INTERNET_STATUS_RESOLVING_NAME
);
CHECK_NOT_NOTIFIED
(
INTERNET_STATUS_NAME_RESOLVED
);
...
...
@@ -975,8 +955,6 @@ static void InternetReadFileExA_test(int flags)
abort:
SET_EXPECT2
(
INTERNET_STATUS_HANDLE_CLOSING
,
(
hor
!=
0x0
)
+
(
hic
!=
0x0
));
if
(
hor
)
{
SET_WINE_ALLOW
(
INTERNET_STATUS_CLOSING_CONNECTION
);
SET_WINE_ALLOW
(
INTERNET_STATUS_CONNECTION_CLOSED
);
rc
=
InternetCloseHandle
(
hor
);
ok
((
rc
!=
0
),
"InternetCloseHandle of handle opened by HttpOpenRequestA failed
\n
"
);
rc
=
InternetCloseHandle
(
hor
);
...
...
@@ -2640,7 +2618,7 @@ static void test_url_caching(int port, int *num_retrievals)
r
=
HttpSendRequest
(
hr
,
NULL
,
0
,
NULL
,
0
);
ok
(
r
,
"HttpSendRequest failed
\n
"
);
ok
(
*
num_retrievals
==
1
,
"expected 1 retrievals
\n
"
);
ok
(
*
num_retrievals
==
1
,
"expected 1 retrievals
, got %d
\n
"
,
*
num_retrievals
);
count
=
0
;
memset
(
buffer
,
0
,
sizeof
buffer
);
...
...
@@ -3406,7 +3384,7 @@ START_TEST(http)
pInternetSetStatusCallbackA
=
(
void
*
)
GetProcAddress
(
hdll
,
"InternetSetStatusCallbackA"
);
init_status_tests
();
if
(
0
)
test_InternetCloseHandle
();
test_InternetCloseHandle
();
InternetReadFile_test
(
INTERNET_FLAG_ASYNC
,
&
test_data
[
0
]);
InternetReadFile_test
(
INTERNET_FLAG_ASYNC
,
&
test_data
[
1
]);
InternetReadFile_test
(
0
,
&
test_data
[
1
]);
...
...
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