From 1cd1997deef3b88afc06a0981285149e41ac689c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Julio=20C=C3=A9sar=20Rocha?= Date: Wed, 21 Dec 2022 14:34:04 -0800 Subject: [PATCH 1/3] Test Access-Control-Request-Headers (#11031) * Add test ValidatePreflightResponseMainAndContentHeadersSucceeds * Allow resetting static origin --- ...-02bc19fb-606a-49b9-b555-145c15e79849.json | 7 +++ .../OriginPolicyHttpFilterTest.cpp | 52 +++++++++++++++++++ .../Networking/OriginPolicyHttpFilter.cpp | 2 + 3 files changed, 61 insertions(+) create mode 100644 change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json diff --git a/change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json b/change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json new file mode 100644 index 00000000000..13cb99c9391 --- /dev/null +++ b/change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json @@ -0,0 +1,7 @@ +{ + "type": "prerelease", + "comment": "Test Access-Control-Request-Headers", + "packageName": "react-native-windows", + "email": "julio.rocha@microsoft.com", + "dependentChangeType": "patch" +} diff --git a/vnext/Desktop.UnitTests/OriginPolicyHttpFilterTest.cpp b/vnext/Desktop.UnitTests/OriginPolicyHttpFilterTest.cpp index a31afb0ff05..7bf22675485 100644 --- a/vnext/Desktop.UnitTests/OriginPolicyHttpFilterTest.cpp +++ b/vnext/Desktop.UnitTests/OriginPolicyHttpFilterTest.cpp @@ -4,19 +4,28 @@ #include #include +#include +#include "WinRTNetworkingMocks.h" // Windows API #include #include using namespace Microsoft::VisualStudio::CppUnitTestFramework; +using namespace winrt::Windows::Web::Http; using Microsoft::React::Networking::OriginPolicyHttpFilter; +using Microsoft::React::Networking::RequestArgs; +using Microsoft::React::Networking::ResponseOperation; using winrt::Windows::Foundation::Uri; namespace Microsoft::React::Test { TEST_CLASS (OriginPolicyHttpFilterTest) { + TEST_CLASS_INITIALIZE(Initialize) { + winrt::uninit_apartment(); + } + // TEMP tests to see if Uri has comparison capabilities TEST_METHOD(UrlsHaveSameOrigin) { // clang-format off @@ -242,6 +251,49 @@ TEST_CLASS (OriginPolicyHttpFilterTest) { Assert::AreEqual(2, static_cast(response.Headers().Size())); } } + + TEST_METHOD(ValidatePreflightResponseMainAndContentHeadersSucceeds) { + auto mockFilter = winrt::make(); + mockFilter.as()->Mocks.SendRequestAsync = + [](HttpRequestMessage const &request) -> ResponseOperation { + HttpResponseMessage response{}; + + response.StatusCode(HttpStatusCode::Ok); + response.Headers().Insert(L"Access-Control-Allow-Origin", L"*"); + // Return allowed headers as requested by client + response.Headers().Insert( + L"Access-Control-Allow-Headers", request.Headers().Lookup(L"Access-Control-Request-Headers")); + + co_return response; + }; + + auto reqArgs = winrt::make(); + auto request = HttpRequestMessage(HttpMethod::Get(), Uri{L"http://somehost"}); + request.Properties().Insert(L"RequestArgs", reqArgs); + request.Headers().TryAppendWithoutValidation(L"Authorization", L"Bearer abc"); + // Should implicitly set Conent-Length and Content-Type + request.Content(HttpStringContent{L"PreflightContent"}); + + auto filter = winrt::make(mockFilter); + auto opFilter = filter.as(); + + OriginPolicyHttpFilter::SetStaticOrigin("http://somehost"); + try { + auto sendOp = opFilter->SendPreflightAsync(request); + sendOp.get(); + + auto response = sendOp.GetResults(); + opFilter->ValidatePreflightResponse(request, response); + + OriginPolicyHttpFilter::SetStaticOrigin({}); + Assert::AreEqual( + L"Authorization, Content-Length, Content-Type", + response.Headers().Lookup(L"Access-Control-Allow-Headers").c_str()); + } catch (const winrt::hresult_error &e) { + OriginPolicyHttpFilter::SetStaticOrigin({}); + Assert::Fail(e.message().c_str()); + } + } }; } // namespace Microsoft::React::Test diff --git a/vnext/Shared/Networking/OriginPolicyHttpFilter.cpp b/vnext/Shared/Networking/OriginPolicyHttpFilter.cpp index cd01c56d7dd..d57845cdbd0 100644 --- a/vnext/Shared/Networking/OriginPolicyHttpFilter.cpp +++ b/vnext/Shared/Networking/OriginPolicyHttpFilter.cpp @@ -113,6 +113,8 @@ bool OriginPolicyHttpFilter::ConstWcharComparer::operator()(const wchar_t *a, co /*static*/ void OriginPolicyHttpFilter::SetStaticOrigin(std::string &&url) { if (!url.empty()) s_origin = Uri{to_hstring(url)}; + else + s_origin = nullptr; } /*static*/ bool OriginPolicyHttpFilter::IsSameOrigin(Uri const &u1, Uri const &u2) noexcept { From 8671c30b2c4b835a4bc091060ad3266f3884dfe6 Mon Sep 17 00:00:00 2001 From: "Julio C. Rocha" Date: Wed, 21 Dec 2022 15:05:59 -0800 Subject: [PATCH 2/3] Remove change file --- ...ative-windows-02bc19fb-606a-49b9-b555-145c15e79849.json | 7 ------- 1 file changed, 7 deletions(-) delete mode 100644 change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json diff --git a/change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json b/change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json deleted file mode 100644 index 13cb99c9391..00000000000 --- a/change/react-native-windows-02bc19fb-606a-49b9-b555-145c15e79849.json +++ /dev/null @@ -1,7 +0,0 @@ -{ - "type": "prerelease", - "comment": "Test Access-Control-Request-Headers", - "packageName": "react-native-windows", - "email": "julio.rocha@microsoft.com", - "dependentChangeType": "patch" -} From b78f974a9485ac509b011b5eb0bc708a1bb066d1 Mon Sep 17 00:00:00 2001 From: "Julio C. Rocha" Date: Wed, 21 Dec 2022 15:16:20 -0800 Subject: [PATCH 3/3] Change files --- ...ative-windows-2b1076e7-13bc-47c6-b7f0-c00f1e0bb5e4.json | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 change/react-native-windows-2b1076e7-13bc-47c6-b7f0-c00f1e0bb5e4.json diff --git a/change/react-native-windows-2b1076e7-13bc-47c6-b7f0-c00f1e0bb5e4.json b/change/react-native-windows-2b1076e7-13bc-47c6-b7f0-c00f1e0bb5e4.json new file mode 100644 index 00000000000..2ae30838018 --- /dev/null +++ b/change/react-native-windows-2b1076e7-13bc-47c6-b7f0-c00f1e0bb5e4.json @@ -0,0 +1,7 @@ +{ + "type": "patch", + "comment": "Test Access-Control-Request-Headers (#11031)", + "packageName": "react-native-windows", + "email": "jurocha@microsoft.com", + "dependentChangeType": "patch" +}