Merge branch 'web-request'
Add wxWebViewRequest and related classes allowing to use HTTPS and HTTP/2. See https://github.com/wxWidgets/wxWidgets/pull/977
This commit is contained in:
@@ -102,6 +102,7 @@ TEST_OBJECTS = \
|
||||
test_typeinfotest.o \
|
||||
test_ipc.o \
|
||||
test_socket.o \
|
||||
test_webrequest.o \
|
||||
test_regextest.o \
|
||||
test_wxregextest.o \
|
||||
test_scopeguardtest.o \
|
||||
@@ -715,6 +716,9 @@ test_ipc.o: $(srcdir)/net/ipc.cpp $(TEST_ODEP)
|
||||
test_socket.o: $(srcdir)/net/socket.cpp $(TEST_ODEP)
|
||||
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/net/socket.cpp
|
||||
|
||||
test_webrequest.o: $(srcdir)/net/webrequest.cpp $(TEST_ODEP)
|
||||
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/net/webrequest.cpp
|
||||
|
||||
test_regextest.o: $(srcdir)/regex/regextest.cpp $(TEST_ODEP)
|
||||
$(CXXC) -c -o $@ $(TEST_CXXFLAGS) $(srcdir)/regex/regextest.cpp
|
||||
|
||||
|
1114
tests/makefile.bcc
Normal file
1114
tests/makefile.bcc
Normal file
File diff suppressed because it is too large
Load Diff
@@ -74,6 +74,7 @@ TEST_OBJECTS = \
|
||||
$(OBJS)\test_typeinfotest.o \
|
||||
$(OBJS)\test_ipc.o \
|
||||
$(OBJS)\test_socket.o \
|
||||
$(OBJS)\test_webrequest.o \
|
||||
$(OBJS)\test_regextest.o \
|
||||
$(OBJS)\test_wxregextest.o \
|
||||
$(OBJS)\test_scopeguardtest.o \
|
||||
@@ -696,6 +697,9 @@ $(OBJS)\test_ipc.o: ./net/ipc.cpp
|
||||
$(OBJS)\test_socket.o: ./net/socket.cpp
|
||||
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
|
||||
|
||||
$(OBJS)\test_webrequest.o: ./net/webrequest.cpp
|
||||
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
|
||||
|
||||
$(OBJS)\test_regextest.o: ./regex/regextest.cpp
|
||||
$(CXX) -c -o $@ $(TEST_CXXFLAGS) $(CPPDEPS) $<
|
||||
|
||||
|
@@ -77,6 +77,7 @@ TEST_OBJECTS = \
|
||||
$(OBJS)\test_typeinfotest.obj \
|
||||
$(OBJS)\test_ipc.obj \
|
||||
$(OBJS)\test_socket.obj \
|
||||
$(OBJS)\test_webrequest.obj \
|
||||
$(OBJS)\test_regextest.obj \
|
||||
$(OBJS)\test_wxregextest.obj \
|
||||
$(OBJS)\test_scopeguardtest.obj \
|
||||
@@ -1130,6 +1131,9 @@ $(OBJS)\test_ipc.obj: .\net\ipc.cpp
|
||||
$(OBJS)\test_socket.obj: .\net\socket.cpp
|
||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\net\socket.cpp
|
||||
|
||||
$(OBJS)\test_webrequest.obj: .\net\webrequest.cpp
|
||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\net\webrequest.cpp
|
||||
|
||||
$(OBJS)\test_regextest.obj: .\regex\regextest.cpp
|
||||
$(CXX) /c /nologo /TP /Fo$@ $(TEST_CXXFLAGS) .\regex\regextest.cpp
|
||||
|
||||
|
407
tests/net/webrequest.cpp
Normal file
407
tests/net/webrequest.cpp
Normal file
@@ -0,0 +1,407 @@
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
// Name: tests/net/webrequest.cpp
|
||||
// Purpose: wxWebRequest test
|
||||
// Author: Tobias Taschner
|
||||
// Created: 2018-10-24
|
||||
// Copyright: (c) 2018 wxWidgets development team
|
||||
// Licence: wxWindows licence
|
||||
/////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
// ----------------------------------------------------------------------------
|
||||
// headers
|
||||
// ----------------------------------------------------------------------------
|
||||
|
||||
#include "testprec.h"
|
||||
|
||||
#ifdef __BORLANDC__
|
||||
#pragma hdrstop
|
||||
#endif
|
||||
|
||||
#ifndef WX_PRECOMP
|
||||
#include "wx/wx.h"
|
||||
#endif // WX_PRECOMP
|
||||
|
||||
#if wxUSE_WEBREQUEST
|
||||
|
||||
#include "wx/webrequest.h"
|
||||
#include "wx/filename.h"
|
||||
#include "wx/wfstream.h"
|
||||
|
||||
// This test uses https://httpbin.org by default, but this can be overridden by
|
||||
// setting WX_TEST_WEBREQUEST_URL, e.g. when running httpbin locally in a
|
||||
// docker container. This variable can also be set to a special value "0" to
|
||||
// disable running the test entirely.
|
||||
static const char* WX_TEST_WEBREQUEST_URL_DEFAULT = "https://httpbin.org";
|
||||
|
||||
class RequestFixture : public wxTimer
|
||||
{
|
||||
public:
|
||||
RequestFixture()
|
||||
{
|
||||
expectedFileSize = 0;
|
||||
dataSize = 0;
|
||||
}
|
||||
|
||||
// All tests should call this function first and skip the test entirely if
|
||||
// it returns false, as this indicates that web requests tests are disabled.
|
||||
bool InitBaseURL()
|
||||
{
|
||||
if ( !wxGetEnv("WX_TEST_WEBREQUEST_URL", &baseURL) )
|
||||
baseURL = WX_TEST_WEBREQUEST_URL_DEFAULT;
|
||||
|
||||
return baseURL != "0";
|
||||
}
|
||||
|
||||
void Create(const wxString& subURL)
|
||||
{
|
||||
CreateAbs(baseURL + subURL);
|
||||
}
|
||||
|
||||
void CreateAbs(const wxString& url)
|
||||
{
|
||||
request = wxWebSession::GetDefault().CreateRequest(this, url);
|
||||
Bind(wxEVT_WEBREQUEST_STATE, &RequestFixture::OnRequestState, this);
|
||||
Bind(wxEVT_WEBREQUEST_DATA, &RequestFixture::OnData, this);
|
||||
}
|
||||
|
||||
void OnRequestState(wxWebRequestEvent& evt)
|
||||
{
|
||||
switch (evt.GetState())
|
||||
{
|
||||
case wxWebRequest::State_Idle:
|
||||
FAIL("should never get events with State_Idle");
|
||||
break;
|
||||
|
||||
case wxWebRequest::State_Active:
|
||||
CHECK( request.GetNativeHandle() );
|
||||
break;
|
||||
|
||||
case wxWebRequest::State_Completed:
|
||||
if ( request.GetStorage() == wxWebRequest::Storage_File )
|
||||
{
|
||||
wxFileName fn(evt.GetDataFile());
|
||||
CHECK( fn.GetSize() == expectedFileSize );
|
||||
}
|
||||
wxFALLTHROUGH;
|
||||
|
||||
case wxWebRequest::State_Unauthorized:
|
||||
case wxWebRequest::State_Failed:
|
||||
case wxWebRequest::State_Cancelled:
|
||||
errorDescription = evt.GetErrorDescription();
|
||||
loop.Exit();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void Notify() wxOVERRIDE
|
||||
{
|
||||
WARN("Exiting loop on timeout");
|
||||
loop.Exit();
|
||||
}
|
||||
|
||||
void OnData(wxWebRequestEvent& evt)
|
||||
{
|
||||
// Count all bytes recieved via data event for Storage_None
|
||||
dataSize += evt.GetDataSize();
|
||||
}
|
||||
|
||||
void RunLoopWithTimeout()
|
||||
{
|
||||
StartOnce(10000); // Ensure that we exit the loop after 10s.
|
||||
loop.Run();
|
||||
Stop();
|
||||
}
|
||||
|
||||
void Run(wxWebRequest::State requiredState = wxWebRequest::State_Completed,
|
||||
int requiredStatus = 200)
|
||||
{
|
||||
REQUIRE( request.GetState() == wxWebRequest::State_Idle );
|
||||
request.Start();
|
||||
RunLoopWithTimeout();
|
||||
REQUIRE( request.GetState() == requiredState );
|
||||
if (requiredStatus)
|
||||
CHECK( request.GetResponse().GetStatus() == requiredStatus );
|
||||
}
|
||||
|
||||
// Precondition: we must have an auth challenge.
|
||||
void UseCredentials(const wxString& user, const wxString& password)
|
||||
{
|
||||
request.GetAuthChallenge().SetCredentials(
|
||||
wxWebCredentials(user, wxSecretValue(password)));
|
||||
}
|
||||
|
||||
wxString baseURL;
|
||||
wxEventLoop loop;
|
||||
wxWebRequest request;
|
||||
wxInt64 expectedFileSize;
|
||||
wxInt64 dataSize;
|
||||
wxString errorDescription;
|
||||
};
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Get::Bytes", "[net][webrequest][get]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/bytes/65536");
|
||||
Run();
|
||||
CHECK( request.GetResponse().GetContentLength() == 65536 );
|
||||
CHECK( request.GetBytesExpectedToReceive() == 65536 );
|
||||
CHECK( request.GetBytesReceived() == 65536 );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Get::Simple", "[net][webrequest][get]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
// Note that the session may be initialized on demand, so don't check the
|
||||
// native handle before actually using it.
|
||||
wxWebSession& session = wxWebSession::GetDefault();
|
||||
REQUIRE( session.IsOpened() );
|
||||
|
||||
// Request is not initialized yet.
|
||||
CHECK( !request.IsOk() );
|
||||
CHECK( !request.GetNativeHandle() );
|
||||
|
||||
Create("/status/200");
|
||||
CHECK( request.IsOk() );
|
||||
CHECK( session.GetNativeHandle() );
|
||||
|
||||
// Note that the request must be started to have a valid native handle.
|
||||
request.Start();
|
||||
CHECK( request.GetNativeHandle() );
|
||||
RunLoopWithTimeout();
|
||||
CHECK( request.GetState() == wxWebRequest::State_Completed );
|
||||
CHECK( request.GetResponse().GetStatus() == 200 );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Get::String", "[net][webrequest][get]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/base64/VGhlIHF1aWNrIGJyb3duIGZveCBqdW1wcyBvdmVyIHRoZSBsYXp5IGRvZw==");
|
||||
Run();
|
||||
CHECK( request.GetResponse().AsString() == "The quick brown fox jumps over the lazy dog" );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Get::File", "[net][webrequest][get]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
expectedFileSize = 99 * 1024;
|
||||
Create(wxString::Format("/bytes/%lld", expectedFileSize));
|
||||
request.SetStorage(wxWebRequest::Storage_File);
|
||||
Run();
|
||||
CHECK( request.GetBytesReceived() == expectedFileSize );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Get::None", "[net][webrequest][get]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
int processingSize = 99 * 1024;
|
||||
Create(wxString::Format("/bytes/%d", processingSize));
|
||||
request.SetStorage(wxWebRequest::Storage_None);
|
||||
Run();
|
||||
CHECK( request.GetBytesReceived() == processingSize );
|
||||
CHECK( dataSize == processingSize );
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Error::HTTP", "[net][webrequest][error]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/status/404");
|
||||
Run(wxWebRequest::State_Failed, 404);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Error::Body", "[net][webrequest][error]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
// We can't use the same httpbin.org server that we use for the other tests
|
||||
// for this one because it doesn't return anything in the body when
|
||||
// returning an error status code, so use another one.
|
||||
CreateAbs("https://httpstat.us/418");
|
||||
Run(wxWebRequest::State_Failed, 0);
|
||||
|
||||
// For some reason, this test doesn't work with libcurl included in Ubuntu
|
||||
// 14.04, so skip it.
|
||||
const int status = request.GetResponse().GetStatus();
|
||||
if ( status == 0 )
|
||||
{
|
||||
WARN("Status code not returned.");
|
||||
}
|
||||
else
|
||||
{
|
||||
CHECK( status == 418 );
|
||||
CHECK( request.GetResponse().AsString() == "418 I'm a teapot" );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Error::Connect", "[net][webrequest][error]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
CreateAbs("http://127.0.0.1:51234");
|
||||
Run(wxWebRequest::State_Failed, 0);
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Post", "[net][webrequest]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/post");
|
||||
request.SetData("app=WebRequestSample&version=1", "application/x-www-form-urlencoded");
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Put", "[net][webrequest]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/put");
|
||||
wxScopedPtr<wxInputStream> is(new wxFileInputStream("horse.png"));
|
||||
REQUIRE( is->IsOk() );
|
||||
|
||||
request.SetData(is.release(), "image/png");
|
||||
request.SetMethod("PUT");
|
||||
Run();
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Auth::Basic", "[net][webrequest][auth]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/basic-auth/wxtest/wxwidgets");
|
||||
Run(wxWebRequest::State_Unauthorized, 401);
|
||||
REQUIRE( request.GetAuthChallenge().IsOk() );
|
||||
|
||||
SECTION("Good password")
|
||||
{
|
||||
UseCredentials("wxtest", "wxwidgets");
|
||||
RunLoopWithTimeout();
|
||||
CHECK( request.GetResponse().GetStatus() == 200 );
|
||||
CHECK( request.GetState() == wxWebRequest::State_Completed );
|
||||
}
|
||||
|
||||
SECTION("Bad password")
|
||||
{
|
||||
UseCredentials("wxtest", "foobar");
|
||||
RunLoopWithTimeout();
|
||||
CHECK( request.GetResponse().GetStatus() == 401 );
|
||||
CHECK( request.GetState() == wxWebRequest::State_Unauthorized );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Auth::Digest", "[net][webrequest][auth]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/digest-auth/auth/wxtest/wxwidgets");
|
||||
Run(wxWebRequest::State_Unauthorized, 401);
|
||||
REQUIRE( request.GetAuthChallenge().IsOk() );
|
||||
|
||||
SECTION("Good password")
|
||||
{
|
||||
UseCredentials("wxtest", "wxwidgets");
|
||||
RunLoopWithTimeout();
|
||||
CHECK( request.GetResponse().GetStatus() == 200 );
|
||||
CHECK( request.GetState() == wxWebRequest::State_Completed );
|
||||
}
|
||||
|
||||
SECTION("Bad password")
|
||||
{
|
||||
UseCredentials("foo", "bar");
|
||||
RunLoopWithTimeout();
|
||||
CHECK( request.GetResponse().GetStatus() == 401 );
|
||||
CHECK( request.GetState() == wxWebRequest::State_Unauthorized );
|
||||
}
|
||||
}
|
||||
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Cancel", "[net][webrequest]")
|
||||
{
|
||||
if ( !InitBaseURL() )
|
||||
return;
|
||||
|
||||
Create("/delay/10");
|
||||
request.Start();
|
||||
request.Cancel();
|
||||
RunLoopWithTimeout();
|
||||
if ( !errorDescription.empty() )
|
||||
INFO( "Error:" << errorDescription );
|
||||
REQUIRE( request.GetState() == wxWebRequest::State_Cancelled );
|
||||
}
|
||||
|
||||
// This test is not run by default and has to be explicitly selected to run.
|
||||
TEST_CASE_METHOD(RequestFixture,
|
||||
"WebRequest::Manual", "[.]")
|
||||
{
|
||||
// Allow getting 8-bit strings from the environment correctly.
|
||||
setlocale(LC_ALL, "");
|
||||
|
||||
wxString url;
|
||||
if ( !wxGetEnv("WX_TEST_WEBREQUEST_URL", &url) )
|
||||
{
|
||||
FAIL("Specify WX_TEST_WEBREQUEST_URL");
|
||||
}
|
||||
|
||||
CreateAbs(url);
|
||||
request.Start();
|
||||
RunLoopWithTimeout();
|
||||
|
||||
WARN("Request state " << request.GetState());
|
||||
wxWebResponse response = request.GetResponse();
|
||||
REQUIRE( response.IsOk() );
|
||||
WARN("Status: " << response.GetStatus()
|
||||
<< " (" << response.GetStatusText() << ")\n" <<
|
||||
"Body length: " << response.GetContentLength() << "\n" <<
|
||||
"Body: " << response.AsString() << "\n");
|
||||
}
|
||||
|
||||
WX_DECLARE_STRING_HASH_MAP(wxString, wxWebRequestHeaderMap);
|
||||
|
||||
namespace wxPrivate
|
||||
{
|
||||
WXDLLIMPEXP_NET wxString
|
||||
SplitParameters(const wxString& s, wxWebRequestHeaderMap& parameters);
|
||||
}
|
||||
|
||||
TEST_CASE("WebRequestUtils", "[net][webrequest]")
|
||||
{
|
||||
wxString value;
|
||||
wxWebRequestHeaderMap params;
|
||||
|
||||
wxString header = "multipart/mixed; boundary=\"MIME_boundary_01234567\"";
|
||||
|
||||
value = wxPrivate::SplitParameters(header, params);
|
||||
CHECK( value == "multipart/mixed" );
|
||||
CHECK( params.size() == 1 );
|
||||
CHECK( params["boundary"] == "MIME_boundary_01234567" );
|
||||
}
|
||||
|
||||
#endif // wxUSE_WEBREQUEST
|
@@ -70,6 +70,7 @@
|
||||
misc/typeinfotest.cpp
|
||||
net/ipc.cpp
|
||||
net/socket.cpp
|
||||
net/webrequest.cpp
|
||||
regex/regextest.cpp
|
||||
regex/wxregextest.cpp
|
||||
scopeguard/scopeguardtest.cpp
|
||||
|
@@ -171,7 +171,13 @@ static void TestAssertHandler(const wxString& file,
|
||||
|
||||
CATCH_TRANSLATE_EXCEPTION(TestAssertFailure& e)
|
||||
{
|
||||
return e.m_msg.ToStdString(wxConvUTF8);
|
||||
wxString desc = e.m_msg;
|
||||
if ( desc.empty() )
|
||||
desc.Printf(wxASCII_STR("Condition \"%s\" failed"), e.m_cond);
|
||||
|
||||
desc += wxString::Format(wxASCII_STR(" in %s() at %s:%d"), e.m_func, e.m_file, e.m_line);
|
||||
|
||||
return desc.ToStdString(wxConvUTF8);
|
||||
}
|
||||
|
||||
#endif // wxDEBUG_LEVEL
|
||||
|
@@ -524,6 +524,7 @@
|
||||
<ClCompile Include="misc\typeinfotest.cpp" />
|
||||
<ClCompile Include="net\ipc.cpp" />
|
||||
<ClCompile Include="net\socket.cpp" />
|
||||
<ClCompile Include="net\webrequest.cpp" />
|
||||
<ClCompile Include="regex\regextest.cpp" />
|
||||
<ClCompile Include="regex\wxregextest.cpp" />
|
||||
<ClCompile Include="scopeguard\scopeguardtest.cpp" />
|
||||
@@ -570,4 +571,4 @@
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets">
|
||||
</ImportGroup>
|
||||
</Project>
|
||||
</Project>
|
@@ -265,5 +265,8 @@
|
||||
<ClCompile Include="streams\lzmastream.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="net\webrequest.cpp">
|
||||
<Filter>Source Files</Filter>
|
||||
</ClCompile>
|
||||
</ItemGroup>
|
||||
</Project>
|
@@ -562,6 +562,9 @@
|
||||
<File
|
||||
RelativePath=".\weakref\weakref.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\net\webrequest.cpp">
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\regex\wxregextest.cpp">
|
||||
</File>
|
||||
|
@@ -1218,6 +1218,10 @@
|
||||
RelativePath=".\weakref\weakref.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\net\webrequest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\regex\wxregextest.cpp"
|
||||
>
|
||||
|
@@ -1190,6 +1190,10 @@
|
||||
RelativePath=".\weakref\weakref.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\net\webrequest.cpp"
|
||||
>
|
||||
</File>
|
||||
<File
|
||||
RelativePath=".\regex\wxregextest.cpp"
|
||||
>
|
||||
|
Reference in New Issue
Block a user