The IPC tests were excluded from wxQt because wxIPC worker threads
marshal their socket I/O to the main thread via CallAfter(), and a
cross-thread CallAfter() was not reliably processed by the wxQt event
loop, stalling the tests. Now that the previous commit makes WakeUp()
post a real Qt event, the whole suite runs on wxQt: remove the
__WXQT__ exclusions from the test guards (including the one in
tests/test.cpp that compiled out the re-exec'd server mode) and the
comments explaining them.
All 10 [ipc] cases pass repeatedly on wxQt in both test and test_gui,
with both a real X server and QT_QPA_PLATFORM=offscreen. Notably the
offscreen runs are meaningful for the previous commit's fix: with an X
server connected, X-connection traffic keeps rescheduling the idle
timer and can mask a missing WakeUp() event, while offscreen the
event loop goes truly idle.
Now that we have fixtures, with ctors and dtors, instead of setUp() and
tearDown(), we can use std::unique_ptr<> instead of manual memory
management.
No real changes.
Now that none of the tests use the CppUnit compatibility macros any more,
this header can be removed entirely.
Move the pieces still needed by the tests, i.e. wxINFO_FMT(),
WX_ASSERT_MESSAGE(), WX_ASSERT_EQUAL_MESSAGE() and the Catch::StringMaker
specializations for wxString and wxUniChar[Ref], to tests/testprec.h.
wxGetCurrentTestName() is now implemented using Catch itself instead of the
strings set by the CppUnit macros, which means that it finally returns the
correct name for all the tests and not just the CppUnit-style ones.
Assisted-by: Claude Opus 5
Notably, the socket tests using the event loop now use Catch GENERATE()
to run them both with and without the active event loop instead of the
PseudoTest_SetUseEventLoop() hack.
No other changes.
Check the web session native handle only after starting the request, as the
macOS URLSession backend creates the native session lazily.
This avoids depending on prior tests having initialized shared process state.
Make auth and DELETE response checks independent of JSON whitespace, preserve
the base URL path when redirecting to basic auth, and skip digest auth only
with the default public httpbin mirror and WinHTTP backend.
Fix multiple issues in IPC using TCP sockets.
This is a substantial rewrite of the old code which brings improved
error detection, MT-safety and many other fixes.
There is also a much better test suite exercising this code now.
See #24858.
IPCFixture set the gs_clientLoop global mid-constructor but only cleared
it in the destructor. If the constructor threw after that assignment --
which happens when REQUIRE(serverReady) fails because the re-exec'd
server did not come up in time -- the object never became alive, so the
destructor never ran to null the global, yet the m_clientLoop member was
still destroyed during stack unwinding. That left gs_clientLoop dangling
at a freed wxEventLoop (and leaked gs_client), and the next fixture's
opening DrainPendingIPCEvents() dereferenced the freed loop. The defect
is single-threaded, so ThreadSanitizer never flagged it; AddressSanitizer
reports it as a heap-use-after-free in DrainPendingIPCEvents().
Make construction all-or-nothing with a dismissable guard that resets the
globals (and balances wxSocketBase::Shutdown()) on any early exit, and
raise the server-readiness bound to 120s under sanitizers, where the
instrumented server is much slower to start, so the timeout no longer
fires spuriously.
WaitForAdviseWorkers() skipped Wait() when a worker thread had already
finished, but a joinable thread must be joined even then to release
its resources. The skipped joins showed up as ThreadSanitizer "thread
leak" reports in the re-executed server processes when running the
IPC tests under TSan.
Add a test exercising the IPC-over-sockets implementation from a single
thread and from multiple threads concurrently (Execute, Request, Poke,
Advise, combined Advise+Request, and concurrent main-thread and
worker-thread Request()s).
Each test starts its own server by re-executing the test program with
WX_IPC_TEST_SERVER set and shuts it down again in the fixture teardown, so
no server process outlives a test (or disturbs the unrelated GUI tests in
test_gui). The client runs in the main Catch2 process and queries the server
for state to verify it (Catch2 macros cannot run in the server process). The
wait loops are wall-clock bounded so they behave under a GUI event loop, and
a per-fixture watchdog aborts with a diagnostic if a test ever hangs rather
than letting CI time out.
The test runs in both the console "test" and the GUI "test_gui" programs. It
is excluded from one configuration: wxQt, whose event loop does not reliably
process a cross-thread CallAfter() (a wxQt bug fixed separately).
Allow getting detailed information about the operations performed by
wxWebRequest, at least when using libcurl-based backend, which provides
good built-in support for this, and partially when using WinHTTP.
Note that the debug logger is set at the session level and not for each
request: this is less flexible, but more convenient and is probably how
it will always be used in practice.
See #26086.
Add UseBasicAuth() which allows to avoid an extra round trip to the
server due to trying to access a protected URL without providing the
credentials first and only sending them in response to 401 response.
For libcurl, simply set authentication method to CURLAUTH_BASIC and let
the library handle everything. For the other backends, add the required
"Authorization" header ourselves, as they don't seem to have any support
for doing preemptive authentication on their own.
Set seek callback to allow libcurl to reuse the data being uploaded when
it has to redo the HTTP request, e.g. because of redirection after a 301
or resubmitting it with correct authentication data after a 401.
Add a test checking that this works correctly, although it has to be
disabled for WinHTTP for now as it doesn't handle 307/308 redirects
automatically (see #26046).
They are simply not handled properly by NSURLRequest, apparently, and
there doesn't seem to be any simple way around it, so for now just
document that this doesn't work and adjust the test to avoid using
reserved characters in the password when using NSURLSession-based
backend.
Although username/password with the reserved characters worked correctly
when using them via wxWebAuthChallenge::SetCredentials() (see the parent
commit), specifying such usernames/passwords in the URL itself didn't
work correctly because they were used in their percent-encoded form, as
this is how WinHttpCrackUrl() returns them to us.
Fix this by decoding them ourselves.
Add a test which works now but would fail when using WinHTTP backend
before.
This reverts commit 8395e5733d because
HTTP standard says that senders MUST NOT generate multiple lines with
the same header, with the only exception of Set-Cookie, so we shouldn't
provide a way to do it.
That commit also introduced a nasty regression with the programs calling
AddCommonHeader("User-Agent") not working at all any more after it
because WinHTTP refuses to send a request with multiple copies of this
header.
Also partially reverts 1000d67c13 which
was done later but is logically part of the same commit that is being
reverted.
See #24881.
This object shouldn't be destroyed as long as there are any
wxWebRequests using it still alive, as destroying them after the session
would result in a crash, so replace a (possibly dangling) reference to
wxWebSessionImpl in wxWebRequestImpl with a shared pointer, which keeps
it alive for as long as necessary.
See #24969.
The format of the generated JSON by the httpbin service for
multiple headers with the same name differs between platforms.
These headers are sometimes put into a JSON array and sometimes
concatenated into a single comma-separated string.
wxWebRequest::AddHeader() was added to accompany the existing
SetHeader() method. In wxWebSession, AddCommonHeader() did exist
already but behaved like setting a header. Its behavior was adapted
to its name and SetCommonHeader() was added with the old behavior
to accompany AddCommonHeader().
The WinHTTP and CURL implementations of wxWebRequest do now append
multiple headers of the same name. The URLSession implementation
follows in the next commits.
HTTP headers like Set-Cookie can be present multiple times in a
web response by definition. The existing GetHeader() method is
not sufficient to cope with this situation.
This commit already adds an implementation for Windows.
Linux and macOS follow in the next commits.
Instead of constructing the full URLs manually simplify the test by
using SetBaseURL().
This required removing leading slashes from all relative URLs used in
the test, but there are no other real changes.
Allow disabling the proxy used by default or specifying a custom proxy.
Unfortunately NSURLSession implementation doesn't support neither paths
in the proxy URLs nor proxy authentication when using synchronous
requests, but there doesn't seem to be any way around it.
This may not happen if the session couldn't be initialized for some
reason and it's better to stop the test immediately in this case than to
give a lot of other confusing errors later.
Previously body wasn't sent, even if it was specified, for the custom
requests such as DELETE.
Fix this by setting CURLOPT_UPLOAD and CURLOPT_INFILESIZE options if the
body is present for any method except POST, which is handled specially
by libcurl, and not only for PUT.
Add a unit test checking that this works now.
No real changes, just add GetHTTPMethod() helper function in the base
wxWebRequestImpl class and use it in all backends: previously, WinHTTP
and NSURLSession ones already did the same thing, but each in their own
way, while libcurl backend used a different logic which was mostly
equivalent, but this was not really obvious, while now it should be.
Also add a test for using a custom method (DELETE), for now without
body, as this is (still) not supported by libcurl backend.
Allow defining a single WX_TEST_WEBREQUEST_USE_BADSSL environment
variable to use badssl.com for all tests instead of bothering with
defining each variable separately (but it's still possible to do it and
override the default values implied by WX_TEST_WEBREQUEST_USE_BADSSL).
Allow disabling host name checks too, to make the connection completely
insecure by accepting any certificate for any host.
Incidentally, this also allows checking for valid certificate for any
host, even if this doesn't seem tremendously useful.
Document that disabling any kind of verification in NSURLSession-based
backend disables all of them and also significantly refactor and extend
unit tests checking for this.
The wxWebAuthChallenge-based approach seems to be unnecessarily
complicated for the synchronous use case and isn't supported by the
current NSURLSession backend implementation (although this could be
changed by rewriting it to use a different delegate for the sync
requests and remembering wxWebAuthChallenge in it between the calls to
Execute()).
For now, just drop support for it and require specifying the
authentication information in the URL itself.