Allow reusing POST data when using wxWebRequestCURL 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).
Add wxWebCredentials::IsOk() Add a trivial accessor to make testing for whether we are using a default constructed or initialized object simpler.
Add support for preemptively using "Basic" HTTP authentication 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.
Fix using built-in libjpeg from built-in libtiff This didn't work before, usually just silently disabling JPEG support in libtiff because libjpeg couldn't be found, but sometimes also resulting in build errors due to libtiff configure detecting a newer version of libjpeg available in the system and then trying to use its features (such as "dual 8/12 bit mode", whatever it is, in libjpeg-turbo > 3) when building using the actually used version resulting in build errors.
Merge branch 'webrequest-improve-redirect' Improvements to wxWebRequest handling of multiple requests (due to redirects and/or authorization required). See #26048.
| ... | ... | @@ -26531,8 +26531,8 @@ $as_echo "yes" >&6; } |
| 26531 | 26531 | fi
|
| 26532 | 26532 | if test "$wxUSE_LIBJPEG" = "no"; then
|
| 26533 | 26533 | tiff_jpeg_option=--disable-jpeg
|
| 26534 | - else
|
|
| 26535 | - tiff_jpeg_option=--enable-jpeg
|
|
| 26534 | + elif test "$wxUSE_LIBJPEG" = "builtin"; then
|
|
| 26535 | + tiff_jpeg_option=--with-jpeg-from-wx
|
|
| 26536 | 26536 | fi
|
| 26537 | 26537 | |
| 26538 | 26538 |
| ... | ... | @@ -2656,8 +2656,11 @@ if test "$wxUSE_LIBTIFF" != "no" ; then |
| 2656 | 2656 | dnl the top-level script to all the other ones called recursively), so
|
| 2657 | 2657 | dnl we need to hack around this
|
| 2658 | 2658 | tiff_jpeg_option=--disable-jpeg
|
| 2659 | - else
|
|
| 2660 | - tiff_jpeg_option=--enable-jpeg
|
|
| 2659 | + elif test "$wxUSE_LIBJPEG" = "builtin"; then
|
|
| 2660 | + dnl JPEG support is enabled by default, but make sure that we use
|
|
| 2661 | + dnl our own libjpeg, even if another version of the library is
|
|
| 2662 | + dnl installed system-wide
|
|
| 2663 | + tiff_jpeg_option=--with-jpeg-from-wx
|
|
| 2661 | 2664 | fi
|
| 2662 | 2665 | |
| 2663 | 2666 | dnl if you ever want to enable webp, check if it clashes with the wxUSE_LIBWBP setting
|
| ... | ... | @@ -90,6 +90,11 @@ public: |
| 90 | 90 | |
| 91 | 91 | virtual void SetTimeouts(long connectionTimeoutMs, long dataTimeoutMs) = 0;
|
| 92 | 92 | |
| 93 | + void UseBasicAuth(const wxWebCredentials& cred)
|
|
| 94 | + {
|
|
| 95 | + m_basicAuthCred = cred;
|
|
| 96 | + }
|
|
| 97 | + |
|
| 93 | 98 | virtual wxWebResponseImplPtr GetResponse() const = 0;
|
| 94 | 99 | |
| 95 | 100 | virtual wxWebAuthChallengeImplPtr GetAuthChallenge() const = 0;
|
| ... | ... | @@ -125,6 +130,16 @@ public: |
| 125 | 130 | wxEvtHandler* GetHandler() const { return m_handler; }
|
| 126 | 131 | |
| 127 | 132 | protected:
|
| 133 | + // Used by the implementation which don't support preemptive basic
|
|
| 134 | + // authentication natively.
|
|
| 135 | + void AddBasicAuthHeaderIfNecessary();
|
|
| 136 | + |
|
| 137 | + // Direct access for those that do support it natively (don't use it just
|
|
| 138 | + // to redo what AddBasicAuthHeaderIfNecessary() does).
|
|
| 139 | + const wxWebCredentials& GetBasicAuthCredentials() const
|
|
| 140 | + { return m_basicAuthCred; }
|
|
| 141 | + |
|
| 142 | + |
|
| 128 | 143 | wxString m_method;
|
| 129 | 144 | wxWebRequest::Storage m_storage = wxWebRequest::Storage_Memory;
|
| 130 | 145 | wxWebRequestHeaderMap m_headers;
|
| ... | ... | @@ -205,6 +220,9 @@ private: |
| 205 | 220 | wxFileOffset m_bytesReceived = 0;
|
| 206 | 221 | wxCharBuffer m_dataText;
|
| 207 | 222 | |
| 223 | + // If not empty, use preemptive basic authentication.
|
|
| 224 | + wxWebCredentials m_basicAuthCred;
|
|
| 225 | + |
|
| 208 | 226 | // Initially false, set to true after the first call to Cancel().
|
| 209 | 227 | bool m_cancelled = false;
|
| 210 | 228 |
| ... | ... | @@ -89,8 +89,9 @@ public: |
| 89 | 89 | |
| 90 | 90 | wxString GetError() const;
|
| 91 | 91 | |
| 92 | - // Method called from libcurl callback
|
|
| 92 | + // These functions implement libcurl callbacks.
|
|
| 93 | 93 | size_t CURLOnRead(char* buffer, size_t size);
|
| 94 | + int CURLOnSeek(curl_off_t offset, int origin);
|
|
| 94 | 95 | |
| 95 | 96 | private:
|
| 96 | 97 | // Common initialization for sync and async requests performed when the
|
| ... | ... | @@ -26,6 +26,8 @@ public: |
| 26 | 26 | {
|
| 27 | 27 | }
|
| 28 | 28 | |
| 29 | + bool IsOk() const { return !m_user.empty(); }
|
|
| 30 | + |
|
| 29 | 31 | const wxString& GetUser() const { return m_user; }
|
| 30 | 32 | const wxSecretValue& GetPassword() const { return m_password; }
|
| 31 | 33 | |
| ... | ... | @@ -219,6 +221,8 @@ public: |
| 219 | 221 | |
| 220 | 222 | void SetTimeouts(long connectionTimeoutMs, long dataTimeoutMs);
|
| 221 | 223 | |
| 224 | + void UseBasicAuth(const wxWebCredentials& cred);
|
|
| 225 | + |
|
| 222 | 226 | Storage GetStorage() const;
|
| 223 | 227 | |
| 224 | 228 | wxWebResponse GetResponse() const;
|
| ... | ... | @@ -477,6 +477,26 @@ public: |
| 477 | 477 | */
|
| 478 | 478 | void SetTimeouts(long connectionTimeoutMs, long dataTimeoutMs);
|
| 479 | 479 | |
| 480 | + /**
|
|
| 481 | + Explicitly request using HTTP "Basic" authentication with the provided
|
|
| 482 | + credentials.
|
|
| 483 | + |
|
| 484 | + If this function is not called, wxWebRequest initially makes a request
|
|
| 485 | + without using any authentication and then requests credentials from the
|
|
| 486 | + application, using the preferred authentication method among those
|
|
| 487 | + supported by both the client and the server, using wxWebAuthChallenge.
|
|
| 488 | + This is the most flexible approach, but it always requires making an
|
|
| 489 | + extra HTTP request.
|
|
| 490 | + |
|
| 491 | + If the application knows that "Basic" authentication should be used, it
|
|
| 492 | + can avoid this extra request by calling this function before calling
|
|
| 493 | + Execute(): this will use the provided credentials for the initial
|
|
| 494 | + request.
|
|
| 495 | + |
|
| 496 | + @since 3.3.2
|
|
| 497 | + */
|
|
| 498 | + void UseBasicAuth(const wxWebCredentials& cred);
|
|
| 499 | + |
|
| 480 | 500 | /**
|
| 481 | 501 | Flags for disabling security features.
|
| 482 | 502 | |
| ... | ... | @@ -609,16 +629,17 @@ public: |
| 609 | 629 | }
|
| 610 | 630 | @endcode
|
| 611 | 631 | |
| 612 | - To handle authentication with this class the username and password must be
|
|
| 613 | - specified in the URL itself and wxWebAuthChallenge is not used with it.
|
|
| 632 | + wxWebAuthChallenge is not used with this class, to access protected
|
|
| 633 | + resources the username and password may be specified in the URL itself or
|
|
| 634 | + UseBasicAuth() must be called prior to Execute().
|
|
| 614 | 635 | |
| 615 | 636 | @note Any reserved characters (see RFC 3986) in the username or password
|
| 616 | 637 | must be percent encoded. wxURI::SetUserAndPassword() can be used to
|
| 617 | 638 | ensure that this is done correctly.
|
| 618 | 639 | |
| 619 | 640 | @note macOS backend using NSURLSession doesn't handle encoded characters in
|
| 620 | - the password (but does handle them in the username). Async wxWebSession
|
|
| 621 | - must be used if you need to support them under this platform.
|
|
| 641 | + the password (but does handle them in the username). Use wxWebSession or
|
|
| 642 | + UseBasicAuth() if you need to support them under this platform.
|
|
| 622 | 643 | |
| 623 | 644 | @see wxWebRequest
|
| 624 | 645 | |
| ... | ... | @@ -965,6 +986,25 @@ public: |
| 965 | 986 | */
|
| 966 | 987 | void SetTimeouts(long connectionTimeoutMs, long dataTimeoutMs);
|
| 967 | 988 | |
| 989 | + /**
|
|
| 990 | + Explicitly request using HTTP "Basic" authentication with the provided
|
|
| 991 | + credentials.
|
|
| 992 | + |
|
| 993 | + If this function is not called, wxWebRequestSync will use the
|
|
| 994 | + credentials from the URL itself to authenticate with the server if
|
|
| 995 | + necessary. This has the advantage of supporting multiple authentication
|
|
| 996 | + methods, but requires an extra HTTP request to be made to discover the
|
|
| 997 | + methods supported by the server.
|
|
| 998 | + |
|
| 999 | + If the application knows that "Basic" authentication should be used, it
|
|
| 1000 | + can avoid this extra request by calling this function before calling
|
|
| 1001 | + Execute(): this will use the provided credentials for the initial
|
|
| 1002 | + request.
|
|
| 1003 | + |
|
| 1004 | + @since 3.3.2
|
|
| 1005 | + */
|
|
| 1006 | + void UseBasicAuth(const wxWebCredentials& cred);
|
|
| 1007 | + |
|
| 968 | 1008 | /**
|
| 969 | 1009 | Make connection insecure by disabling security checks.
|
| 970 | 1010 | |
| ... | ... | @@ -1070,6 +1110,16 @@ public: |
| 1070 | 1110 | wxWebCredentials(const wxString& user = wxString(),
|
| 1071 | 1111 | const wxSecretValue& password = wxSecretValue());
|
| 1072 | 1112 | |
| 1113 | + /**
|
|
| 1114 | + Return true if user name is set.
|
|
| 1115 | + |
|
| 1116 | + This can be used to distinguish this object from the
|
|
| 1117 | + default-constructed one.
|
|
| 1118 | + |
|
| 1119 | + @since 3.3.2
|
|
| 1120 | + */
|
|
| 1121 | + bool IsOk() const;
|
|
| 1122 | + |
|
| 1073 | 1123 | /// Return the user.
|
| 1074 | 1124 | const wxString& GetUser() const;
|
| 1075 | 1125 |
| ... | ... | @@ -13,6 +13,8 @@ |
| 13 | 13 | #if wxUSE_WEBREQUEST
|
| 14 | 14 | |
| 15 | 15 | #include "wx/webrequest.h"
|
| 16 | + |
|
| 17 | +#include "wx/base64.h"
|
|
| 16 | 18 | #include "wx/mstream.h"
|
| 17 | 19 | #include "wx/module.h"
|
| 18 | 20 | #include "wx/uri.h"
|
| ... | ... | @@ -184,6 +186,22 @@ wxWebRequestImpl::SetData(std::unique_ptr<wxInputStream> dataStream, |
| 184 | 186 | return true;
|
| 185 | 187 | }
|
| 186 | 188 | |
| 189 | +void wxWebRequestImpl::AddBasicAuthHeaderIfNecessary()
|
|
| 190 | +{
|
|
| 191 | + if ( !m_basicAuthCred.IsOk() )
|
|
| 192 | + return;
|
|
| 193 | + |
|
| 194 | + const auto authInfo = wxString::Format("%s:%s",
|
|
| 195 | + m_basicAuthCred.GetUser(),
|
|
| 196 | + m_basicAuthCred.GetPassword().GetAsString()
|
|
| 197 | + );
|
|
| 198 | + |
|
| 199 | + const auto buf = authInfo.utf8_str();
|
|
| 200 | + |
|
| 201 | + SetHeader("Authorization",
|
|
| 202 | + "Basic " + wxBase64Encode(buf.data(), buf.length()));
|
|
| 203 | +}
|
|
| 204 | + |
|
| 187 | 205 | wxFileOffset wxWebRequestImpl::GetBytesReceived() const
|
| 188 | 206 | {
|
| 189 | 207 | return m_bytesReceived;
|
| ... | ... | @@ -477,6 +495,12 @@ void wxWebRequestBase::SetTimeouts(long connectionTimeoutMs, long dataTimeoutMs) |
| 477 | 495 | m_impl->SetTimeouts(connectionTimeoutMs, dataTimeoutMs);
|
| 478 | 496 | }
|
| 479 | 497 | |
| 498 | +void wxWebRequestBase::UseBasicAuth(const wxWebCredentials& cred)
|
|
| 499 | +{
|
|
| 500 | + wxCHECK_IMPL_VOID();
|
|
| 501 | + |
|
| 502 | + m_impl->UseBasicAuth(cred);
|
|
| 503 | +}
|
|
| 480 | 504 | |
| 481 | 505 | wxWebRequestBase::Storage wxWebRequestBase::GetStorage() const
|
| 482 | 506 | {
|
| ... | ... | @@ -50,6 +50,10 @@ |
| 50 | 50 | #define CURLOPT_ACCEPT_ENCODING CURLOPT_ENCODING
|
| 51 | 51 | #endif
|
| 52 | 52 | |
| 53 | +#if wxUSE_LOG_TRACE
|
|
| 54 | +constexpr const char* TRACE_CURL = "curl";
|
|
| 55 | +#endif
|
|
| 56 | + |
|
| 53 | 57 | // Define libcurl timeout constants
|
| 54 | 58 | static constexpr int LIBCURL_DEFAULT_CONNECT_TIMEOUT = 300000; // 5m in ms.
|
| 55 | 59 | |
| ... | ... | @@ -335,6 +339,13 @@ static size_t wxCURLRead(char *buffer, size_t size, size_t nitems, void *userdat |
| 335 | 339 | return static_cast<wxWebRequestCURL*>(userdata)->CURLOnRead(buffer, size * nitems);
|
| 336 | 340 | }
|
| 337 | 341 | |
| 342 | +static int wxCURLSeek(void* userdata, curl_off_t offset, int origin)
|
|
| 343 | +{
|
|
| 344 | + wxCHECK_MSG( userdata, CURL_SEEKFUNC_CANTSEEK, "invalid curl seek callback data" );
|
|
| 345 | + |
|
| 346 | + return static_cast<wxWebRequestCURL*>(userdata)->CURLOnSeek(offset, origin);
|
|
| 347 | +}
|
|
| 348 | + |
|
| 338 | 349 | wxWebRequestCURL::wxWebRequestCURL(wxWebSession & session,
|
| 339 | 350 | wxWebSessionCURL& sessionImpl,
|
| 340 | 351 | wxEvtHandler* handler,
|
| ... | ... | @@ -377,6 +388,8 @@ void wxWebRequestCURL::DoStartPrepare(const wxString& url) |
| 377 | 388 | wxCURLSetOpt(m_handle, CURLOPT_HEADERFUNCTION, wxCURLHeader);
|
| 378 | 389 | wxCURLSetOpt(m_handle, CURLOPT_READFUNCTION, wxCURLRead);
|
| 379 | 390 | wxCURLSetOpt(m_handle, CURLOPT_READDATA, this);
|
| 391 | + wxCURLSetOpt(m_handle, CURLOPT_SEEKFUNCTION, wxCURLSeek);
|
|
| 392 | + wxCURLSetOpt(m_handle, CURLOPT_SEEKDATA, this);
|
|
| 380 | 393 | // Enable gzip, etc decompression
|
| 381 | 394 | wxCURLSetOpt(m_handle, CURLOPT_ACCEPT_ENCODING, "");
|
| 382 | 395 | // Enable redirection handling
|
| ... | ... | @@ -419,8 +432,9 @@ void wxWebRequestCURL::DoStartPrepare(const wxString& url) |
| 419 | 432 | break;
|
| 420 | 433 | }
|
| 421 | 434 | |
| 422 | - // Enable all supported authentication methods
|
|
| 423 | - wxCURLSetOpt(m_handle, CURLOPT_HTTPAUTH, CURLAUTH_ANY);
|
|
| 435 | + // Enable all supported authentication methods for proxy if we're using it,
|
|
| 436 | + // but wait until we know whether we're using basic authentication for HTTP
|
|
| 437 | + // in DoFinishPrepare() before enabling it for HTTP as well.
|
|
| 424 | 438 | if ( usingProxy )
|
| 425 | 439 | wxCURLSetOpt(m_handle, CURLOPT_PROXYAUTH, CURLAUTH_ANY);
|
| 426 | 440 | }
|
| ... | ... | @@ -440,6 +454,22 @@ wxWebRequestCURL::~wxWebRequestCURL() |
| 440 | 454 | |
| 441 | 455 | wxWebRequest::Result wxWebRequestCURL::DoFinishPrepare()
|
| 442 | 456 | {
|
| 457 | + // Force using basic authentication if necessary.
|
|
| 458 | + auto httpAuthMethod = CURLAUTH_ANY;
|
|
| 459 | + auto const& basicAuthCred = GetBasicAuthCredentials();
|
|
| 460 | + if ( basicAuthCred.IsOk() )
|
|
| 461 | + {
|
|
| 462 | + httpAuthMethod = CURLAUTH_BASIC;
|
|
| 463 | + |
|
| 464 | + wxCURLSetOpt(m_handle, CURLOPT_USERNAME,
|
|
| 465 | + basicAuthCred.GetUser());
|
|
| 466 | + wxCURLSetOpt(m_handle, CURLOPT_PASSWORD,
|
|
| 467 | + basicAuthCred.GetPassword().GetAsString());
|
|
| 468 | + }
|
|
| 469 | + |
|
| 470 | + wxCURLSetOpt(m_handle, CURLOPT_HTTPAUTH, httpAuthMethod);
|
|
| 471 | + |
|
| 472 | + |
|
| 443 | 473 | m_response.reset(new wxWebResponseCURL(*this));
|
| 444 | 474 | |
| 445 | 475 | const auto result = m_response->InitFileStorage();
|
| ... | ... | @@ -618,6 +648,34 @@ size_t wxWebRequestCURL::CURLOnRead(char* buffer, size_t size) |
| 618 | 648 | return 0;
|
| 619 | 649 | }
|
| 620 | 650 | |
| 651 | +int wxWebRequestCURL::CURLOnSeek(curl_off_t offset, int origin)
|
|
| 652 | +{
|
|
| 653 | + wxSeekMode mode = wxFromStart;
|
|
| 654 | + switch ( origin )
|
|
| 655 | + {
|
|
| 656 | + case SEEK_SET:
|
|
| 657 | + mode = wxFromStart;
|
|
| 658 | + break;
|
|
| 659 | + |
|
| 660 | + case SEEK_CUR:
|
|
| 661 | + mode = wxFromCurrent;
|
|
| 662 | + break;
|
|
| 663 | + |
|
| 664 | + case SEEK_END:
|
|
| 665 | + mode = wxFromEnd;
|
|
| 666 | + break;
|
|
| 667 | + |
|
| 668 | + default:
|
|
| 669 | + wxLogTrace(TRACE_CURL, "Seek function: unknown origin %d", origin);
|
|
| 670 | + return CURL_SEEKFUNC_CANTSEEK;
|
|
| 671 | + }
|
|
| 672 | + |
|
| 673 | + if ( m_dataStream->SeekI(offset, mode) == wxInvalidOffset )
|
|
| 674 | + return CURL_SEEKFUNC_CANTSEEK;
|
|
| 675 | + |
|
| 676 | + return CURL_SEEKFUNC_OK;
|
|
| 677 | +}
|
|
| 678 | + |
|
| 621 | 679 | wxFileOffset wxWebRequestCURL::GetBytesSent() const
|
| 622 | 680 | {
|
| 623 | 681 | return m_bytesSent;
|
| ... | ... | @@ -875,10 +933,6 @@ using SocketPollerBase = WinSock1SocketPoller; |
| 875 | 933 | |
| 876 | 934 | #else
|
| 877 | 935 | |
| 878 | -#if wxUSE_LOG_TRACE
|
|
| 879 | -constexpr const char* TRACE_CURL = "curl";
|
|
| 880 | -#endif
|
|
| 881 | - |
|
| 882 | 936 | // SocketPollerSourceHandler - a source handler used by the SocketPoller class.
|
| 883 | 937 | |
| 884 | 938 | class SourceSocketPoller;
|
| ... | ... | @@ -673,8 +673,11 @@ wxWebRequest::Result wxWebRequestWinHTTP::DoPrepareRequest() |
| 673 | 673 | return FailWithLastError("Parsing URL");
|
| 674 | 674 | }
|
| 675 | 675 | |
| 676 | - // If we have auth in the URL, remember them but we can't use them yet
|
|
| 677 | - // because we don't yet know which authentication scheme the server uses.
|
|
| 676 | + // If basic authentication was explicitly requested, send it in the
|
|
| 677 | + // "Authorization:" header to avoid an extra round-trip just to get 401
|
|
| 678 | + // response first.
|
|
| 679 | + AddBasicAuthHeaderIfNecessary();
|
|
| 680 | + |
|
| 678 | 681 | if ( urlComps.HasCredentials() )
|
| 679 | 682 | {
|
| 680 | 683 | m_credentialsFromURL = urlComps.GetCredentials();
|
| ... | ... | @@ -187,6 +187,9 @@ wxWebRequestURLSession::DoPrepare(void (^completionHandler)(NSData*, NSURLRespon |
| 187 | 187 | [NSURL URLWithString:wxCFStringRef(m_url).AsNSString()]];
|
| 188 | 188 | req.HTTPMethod = wxCFStringRef(method).AsNSString();
|
| 189 | 189 | |
| 190 | + // Provide basic authorization header if credentials were set
|
|
| 191 | + AddBasicAuthHeaderIfNecessary();
|
|
| 192 | + |
|
| 190 | 193 | // Set request headers
|
| 191 | 194 | for (wxWebRequestHeaderMap::const_iterator it = m_headers.begin(); it != m_headers.end(); ++it)
|
| 192 | 195 | {
|
| 1 | -Subproject commit 3c572cf139293e75754550e02e906bf88cfba68e |
|
| 1 | +Subproject commit a40df5ddc406a958721ee4fc6faf5058460bc97b |
| ... | ... | @@ -653,6 +653,22 @@ TEST_CASE_METHOD(RequestFixture, |
| 653 | 653 | }
|
| 654 | 654 | }
|
| 655 | 655 | |
| 656 | +TEST_CASE_METHOD(RequestFixture,
|
|
| 657 | + "WebRequest::Auth::Basic/Explicit", "[net][webrequest][auth]")
|
|
| 658 | +{
|
|
| 659 | + if ( !InitBaseURL() )
|
|
| 660 | + return;
|
|
| 661 | + |
|
| 662 | + Create("basic-auth/wxtest/wxwidgets");
|
|
| 663 | + |
|
| 664 | + request.UseBasicAuth(wxWebCredentials("wxtest", wxSecretValue("wxwidgets")));
|
|
| 665 | + |
|
| 666 | + Run();
|
|
| 667 | + |
|
| 668 | + CHECK_THAT( request.GetResponse().AsString().utf8_string(),
|
|
| 669 | + Catch::Contains(AUTHORIZED_SUBSTRING) );
|
|
| 670 | +}
|
|
| 671 | + |
|
| 656 | 672 | TEST_CASE_METHOD(RequestFixture,
|
| 657 | 673 | "WebRequest::Auth::Basic/Reserved", "[net][webrequest][auth]")
|
| 658 | 674 | {
|
| ... | ... | @@ -1064,6 +1080,30 @@ TEST_CASE_METHOD(SyncRequestFixture, |
| 1064 | 1080 | CHECK( response.GetStatus() == 200 );
|
| 1065 | 1081 | }
|
| 1066 | 1082 | |
| 1083 | +TEST_CASE_METHOD(SyncRequestFixture,
|
|
| 1084 | + "WebRequest::Sync::PostAfterRedirect", "[net][webrequest][sync]")
|
|
| 1085 | +{
|
|
| 1086 | + if ( !InitBaseURL() )
|
|
| 1087 | + return;
|
|
| 1088 | + |
|
| 1089 | + // We can't test this when using WinHTTP because we need to use either 307
|
|
| 1090 | + // or 308 redirect status code to preserve the POST method across the
|
|
| 1091 | + // redirect (all backends switch to GET for 301 and 302, although it would
|
|
| 1092 | + // be possible to configure this to preserve POST when using libcurl) and
|
|
| 1093 | + // WinHTTP doesn't handle them automatically.
|
|
| 1094 | + const auto& versionInfo = wxWebSession::GetDefault().GetLibraryVersionInfo();
|
|
| 1095 | + if ( versionInfo.GetName() == "WinHTTP" )
|
|
| 1096 | + {
|
|
| 1097 | + WARN("Skipping POST with redirect test with WinHTTP backend");
|
|
| 1098 | + return;
|
|
| 1099 | + }
|
|
| 1100 | + |
|
| 1101 | + Create("redirect-to?url=post&status_code=307");
|
|
| 1102 | + request.SetData("app=WebRequestRedirect&version=1", "application/x-www-form-urlencoded");
|
|
| 1103 | + REQUIRE( Execute() );
|
|
| 1104 | + CHECK( response.GetStatus() == 200 );
|
|
| 1105 | +}
|
|
| 1106 | + |
|
| 1067 | 1107 | TEST_CASE_METHOD(SyncRequestFixture,
|
| 1068 | 1108 | "WebRequest::Sync::Put", "[net][webrequest][sync]")
|
| 1069 | 1109 | {
|
| ... | ... | @@ -1121,6 +1161,32 @@ TEST_CASE_METHOD(SyncRequestFixture, |
| 1121 | 1161 | Catch::Contains(AUTHORIZED_SUBSTRING) );
|
| 1122 | 1162 | }
|
| 1123 | 1163 | |
| 1164 | + SECTION("Explicit basic auth")
|
|
| 1165 | + {
|
|
| 1166 | + Create("basic-auth/wxtest/wxwidgets");
|
|
| 1167 | + request.UseBasicAuth(wxWebCredentials("wxtest", wxSecretValue("wxwidgets")));
|
|
| 1168 | + |
|
| 1169 | + CHECK( Execute() );
|
|
| 1170 | + CHECK( response.GetStatus() == 200 );
|
|
| 1171 | + CHECK( state == wxWebRequest::State_Completed );
|
|
| 1172 | + |
|
| 1173 | + CHECK_THAT( response.AsString().utf8_string(),
|
|
| 1174 | + Catch::Contains(AUTHORIZED_SUBSTRING) );
|
|
| 1175 | + }
|
|
| 1176 | + |
|
| 1177 | + SECTION("Password after redirect")
|
|
| 1178 | + {
|
|
| 1179 | + Create("redirect-to?url=basic-auth/wxtest/wxwidgets");
|
|
| 1180 | + request.UseBasicAuth(wxWebCredentials("wxtest", wxSecretValue("wxwidgets")));
|
|
| 1181 | + |
|
| 1182 | + CHECK( Execute() );
|
|
| 1183 | + CHECK( response.GetStatus() == 200 );
|
|
| 1184 | + CHECK( state == wxWebRequest::State_Completed );
|
|
| 1185 | + |
|
| 1186 | + CHECK_THAT( response.AsString().utf8_string(),
|
|
| 1187 | + Catch::Contains(AUTHORIZED_SUBSTRING) );
|
|
| 1188 | + }
|
|
| 1189 | + |
|
| 1124 | 1190 | SECTION("Bad password")
|
| 1125 | 1191 | {
|
| 1126 | 1192 | CreateWithAuth("basic-auth/wxtest/wxwidgets", "wxtest", "foobar");
|
—
View it on GitLab.
You're receiving this email because of your account on gitlab.com. Manage all notifications · Help