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
5205d038
Commit
5205d038
authored
Jan 09, 2011
by
David Hedberg
Committed by
Alexandre Julliard
Jan 11, 2011
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
urlmon: Add some error handling to the http protocol.
parent
c9e6f774
Expand all
Hide whitespace changes
Inline
Side-by-side
Showing
2 changed files
with
168 additions
and
5 deletions
+168
-5
http.c
dlls/urlmon/http.c
+168
-5
url.c
dlls/urlmon/tests/url.c
+0
-0
No files found.
dlls/urlmon/http.c
View file @
5205d038
...
@@ -80,6 +80,145 @@ static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
...
@@ -80,6 +80,145 @@ static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
return
ret
;
return
ret
;
}
}
static
inline
BOOL
set_security_flag
(
HttpProtocol
*
This
,
DWORD
new_flag
)
{
DWORD
flags
,
size
=
sizeof
(
flags
);
BOOL
res
;
res
=
InternetQueryOptionW
(
This
->
base
.
request
,
INTERNET_OPTION_SECURITY_FLAGS
,
&
flags
,
&
size
);
if
(
res
)
{
flags
|=
new_flag
;
res
=
InternetSetOptionW
(
This
->
base
.
request
,
INTERNET_OPTION_SECURITY_FLAGS
,
&
flags
,
size
);
}
if
(
!
res
)
ERR
(
"Failed to set security flag(s): %x
\n
"
,
new_flag
);
return
res
;
}
static
inline
HRESULT
internet_error_to_hres
(
DWORD
error
)
{
switch
(
error
)
{
case
ERROR_INTERNET_SEC_CERT_DATE_INVALID
:
case
ERROR_INTERNET_SEC_CERT_CN_INVALID
:
case
ERROR_INTERNET_INVALID_CA
:
case
ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
:
return
INET_E_INVALID_CERTIFICATE
;
case
ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR
:
case
ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR
:
case
ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION
:
return
INET_E_REDIRECT_FAILED
;
default:
return
INET_E_DOWNLOAD_FAILURE
;
}
}
static
HRESULT
handle_http_error
(
HttpProtocol
*
This
,
DWORD
error
)
{
IServiceProvider
*
serv_prov
;
IWindowForBindingUI
*
wfb_ui
;
IHttpSecurity
*
http_security
;
BOOL
security_problem
;
HRESULT
hres
;
switch
(
error
)
{
case
ERROR_INTERNET_SEC_CERT_DATE_INVALID
:
case
ERROR_INTERNET_SEC_CERT_CN_INVALID
:
case
ERROR_INTERNET_HTTP_TO_HTTPS_ON_REDIR
:
case
ERROR_INTERNET_HTTPS_TO_HTTP_ON_REDIR
:
case
ERROR_HTTP_REDIRECT_NEEDS_CONFIRMATION
:
case
ERROR_INTERNET_INVALID_CA
:
case
ERROR_INTERNET_CLIENT_AUTH_CERT_NEEDED
:
security_problem
=
TRUE
;
break
;
default:
security_problem
=
FALSE
;
}
hres
=
IInternetProtocolSink_QueryInterface
(
This
->
base
.
protocol_sink
,
&
IID_IServiceProvider
,
(
void
**
)
&
serv_prov
);
if
(
FAILED
(
hres
))
{
ERR
(
"Failed to get IServiceProvider.
\n
"
);
return
E_ABORT
;
}
if
(
security_problem
)
{
hres
=
IServiceProvider_QueryService
(
serv_prov
,
&
IID_IHttpSecurity
,
&
IID_IHttpSecurity
,
(
void
**
)
&
http_security
);
if
(
SUCCEEDED
(
hres
))
{
hres
=
IHttpSecurity_OnSecurityProblem
(
http_security
,
error
);
IHttpSecurity_Release
(
http_security
);
if
(
hres
!=
S_FALSE
)
{
BOOL
res
=
FALSE
;
IServiceProvider_Release
(
serv_prov
);
if
(
hres
==
S_OK
)
{
if
(
error
==
ERROR_INTERNET_SEC_CERT_DATE_INVALID
)
res
=
set_security_flag
(
This
,
SECURITY_FLAG_IGNORE_CERT_DATE_INVALID
);
else
if
(
error
==
ERROR_INTERNET_SEC_CERT_CN_INVALID
)
res
=
set_security_flag
(
This
,
SECURITY_FLAG_IGNORE_CERT_CN_INVALID
);
else
if
(
error
==
ERROR_INTERNET_INVALID_CA
)
res
=
set_security_flag
(
This
,
SECURITY_FLAG_IGNORE_UNKNOWN_CA
);
if
(
res
)
return
RPC_E_RETRY
;
FIXME
(
"Don't know how to ignore error %d
\n
"
,
error
);
return
E_ABORT
;
}
if
(
hres
==
E_ABORT
)
return
E_ABORT
;
if
(
hres
==
RPC_E_RETRY
)
return
RPC_E_RETRY
;
return
internet_error_to_hres
(
error
);
}
}
}
hres
=
IServiceProvider_QueryService
(
serv_prov
,
&
IID_IWindowForBindingUI
,
&
IID_IWindowForBindingUI
,
(
void
**
)
&
wfb_ui
);
if
(
SUCCEEDED
(
hres
))
{
HWND
hwnd
;
const
IID
*
iid_reason
;
if
(
security_problem
)
iid_reason
=
&
IID_IHttpSecurity
;
else
if
(
error
==
ERROR_INTERNET_INCORRECT_PASSWORD
)
iid_reason
=
&
IID_IAuthenticate
;
else
iid_reason
=
&
IID_IWindowForBindingUI
;
hres
=
IWindowForBindingUI_GetWindow
(
wfb_ui
,
iid_reason
,
&
hwnd
);
if
(
SUCCEEDED
(
hres
)
&&
hwnd
)
{
DWORD
res
;
res
=
InternetErrorDlg
(
hwnd
,
This
->
base
.
request
,
error
,
FLAGS_ERROR_UI_FLAGS_CHANGE_OPTIONS
|
FLAGS_ERROR_UI_FLAGS_GENERATE_DATA
,
NULL
);
if
(
res
==
ERROR_INTERNET_FORCE_RETRY
||
res
==
ERROR_SUCCESS
)
hres
=
RPC_E_RETRY
;
else
hres
=
E_FAIL
;
}
IWindowForBindingUI_Release
(
wfb_ui
);
}
IServiceProvider_Release
(
serv_prov
);
if
(
hres
==
RPC_E_RETRY
)
return
hres
;
return
internet_error_to_hres
(
error
);
}
static
ULONG
send_http_request
(
HttpProtocol
*
This
)
static
ULONG
send_http_request
(
HttpProtocol
*
This
)
{
{
INTERNET_BUFFERSW
send_buffer
=
{
sizeof
(
INTERNET_BUFFERSW
)};
INTERNET_BUFFERSW
send_buffer
=
{
sizeof
(
INTERNET_BUFFERSW
)};
...
@@ -285,13 +424,18 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques
...
@@ -285,13 +424,18 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, IUri *uri, DWORD reques
if
(
!
res
)
if
(
!
res
)
WARN
(
"InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x
\n
"
,
GetLastError
());
WARN
(
"InternetSetOption(INTERNET_OPTION_HTTP_DECODING) failed: %08x
\n
"
,
GetLastError
());
error
=
send_http_request
(
This
);
do
{
error
=
send_http_request
(
This
);
if
(
error
==
ERROR_IO_PENDING
||
error
==
ERROR_SUCCESS
)
if
(
error
==
ERROR_IO_PENDING
||
error
==
ERROR_SUCCESS
)
return
S_OK
;
return
S_OK
;
hres
=
handle_http_error
(
This
,
error
);
}
while
(
hres
==
RPC_E_RETRY
);
WARN
(
"HttpSendRequest failed: %d
\n
"
,
error
);
WARN
(
"HttpSendRequest failed: %d
\n
"
,
error
);
return
INET_E_DOWNLOAD_FAILURE
;
return
hres
;
}
}
static
HRESULT
HttpProtocol_end_request
(
Protocol
*
protocol
)
static
HRESULT
HttpProtocol_end_request
(
Protocol
*
protocol
)
...
@@ -393,7 +537,26 @@ static void HttpProtocol_close_connection(Protocol *prot)
...
@@ -393,7 +537,26 @@ static void HttpProtocol_close_connection(Protocol *prot)
static
void
HttpProtocol_on_error
(
Protocol
*
prot
,
DWORD
error
)
static
void
HttpProtocol_on_error
(
Protocol
*
prot
,
DWORD
error
)
{
{
FIXME
(
"(%p) %d - stub
\n
"
,
prot
,
error
);
HttpProtocol
*
This
=
impl_from_Protocol
(
prot
);
HRESULT
hres
;
TRACE
(
"(%p) %d
\n
"
,
prot
,
error
);
if
(
prot
->
flags
&
FLAG_FIRST_CONTINUE_COMPLETE
)
{
FIXME
(
"Not handling error %d
\n
"
,
error
);
return
;
}
while
((
hres
=
handle_http_error
(
This
,
error
))
==
RPC_E_RETRY
)
{
error
=
send_http_request
(
This
);
if
(
error
==
ERROR_IO_PENDING
||
error
==
ERROR_SUCCESS
)
return
;
}
protocol_abort
(
prot
,
hres
);
protocol_close_connection
(
prot
);
return
;
}
}
static
const
ProtocolVtbl
AsyncProtocolVtbl
=
{
static
const
ProtocolVtbl
AsyncProtocolVtbl
=
{
...
...
dlls/urlmon/tests/url.c
View file @
5205d038
This diff is collapsed.
Click to expand it.
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