我正在将 OAuth 身份验证分解为IHttpFilter以与HttpClient一起使用。我正在使用以下代码进行测试,期望它将所有请求简单地转发到HttpBaseProtocolFilter:
#include <winrt/Windows.Foundation.h>
#include <winrt/Windows.Web.Http.h>
#include <winrt/Windows.Web.Http.Filters.h>
using namespace winrt;
using namespace Windows::Foundation;
using namespace Windows::Web::Http;
using namespace Windows::Web::Http::Filters;
struct TestHttpFilter : implements<TestHttpFilter, IHttpFilter>
{
TestHttpFilter(IHttpFilter inner_filter) : inner_filter_{ inner_filter } {}
IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> SendRequestAsync(HttpRequestMessage const& request) const
{
auto const result{ co_await inner_filter_.SendRequestAsync(request) };
co_return result;
}
private:
IHttpFilter inner_filter_{ nullptr };
};
int main()
{
init_apartment();
IHttpFilter const base_filter{ HttpBaseProtocolFilter{} };
IHttpFilter const test_filter{ TestHttpFilter{ base_filter } };
HttpClient const http_client{ test_filter };
auto const result{ http_client.GetStringAsync({ L"http://aka.ms/cppwinrt" }).get() };
printf("Response: %ls!\n", result.c_str());
}
过滤器链已正确创建,并传递给HttpClient
c'tor。发出GetStringAsync
调用时,代码内部崩溃TestHttpFilter::SendRequestAsync
并出现以下错误:
Exception thrown at <address> in <app>.exe: 0xC0000005: Access violation reading location 0x0000000000000000.
put_abi
这看起来是在 SDK 头文件<Windows.Web.Http.Filters.h>内的调用中取消引用的 NULL 指针(为简洁起见,省略了命名空间):
template <typename D> IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> consume_Windows_Web_Http_Filters_IHttpFilter<D>::SendRequestAsync(HttpRequestMessage const& request) const
{
IAsyncOperationWithProgress<HttpResponseMessage, HttpProgress> operation{ nullptr };
check_hresult(WINRT_SHIM(IHttpFilter)->SendRequestAsync(get_abi(request), put_abi(operation)));
return operation;
}
我不明白,我哪里做错了。我希望通过回答以下问题来深入了解它的核心:
- 执行有什么问题
TestHttpFilter
吗? - HTTP过滤器可以与
HttpClient
(例如)的便捷实现一起使用,还是我们在使用过滤器时GetStringAsync
需要通过接口?SendRequestAsync
- 极不可能,但这可能是生成的 SDK 标头的问题,为本地
operation
对象选择了不合适的 c'tor?
我可以使用官方 Windows SDK 版本 10.0.17134.0 重现该问题。