Commit aa1d0322 authored by Jacek Caban's avatar Jacek Caban Committed by Alexandre Julliard

urlmon: Added ftp protocol tests.

parent 3e84960c
...@@ -110,7 +110,7 @@ static const WCHAR emptyW[] = {0}; ...@@ -110,7 +110,7 @@ static const WCHAR emptyW[] = {0};
static HRESULT expect_hrResult; static HRESULT expect_hrResult;
static LPCWSTR file_name, http_url, expect_wsz; static LPCWSTR file_name, http_url, expect_wsz;
static IInternetProtocol *http_protocol = NULL; static IInternetProtocol *async_protocol = NULL;
static BOOL first_data_notif = FALSE, http_is_first = FALSE, static BOOL first_data_notif = FALSE, http_is_first = FALSE,
http_post_test = FALSE; http_post_test = FALSE;
static int state = 0, prot_state; static int state = 0, prot_state;
...@@ -128,6 +128,7 @@ static enum { ...@@ -128,6 +128,7 @@ static enum {
FILE_TEST, FILE_TEST,
HTTP_TEST, HTTP_TEST,
HTTPS_TEST, HTTPS_TEST,
FTP_TEST,
MK_TEST, MK_TEST,
BIND_TEST BIND_TEST
} tested_protocol; } tested_protocol;
...@@ -135,13 +136,20 @@ static enum { ...@@ -135,13 +136,20 @@ static enum {
static const WCHAR protocol_names[][10] = { static const WCHAR protocol_names[][10] = {
{'f','i','l','e',0}, {'f','i','l','e',0},
{'h','t','t','p',0}, {'h','t','t','p',0},
{'h','t','t','p','s',0},
{'f','t','p',0},
{'m','k',0}, {'m','k',0},
{'t','e','s','t',0} {'t','e','s','t',0}
}; };
static const WCHAR binding_urls[][30] = { static const WCHAR binding_urls[][130] = {
{'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0}, {'f','i','l','e',':','t','e','s','t','.','h','t','m','l',0},
{'h','t','t','p',':','/','/','t','e','s','t','/','t','e','s','t','.','h','t','m','l',0}, {'h','t','t','p',':','/','/','t','e','s','t','/','t','e','s','t','.','h','t','m','l',0},
{'h','t','t','p','s',':','/','/','w','w','w','.','c','o','d','e','w','e','a','v','e','r','s',
'.','c','o','m','/','t','e','s','t','.','h','t','m','l',0},
{'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
'/','p','u','b','/','o','t','h','e','r',
'/','w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0},
{'m','k',':','t','e','s','t',0}, {'m','k',':','t','e','s','t',0},
{'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0} {'t','e','s','t',':','/','/','f','i','l','e','.','h','t','m','l',0}
}; };
...@@ -356,6 +364,7 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL ...@@ -356,6 +364,7 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
} }
if (!state) { if (!state) {
if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST) {
if (http_is_first) { if (http_is_first) {
CLEAR_CALLED(ReportProgress_FINDINGRESOURCE); CLEAR_CALLED(ReportProgress_FINDINGRESOURCE);
CLEAR_CALLED(ReportProgress_CONNECTING); CLEAR_CALLED(ReportProgress_CONNECTING);
...@@ -365,7 +374,12 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL ...@@ -365,7 +374,12 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
/* IE7 does call this */ /* IE7 does call this */
CLEAR_CALLED(ReportProgress_CONNECTING); CLEAR_CALLED(ReportProgress_CONNECTING);
} }
}
if(tested_protocol == FTP_TEST)
todo_wine CHECK_CALLED(ReportProgress_SENDINGREQUEST);
else
CHECK_CALLED(ReportProgress_SENDINGREQUEST); CHECK_CALLED(ReportProgress_SENDINGREQUEST);
if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
SET_EXPECT(OnResponse); SET_EXPECT(OnResponse);
if(tested_protocol == HTTPS_TEST) if(tested_protocol == HTTPS_TEST)
SET_EXPECT(ReportProgress_ACCEPTRANGES); SET_EXPECT(ReportProgress_ACCEPTRANGES);
...@@ -373,14 +387,19 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL ...@@ -373,14 +387,19 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
if(bindf & BINDF_NEEDFILE) if(bindf & BINDF_NEEDFILE)
SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE); SET_EXPECT(ReportProgress_CACHEFILENAMEAVAILABLE);
} }
}
SET_EXPECT(ReportData); SET_EXPECT(ReportData);
hres = IInternetProtocol_Continue(http_protocol, pProtocolData); hres = IInternetProtocol_Continue(async_protocol, pProtocolData);
ok(hres == S_OK, "Continue failed: %08x\n", hres); ok(hres == S_OK, "Continue failed: %08x\n", hres);
if(tested_protocol == FTP_TEST)
CLEAR_CALLED(ReportData);
else
CHECK_CALLED(ReportData); CHECK_CALLED(ReportData);
if (!state) { if (!state) {
state = 1; state = 1;
if(tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST) {
CHECK_CALLED(OnResponse); CHECK_CALLED(OnResponse);
if(tested_protocol == HTTPS_TEST) if(tested_protocol == HTTPS_TEST)
CHECK_CALLED(ReportProgress_ACCEPTRANGES); CHECK_CALLED(ReportProgress_ACCEPTRANGES);
...@@ -388,6 +407,7 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL ...@@ -388,6 +407,7 @@ static HRESULT WINAPI ProtocolSink_Switch(IInternetProtocolSink *iface, PROTOCOL
if(bindf & BINDF_NEEDFILE) if(bindf & BINDF_NEEDFILE)
CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE); CHECK_CALLED(ReportProgress_CACHEFILENAMEAVAILABLE);
} }
}
SetEvent(event_complete); SetEvent(event_complete);
...@@ -451,7 +471,7 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface, ...@@ -451,7 +471,7 @@ static HRESULT WINAPI ProtocolSink_ReportProgress(IInternetProtocolSink *iface,
ok(szStatusText != NULL, "szStatusText == NULL\n"); ok(szStatusText != NULL, "szStatusText == NULL\n");
break; break;
case BINDSTATUS_SENDINGREQUEST: case BINDSTATUS_SENDINGREQUEST:
CHECK_EXPECT(ReportProgress_SENDINGREQUEST); CHECK_EXPECT2(ReportProgress_SENDINGREQUEST);
if(tested_protocol == FILE_TEST) { if(tested_protocol == FILE_TEST) {
ok(szStatusText != NULL, "szStatusText == NULL\n"); ok(szStatusText != NULL, "szStatusText == NULL\n");
if(szStatusText) if(szStatusText)
...@@ -508,7 +528,7 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR ...@@ -508,7 +528,7 @@ static HRESULT WINAPI ProtocolSink_ReportData(IInternetProtocolSink *iface, DWOR
ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax); ok(ulProgressMax == 13, "ulProgressMax=%d, expected 13\n", ulProgressMax);
ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION), ok(grfBSCF == (BSCF_FIRSTDATANOTIFICATION | BSCF_LASTDATANOTIFICATION),
"grcfBSCF = %08x\n", grfBSCF); "grcfBSCF = %08x\n", grfBSCF);
}else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST)) { }else if(!binding_test && (tested_protocol == HTTP_TEST || tested_protocol == HTTPS_TEST || tested_protocol == FTP_TEST)) {
if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE)) if(!(grfBSCF & BSCF_LASTDATANOTIFICATION) || (grfBSCF & BSCF_DATAFULLYAVAILABLE))
CHECK_EXPECT(ReportData); CHECK_EXPECT(ReportData);
else if (http_post_test) else if (http_post_test)
...@@ -570,9 +590,12 @@ static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HR ...@@ -570,9 +590,12 @@ static HRESULT WINAPI ProtocolSink_ReportResult(IInternetProtocolSink *iface, HR
{ {
CHECK_EXPECT(ReportResult); CHECK_EXPECT(ReportResult);
if(tested_protocol == FTP_TEST)
ok(hrResult == E_PENDING || hrResult == S_OK, "hrResult = %08x, expected E_PENDING or S_OK\n", hrResult);
else
ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n", ok(hrResult == expect_hrResult, "hrResult = %08x, expected: %08x\n",
hrResult, expect_hrResult); hrResult, expect_hrResult);
if(SUCCEEDED(hrResult)) if(SUCCEEDED(hrResult) || tested_protocol == FTP_TEST)
ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError); ok(dwError == ERROR_SUCCESS, "dwError = %d, expected ERROR_SUCCESS\n", dwError);
else else
ok(dwError != ERROR_SUCCESS, "dwError == ERROR_SUCCESS\n"); ok(dwError != ERROR_SUCCESS, "dwError == ERROR_SUCCESS\n");
...@@ -1529,7 +1552,7 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL is_first) ...@@ -1529,7 +1552,7 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL is_first)
if (http_post_test) if (http_post_test)
SET_EXPECT(GetBindString_POST_COOKIE); SET_EXPECT(GetBindString_POST_COOKIE);
hres = IInternetProtocol_Start(http_protocol, url, &protocol_sink, &bind_info, 0, 0); hres = IInternetProtocol_Start(async_protocol, url, &protocol_sink, &bind_info, 0, 0);
ok(hres == S_OK, "Start failed: %08x\n", hres); ok(hres == S_OK, "Start failed: %08x\n", hres);
if(FAILED(hres)) if(FAILED(hres))
return FALSE; return FALSE;
...@@ -1558,6 +1581,35 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL is_first) ...@@ -1558,6 +1581,35 @@ static BOOL http_protocol_start(LPCWSTR url, BOOL is_first)
return TRUE; return TRUE;
} }
static void test_protocol_terminate(IInternetProtocol *protocol)
{
BYTE buf[3600];
DWORD cb;
HRESULT hres;
hres = IInternetProtocol_LockRequest(protocol, 0);
ok(hres == S_OK, "LockRequest failed: %08x\n", hres);
hres = IInternetProtocol_Read(protocol, buf, 1, &cb);
ok(hres == S_FALSE, "Read failed: %08x\n", hres);
hres = IInternetProtocol_Terminate(protocol, 0);
ok(hres == S_OK, "Terminate failed: %08x\n", hres);
/* This wait is to give the internet handles being freed in Terminate
* enough time to actually terminate in all cases. Internet handles
* terminate asynchronously and native reuses the main InternetOpen
* handle. The only case in which this seems to be necessary is on
* wine with native wininet and urlmon, resulting in the next time
* test_http_protocol_url being called the first data notification actually
* being an extra last data notification from the previous connection
* about once out of every ten times. */
Sleep(100);
hres = IInternetProtocol_UnlockRequest(protocol);
ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
}
/* is_first refers to whether this is the first call to this function /* is_first refers to whether this is the first call to this function
* _for this url_ */ * _for this url_ */
static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
...@@ -1588,13 +1640,14 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) ...@@ -1588,13 +1640,14 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
return; return;
hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol, hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
(void**)&http_protocol); (void**)&async_protocol);
ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres); ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
if(SUCCEEDED(hres)) { if(SUCCEEDED(hres)) {
BYTE buf[3600]; BYTE buf[3600];
DWORD cb; DWORD cb;
ULONG ref;
test_priority(http_protocol); test_priority(async_protocol);
SET_EXPECT(ReportProgress_FINDINGRESOURCE); SET_EXPECT(ReportProgress_FINDINGRESOURCE);
SET_EXPECT(ReportProgress_CONNECTING); SET_EXPECT(ReportProgress_CONNECTING);
...@@ -1616,7 +1669,7 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) ...@@ -1616,7 +1669,7 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
SET_EXPECT(ReportResult); SET_EXPECT(ReportResult);
expect_hrResult = S_OK; expect_hrResult = S_OK;
hres = IInternetProtocol_Read(http_protocol, buf, 1, &cb); hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
ok((hres == E_PENDING && cb==0) || ok((hres == E_PENDING && cb==0) ||
(hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
...@@ -1631,9 +1684,9 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) ...@@ -1631,9 +1684,9 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
SET_EXPECT(Switch); SET_EXPECT(Switch);
else else
SET_EXPECT(ReportData); SET_EXPECT(ReportData);
hres = IInternetProtocol_Read(http_protocol, buf, sizeof(buf), &cb); hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
if(hres == E_PENDING) { if(hres == E_PENDING) {
hres = IInternetProtocol_Read(http_protocol, buf, 1, &cb); hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
ok((hres == E_PENDING && cb==0) || ok((hres == E_PENDING && cb==0) ||
(hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb); (hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
WaitForSingleObject(event_complete, INFINITE); WaitForSingleObject(event_complete, INFINITE);
...@@ -1641,7 +1694,7 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) ...@@ -1641,7 +1694,7 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
CHECK_CALLED(Switch); CHECK_CALLED(Switch);
else else
CHECK_CALLED(ReportData); CHECK_CALLED(ReportData);
} else { }else {
if(bindf & BINDF_FROMURLMON) if(bindf & BINDF_FROMURLMON)
CHECK_NOT_CALLED(Switch); CHECK_NOT_CALLED(Switch);
else else
...@@ -1652,29 +1705,9 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first) ...@@ -1652,29 +1705,9 @@ static void test_http_protocol_url(LPCWSTR url, BOOL is_https, BOOL is_first)
ok(hres == S_FALSE, "Read failed: %08x\n", hres); ok(hres == S_FALSE, "Read failed: %08x\n", hres);
CHECK_CALLED(ReportResult); CHECK_CALLED(ReportResult);
hres = IInternetProtocol_LockRequest(http_protocol, 0); test_protocol_terminate(async_protocol);
ok(hres == S_OK, "LockRequest failed: %08x\n", hres); ref = IInternetProtocol_Release(async_protocol);
ok(!ref, "ref=%x\n", hres);
hres = IInternetProtocol_Read(http_protocol, buf, 1, &cb);
ok(hres == S_FALSE, "Read failed: %08x\n", hres);
hres = IInternetProtocol_Terminate(http_protocol, 0);
ok(hres == S_OK, "Terminate failed: %08x\n", hres);
/* This wait is to give the internet handles being freed in Terminate
* enough time to actually terminate in all cases. Internet handles
* terminate asynchronously and native reuses the main InternetOpen
* handle. The only case in which this seems to be necessary is on
* wine with native wininet and urlmon, resulting in the next time
* test_http_protocol_url being called the first data notification actually
* being an extra last data notification from the previous connection
* about once out of every ten times. */
Sleep(100);
hres = IInternetProtocol_UnlockRequest(http_protocol);
ok(hres == S_OK, "UnlockRequest failed: %08x\n", hres);
IInternetProtocol_Release(http_protocol);
} }
IClassFactory_Release(factory); IClassFactory_Release(factory);
...@@ -1724,6 +1757,93 @@ static void test_https_protocol(void) ...@@ -1724,6 +1757,93 @@ static void test_https_protocol(void)
test_http_protocol_url(codeweavers_url, TRUE, TRUE); test_http_protocol_url(codeweavers_url, TRUE, TRUE);
} }
static void test_ftp_protocol(void)
{
IInternetProtocolInfo *protocol_info;
IClassFactory *factory;
IUnknown *unk;
BYTE buf[4096];
ULONG ref;
DWORD cb;
HRESULT hres;
static const WCHAR ftp_urlW[] = {'f','t','p',':','/','/','f','t','p','.','w','i','n','e','h','q','.','o','r','g',
'/','p','u','b','/','o','t','h','e','r','/',
'w','i','n','e','l','o','g','o','.','x','c','f','.','t','a','r','.','b','z','2',0};
trace("Testing ftp protocol...\n");
bindf = BINDF_ASYNCHRONOUS | BINDF_ASYNCSTORAGE | BINDF_PULLDATA | BINDF_FROMURLMON | BINDF_NOWRITECACHE;
state = 0;
tested_protocol = FTP_TEST;
first_data_notif = TRUE;
expect_hrResult = E_PENDING;
hres = CoGetClassObject(&CLSID_FtpProtocol, CLSCTX_INPROC_SERVER, NULL, &IID_IUnknown, (void**)&unk);
ok(hres == S_OK, "CoGetClassObject failed: %08x\n", hres);
if(FAILED(hres))
return;
hres = IUnknown_QueryInterface(unk, &IID_IInternetProtocolInfo, (void**)&protocol_info);
ok(hres == E_NOINTERFACE, "Could not get IInternetProtocolInfo interface: %08x, expected E_NOINTERFACE\n", hres);
hres = IUnknown_QueryInterface(unk, &IID_IClassFactory, (void**)&factory);
ok(hres == S_OK, "Could not get IClassFactory interface\n");
IUnknown_Release(unk);
if(FAILED(hres))
return;
hres = IClassFactory_CreateInstance(factory, NULL, &IID_IInternetProtocol,
(void**)&async_protocol);
IClassFactory_Release(factory);
ok(hres == S_OK, "Could not get IInternetProtocol: %08x\n", hres);
test_priority(async_protocol);
SET_EXPECT(GetBindInfo);
SET_EXPECT(GetBindString_USER_AGENT);
SET_EXPECT(ReportProgress_FINDINGRESOURCE);
SET_EXPECT(ReportProgress_CONNECTING);
SET_EXPECT(ReportProgress_SENDINGREQUEST);
SET_EXPECT(Switch);
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);
hres = IInternetProtocol_Read(async_protocol, buf, 1, &cb);
ok((hres == E_PENDING && cb==0) ||
(hres == S_OK && cb==1), "Read failed: %08x (%d bytes)\n", hres, cb);
WaitForSingleObject(event_complete, INFINITE);
CHECK_CALLED(Switch);
while(1) {
SET_EXPECT(Switch);
hres = IInternetProtocol_Read(async_protocol, buf, sizeof(buf), &cb);
if(hres == E_PENDING) {
WaitForSingleObject(event_complete, INFINITE);
CHECK_CALLED(Switch);
}else {
CHECK_NOT_CALLED(Switch);
if(cb == 0) break;
}
}
ok(hres == S_FALSE, "Read failed: %08x\n", hres);
CHECK_CALLED(ReportResult);
test_protocol_terminate(async_protocol);
ref = IInternetProtocol_Release(async_protocol);
ok(!ref, "ref=%d\n", ref);
}
static void test_mk_protocol(void) static void test_mk_protocol(void)
{ {
IInternetProtocolInfo *protocol_info; IInternetProtocolInfo *protocol_info;
...@@ -2011,6 +2131,7 @@ START_TEST(protocol) ...@@ -2011,6 +2131,7 @@ START_TEST(protocol)
test_file_protocol(); test_file_protocol();
test_http_protocol(); test_http_protocol();
test_https_protocol(); test_https_protocol();
test_ftp_protocol();
test_mk_protocol(); test_mk_protocol();
test_CreateBinding(); test_CreateBinding();
test_binding(FILE_TEST); test_binding(FILE_TEST);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment