Я нахожусь в процессе преобразования аутентификации OAuth в IHttpFilter для использования с HTTP-клиент. Я использую следующий код для тестирования, ожидая, что он просто перенаправит все запросы на 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› (пространства имен опущены для краткости):
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, выбирающих неподходящий c'tor для локального объекта
operation
?
Я могу воспроизвести проблему, используя официальную версию Windows SDK 10.0.17134.0.
make<>()
, а не часть фактического исправления. В конце концов, времени жизни объекта в примере кода достаточно. Я думаю, дело в том, чтоmake<>()
возвращает спроецированный тип из типа реализации, который используется типом WinRT (в данном случаеHttpClient
). Можете ли вы пояснить это для меня, если вы не найдете время, чтобы ответить самостоятельно, чтобы я мог завершить этот вопрос и ответ? - person IInspectable   schedule 24.05.2018CoreApplication::Run(App())
. С тем, что я узнал, я ожидал увидетьCoreApplication::Run(make<App>())
вместо этого. Во всяком случае, я составил ответ на этот вопрос в надежде, что он хотя бы приблизительно правильный. Тем не менее, обратная связь была бы очень признательна. - person IInspectable   schedule 25.05.2018