mirror of
https://github.com/reactos/wine.git
synced 2024-11-24 20:30:01 +00:00
urlmon: Use one wininet internet handle for all connections.
This commit is contained in:
parent
8809bef428
commit
09436d69f1
@ -37,11 +37,11 @@ typedef struct {
|
||||
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(FtpProtocol, base, iface)
|
||||
|
||||
static HRESULT FtpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
|
||||
IInternetBindInfo *bind_info)
|
||||
HINTERNET internet_session, IInternetBindInfo *bind_info)
|
||||
{
|
||||
FtpProtocol *This = ASYNCPROTOCOL_THIS(prot);
|
||||
|
||||
This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0,
|
||||
This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0,
|
||||
request_flags|INTERNET_FLAG_EXISTING_CONNECT|INTERNET_FLAG_PASSIVE,
|
||||
(DWORD_PTR)&This->base);
|
||||
if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
|
||||
|
@ -35,11 +35,11 @@ typedef struct {
|
||||
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(GopherProtocol, base, iface)
|
||||
|
||||
static HRESULT GopherProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
|
||||
IInternetBindInfo *bind_info)
|
||||
HINTERNET internet_session, IInternetBindInfo *bind_info)
|
||||
{
|
||||
GopherProtocol *This = ASYNCPROTOCOL_THIS(prot);
|
||||
|
||||
This->base.request = InternetOpenUrlW(This->base.internet, url, NULL, 0,
|
||||
This->base.request = InternetOpenUrlW(internet_session, url, NULL, 0,
|
||||
request_flags, (DWORD_PTR)&This->base);
|
||||
if (!This->base.request && GetLastError() != ERROR_IO_PENDING) {
|
||||
WARN("InternetOpenUrl failed: %d\n", GetLastError());
|
||||
|
@ -73,7 +73,7 @@ static LPWSTR query_http_info(HttpProtocol *This, DWORD option)
|
||||
#define ASYNCPROTOCOL_THIS(iface) DEFINE_THIS2(HttpProtocol, base, iface)
|
||||
|
||||
static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD request_flags,
|
||||
IInternetBindInfo *bind_info)
|
||||
HINTERNET internet_session, IInternetBindInfo *bind_info)
|
||||
{
|
||||
HttpProtocol *This = ASYNCPROTOCOL_THIS(prot);
|
||||
LPWSTR addl_header = NULL, post_cookie = NULL, optional = NULL;
|
||||
@ -106,7 +106,7 @@ static HRESULT HttpProtocol_open_request(Protocol *prot, LPCWSTR url, DWORD requ
|
||||
host = heap_strndupW(url_comp.lpszHostName, url_comp.dwHostNameLength);
|
||||
user = heap_strndupW(url_comp.lpszUserName, url_comp.dwUserNameLength);
|
||||
pass = heap_strndupW(url_comp.lpszPassword, url_comp.dwPasswordLength);
|
||||
This->base.connection = InternetConnectW(This->base.internet, host, url_comp.nPort, user, pass,
|
||||
This->base.connection = InternetConnectW(internet_session, host, url_comp.nPort, user, pass,
|
||||
INTERNET_SERVICE_HTTP, This->https ? INTERNET_FLAG_SECURE : 0, (DWORD_PTR)&This->base);
|
||||
heap_free(pass);
|
||||
heap_free(user);
|
||||
|
@ -186,12 +186,53 @@ static void WINAPI internet_status_callback(HINTERNET internet, DWORD_PTR contex
|
||||
}
|
||||
}
|
||||
|
||||
static HINTERNET create_internet_session(IInternetBindInfo *bind_info)
|
||||
{
|
||||
LPWSTR global_user_agent = NULL;
|
||||
LPOLESTR user_agent = NULL;
|
||||
ULONG size = 0;
|
||||
HINTERNET ret;
|
||||
HRESULT hres;
|
||||
|
||||
hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_USER_AGENT, &user_agent, 1, &size);
|
||||
if(hres != S_OK || !size)
|
||||
global_user_agent = get_useragent();
|
||||
|
||||
ret = InternetOpenW(user_agent ? user_agent : global_user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
|
||||
heap_free(global_user_agent);
|
||||
CoTaskMemFree(user_agent);
|
||||
if(!ret) {
|
||||
WARN("InternetOpen failed: %d\n", GetLastError());
|
||||
return NULL;
|
||||
}
|
||||
|
||||
InternetSetStatusCallbackW(ret, internet_status_callback);
|
||||
return ret;
|
||||
}
|
||||
|
||||
static HINTERNET internet_session;
|
||||
|
||||
HINTERNET get_internet_session(IInternetBindInfo *bind_info)
|
||||
{
|
||||
HINTERNET new_session;
|
||||
|
||||
if(internet_session)
|
||||
return internet_session;
|
||||
|
||||
if(!bind_info)
|
||||
return NULL;
|
||||
|
||||
new_session = create_internet_session(bind_info);
|
||||
if(new_session && InterlockedCompareExchangePointer((void**)&internet_session, new_session, NULL))
|
||||
InternetCloseHandle(new_session);
|
||||
|
||||
return internet_session;
|
||||
}
|
||||
|
||||
HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url,
|
||||
IInternetProtocolSink *protocol_sink, IInternetBindInfo *bind_info)
|
||||
{
|
||||
LPOLESTR user_agent = NULL;
|
||||
DWORD request_flags;
|
||||
ULONG size = 0;
|
||||
HRESULT hres;
|
||||
|
||||
protocol->protocol = prot;
|
||||
@ -210,37 +251,8 @@ HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url,
|
||||
if(!(protocol->bindf & BINDF_FROMURLMON))
|
||||
report_progress(protocol, BINDSTATUS_DIRECTBIND, NULL);
|
||||
|
||||
hres = IInternetBindInfo_GetBindString(bind_info, BINDSTRING_USER_AGENT, &user_agent, 1, &size);
|
||||
if (hres != S_OK || !size) {
|
||||
DWORD len;
|
||||
CHAR null_char = 0;
|
||||
LPSTR user_agenta = NULL;
|
||||
|
||||
len = 0;
|
||||
if ((hres = ObtainUserAgentString(0, &null_char, &len)) != E_OUTOFMEMORY) {
|
||||
WARN("ObtainUserAgentString failed: %08x\n", hres);
|
||||
}else if (!(user_agenta = heap_alloc(len*sizeof(CHAR)))) {
|
||||
WARN("Out of memory\n");
|
||||
}else if ((hres = ObtainUserAgentString(0, user_agenta, &len)) != S_OK) {
|
||||
WARN("ObtainUserAgentString failed: %08x\n", hres);
|
||||
}else {
|
||||
if(!(user_agent = CoTaskMemAlloc((len)*sizeof(WCHAR))))
|
||||
WARN("Out of memory\n");
|
||||
else
|
||||
MultiByteToWideChar(CP_ACP, 0, user_agenta, -1, user_agent, len);
|
||||
}
|
||||
heap_free(user_agenta);
|
||||
}
|
||||
|
||||
protocol->internet = InternetOpenW(user_agent, 0, NULL, NULL, INTERNET_FLAG_ASYNC);
|
||||
CoTaskMemFree(user_agent);
|
||||
if(!protocol->internet) {
|
||||
WARN("InternetOpen failed: %d\n", GetLastError());
|
||||
if(!get_internet_session(bind_info))
|
||||
return report_result(protocol, INET_E_NO_SESSION);
|
||||
}
|
||||
|
||||
/* Native does not check for success of next call, so we won't either */
|
||||
InternetSetStatusCallbackW(protocol->internet, internet_status_callback);
|
||||
|
||||
request_flags = INTERNET_FLAG_KEEP_CONNECTION;
|
||||
if(protocol->bindf & BINDF_NOWRITECACHE)
|
||||
@ -248,7 +260,7 @@ HRESULT protocol_start(Protocol *protocol, IInternetProtocol *prot, LPCWSTR url,
|
||||
if(protocol->bindf & BINDF_NEEDFILE)
|
||||
request_flags |= INTERNET_FLAG_NEED_FILE;
|
||||
|
||||
hres = protocol->vtbl->open_request(protocol, url, request_flags, bind_info);
|
||||
hres = protocol->vtbl->open_request(protocol, url, request_flags, internet_session, bind_info);
|
||||
if(FAILED(hres)) {
|
||||
protocol_close_connection(protocol);
|
||||
return report_result(protocol, hres);
|
||||
@ -421,10 +433,5 @@ void protocol_close_connection(Protocol *protocol)
|
||||
if(protocol->connection)
|
||||
InternetCloseHandle(protocol->connection);
|
||||
|
||||
if(protocol->internet) {
|
||||
InternetCloseHandle(protocol->internet);
|
||||
protocol->internet = 0;
|
||||
}
|
||||
|
||||
protocol->flags = 0;
|
||||
}
|
||||
|
@ -532,6 +532,19 @@ static void ensure_useragent(void)
|
||||
RegCloseKey(hkey);
|
||||
}
|
||||
|
||||
LPWSTR get_useragent(void)
|
||||
{
|
||||
LPWSTR ret;
|
||||
|
||||
ensure_useragent();
|
||||
|
||||
EnterCriticalSection(&session_cs);
|
||||
ret = heap_strdupW(user_agent);
|
||||
LeaveCriticalSection(&session_cs);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
HRESULT WINAPI UrlMkGetSessionOption(DWORD dwOption, LPVOID pBuffer, DWORD dwBufferLength,
|
||||
DWORD* pdwBufferLength, DWORD dwReserved)
|
||||
{
|
||||
|
@ -2155,7 +2155,8 @@ static BOOL http_protocol_start(LPCWSTR url)
|
||||
SET_EXPECT(GetBindInfo);
|
||||
if (!(bindf & BINDF_FROMURLMON))
|
||||
SET_EXPECT(ReportProgress_DIRECTBIND);
|
||||
SET_EXPECT(GetBindString_USER_AGENT);
|
||||
if(!got_user_agent)
|
||||
SET_EXPECT(GetBindString_USER_AGENT);
|
||||
SET_EXPECT(GetBindString_ACCEPT_MIMES);
|
||||
SET_EXPECT(QueryService_HttpNegotiate);
|
||||
SET_EXPECT(BeginningTransaction);
|
||||
@ -2176,11 +2177,6 @@ static BOOL http_protocol_start(LPCWSTR url)
|
||||
CHECK_CALLED(GetBindString_USER_AGENT);
|
||||
got_user_agent = TRUE;
|
||||
}
|
||||
else todo_wine
|
||||
{
|
||||
/* user agent only retrieved once, even with different URLs */
|
||||
CHECK_NOT_CALLED(GetBindString_USER_AGENT);
|
||||
}
|
||||
CHECK_CALLED(GetBindString_ACCEPT_MIMES);
|
||||
CHECK_CALLED(QueryService_HttpNegotiate);
|
||||
CHECK_CALLED(BeginningTransaction);
|
||||
@ -2432,7 +2428,6 @@ static void test_ftp_protocol(void)
|
||||
test_http_info(async_protocol);
|
||||
|
||||
SET_EXPECT(GetBindInfo);
|
||||
SET_EXPECT(GetBindString_USER_AGENT);
|
||||
SET_EXPECT(ReportProgress_FINDINGRESOURCE);
|
||||
SET_EXPECT(ReportProgress_CONNECTING);
|
||||
SET_EXPECT(ReportProgress_SENDINGREQUEST);
|
||||
@ -2441,7 +2436,6 @@ static void test_ftp_protocol(void)
|
||||
hres = IInternetProtocol_Start(async_protocol, ftp_urlW, &protocol_sink, &bind_info, 0, 0);
|
||||
ok(hres == S_OK, "Start failed: %08x\n", hres);
|
||||
CHECK_CALLED(GetBindInfo);
|
||||
todo_wine CHECK_NOT_CALLED(GetBindString_USER_AGENT);
|
||||
|
||||
SET_EXPECT(ReportResult);
|
||||
|
||||
|
@ -121,6 +121,22 @@ static void detach_thread(void)
|
||||
heap_free(data);
|
||||
}
|
||||
|
||||
static void process_detach(void)
|
||||
{
|
||||
HINTERNET internet_session;
|
||||
|
||||
internet_session = get_internet_session(NULL);
|
||||
if(internet_session)
|
||||
InternetCloseHandle(internet_session);
|
||||
|
||||
if (hCabinet)
|
||||
FreeLibrary(hCabinet);
|
||||
|
||||
init_session(FALSE);
|
||||
free_session();
|
||||
free_tls_list();
|
||||
}
|
||||
|
||||
/***********************************************************************
|
||||
* DllMain (URLMON.init)
|
||||
*/
|
||||
@ -132,17 +148,11 @@ BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID fImpLoad)
|
||||
case DLL_PROCESS_ATTACH:
|
||||
URLMON_hInstance = hinstDLL;
|
||||
init_session(TRUE);
|
||||
break;
|
||||
break;
|
||||
|
||||
case DLL_PROCESS_DETACH:
|
||||
if (hCabinet)
|
||||
FreeLibrary(hCabinet);
|
||||
hCabinet = NULL;
|
||||
init_session(FALSE);
|
||||
free_session();
|
||||
free_tls_list();
|
||||
URLMON_hInstance = 0;
|
||||
break;
|
||||
process_detach();
|
||||
break;
|
||||
|
||||
case DLL_THREAD_DETACH:
|
||||
detach_thread();
|
||||
|
@ -63,6 +63,8 @@ HRESULT get_protocol_handler(LPCWSTR,CLSID*,BOOL*,IClassFactory**);
|
||||
IInternetProtocol *get_mime_filter(LPCWSTR);
|
||||
BOOL is_registered_protocol(LPCWSTR);
|
||||
void register_urlmon_namespace(IClassFactory*,REFIID,LPCWSTR,BOOL);
|
||||
HINTERNET get_internet_session(IInternetBindInfo*);
|
||||
LPWSTR get_useragent(void);
|
||||
void free_session(void);
|
||||
|
||||
HRESULT bind_to_storage(LPCWSTR url, IBindCtx *pbc, REFIID riid, void **ppv);
|
||||
@ -83,7 +85,6 @@ typedef struct {
|
||||
DWORD bindf;
|
||||
BINDINFO bind_info;
|
||||
|
||||
HINTERNET internet;
|
||||
HINTERNET request;
|
||||
HINTERNET connection;
|
||||
DWORD flags;
|
||||
@ -97,7 +98,7 @@ typedef struct {
|
||||
} Protocol;
|
||||
|
||||
struct ProtocolVtbl {
|
||||
HRESULT (*open_request)(Protocol*,LPCWSTR,DWORD,IInternetBindInfo*);
|
||||
HRESULT (*open_request)(Protocol*,LPCWSTR,DWORD,HINTERNET,IInternetBindInfo*);
|
||||
HRESULT (*start_downloading)(Protocol*);
|
||||
void (*close_connection)(Protocol*);
|
||||
};
|
||||
|
Loading…
Reference in New Issue
Block a user