CEFInterfaceSchemeHandler.cpp 6.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207
  1. // Engine/Source/Runtime/WebBrowser/Private/CEF/CEFSchemeHandler.cpp
  2. #include "CEF/CEFInterfaceSchemeHandler.h"
  3. #include "Misc/FileHelper.h"
  4. #include "Misc/Paths.h"
  5. #include "IWebInterfaceBrowserSchemeHandler.h"
  6. #if WITH_CEF3
  7. class FHandlerHeaderSetter
  8. : public IWebInterfaceBrowserSchemeHandler::IHeaders
  9. {
  10. public:
  11. FHandlerHeaderSetter(CefRefPtr<CefResponse>& InResponse, int64& InContentLength, CefString& InRedirectUrl)
  12. : Response(InResponse)
  13. , ContentLength(InContentLength)
  14. , RedirectUrl(InRedirectUrl)
  15. , StatusCode(INDEX_NONE)
  16. {
  17. }
  18. virtual ~FHandlerHeaderSetter()
  19. {
  20. if (Headers.size() > 0)
  21. {
  22. Response->SetHeaderMap(Headers);
  23. }
  24. if (StatusCode != INDEX_NONE)
  25. {
  26. Response->SetStatus(StatusCode);
  27. }
  28. if (MimeType.length() > 0)
  29. {
  30. Response->SetMimeType(MimeType);
  31. }
  32. }
  33. virtual void SetMimeType(const TCHAR* InMimeType) override
  34. {
  35. MimeType = TCHAR_TO_WCHAR(InMimeType);
  36. }
  37. virtual void SetStatusCode(int32 InStatusCode) override
  38. {
  39. StatusCode = InStatusCode;
  40. }
  41. virtual void SetContentLength(int32 InContentLength) override
  42. {
  43. ContentLength = InContentLength;
  44. }
  45. virtual void SetRedirect(const TCHAR* InRedirectUrl) override
  46. {
  47. RedirectUrl = TCHAR_TO_WCHAR(InRedirectUrl);
  48. }
  49. virtual void SetHeader(const TCHAR* Key, const TCHAR* Value) override
  50. {
  51. Headers.insert(std::make_pair(CefString(TCHAR_TO_WCHAR(Key)), CefString(TCHAR_TO_WCHAR(Value))));
  52. }
  53. private:
  54. CefRefPtr<CefResponse>& Response;
  55. int64& ContentLength;
  56. CefString& RedirectUrl;
  57. CefResponse::HeaderMap Headers;
  58. CefString MimeType;
  59. int32 StatusCode;
  60. };
  61. class FCefInterfaceSchemeHandler
  62. : public CefResourceHandler
  63. {
  64. public:
  65. FCefInterfaceSchemeHandler(TUniquePtr<IWebInterfaceBrowserSchemeHandler>&& InHandlerImplementation)
  66. : HandlerImplementation(MoveTemp(InHandlerImplementation))
  67. {
  68. }
  69. virtual ~FCefInterfaceSchemeHandler()
  70. {
  71. }
  72. // Begin CefResourceHandler interface.
  73. virtual bool ProcessRequest(CefRefPtr<CefRequest> Request, CefRefPtr<CefCallback> Callback) override
  74. {
  75. if (HandlerImplementation.IsValid())
  76. {
  77. return HandlerImplementation->ProcessRequest(
  78. WCHAR_TO_TCHAR(Request->GetMethod().ToWString().c_str()),
  79. WCHAR_TO_TCHAR(Request->GetURL().ToWString().c_str()),
  80. FSimpleDelegate::CreateLambda([Callback](){ Callback->Continue(); })
  81. );
  82. }
  83. return false;
  84. }
  85. virtual void GetResponseHeaders(CefRefPtr<CefResponse> Response, int64& ResponseLength, CefString& RedirectUrl) override
  86. {
  87. if (ensure(HandlerImplementation.IsValid()))
  88. {
  89. FHandlerHeaderSetter Headers(Response, ResponseLength, RedirectUrl);
  90. HandlerImplementation->GetResponseHeaders(Headers);
  91. }
  92. }
  93. virtual bool ReadResponse(void* DataOut, int BytesToRead, int& BytesRead, CefRefPtr<CefCallback> Callback) override
  94. {
  95. if (ensure(HandlerImplementation.IsValid()))
  96. {
  97. return HandlerImplementation->ReadResponse(
  98. (uint8*)DataOut,
  99. BytesToRead,
  100. BytesRead,
  101. FSimpleDelegate::CreateLambda([Callback](){ Callback->Continue(); })
  102. );
  103. }
  104. BytesRead = 0;
  105. return false;
  106. }
  107. virtual void Cancel() override
  108. {
  109. if (HandlerImplementation.IsValid())
  110. {
  111. HandlerImplementation->Cancel();
  112. }
  113. }
  114. // End CefResourceHandler interface.
  115. private:
  116. TUniquePtr<IWebInterfaceBrowserSchemeHandler> HandlerImplementation;
  117. // Include CEF ref counting.
  118. IMPLEMENT_REFCOUNTING(FCefInterfaceSchemeHandler);
  119. };
  120. class FCefInterfaceSchemeHandlerFactory
  121. : public CefSchemeHandlerFactory
  122. {
  123. public:
  124. FCefInterfaceSchemeHandlerFactory(IWebInterfaceBrowserSchemeHandlerFactory* InWebBrowserSchemeHandlerFactory)
  125. : WebBrowserSchemeHandlerFactory(InWebBrowserSchemeHandlerFactory)
  126. {
  127. }
  128. // Begin CefSchemeHandlerFactory interface.
  129. virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> Browser, CefRefPtr<CefFrame> Frame, const CefString& Scheme, CefRefPtr<CefRequest> Request) override
  130. {
  131. return new FCefInterfaceSchemeHandler(WebBrowserSchemeHandlerFactory->Create(
  132. WCHAR_TO_TCHAR(Request->GetMethod().ToWString().c_str()),
  133. WCHAR_TO_TCHAR(Request->GetURL().ToWString().c_str())));
  134. }
  135. // End CefSchemeHandlerFactory interface.
  136. bool IsUsing(IWebInterfaceBrowserSchemeHandlerFactory* InWebBrowserSchemeHandlerFactory)
  137. {
  138. return WebBrowserSchemeHandlerFactory == InWebBrowserSchemeHandlerFactory;
  139. }
  140. private:
  141. IWebInterfaceBrowserSchemeHandlerFactory* WebBrowserSchemeHandlerFactory;
  142. // Include CEF ref counting.
  143. IMPLEMENT_REFCOUNTING(FCefInterfaceSchemeHandlerFactory);
  144. };
  145. void FCefInterfaceSchemeHandlerFactories::AddSchemeHandlerFactory(FString Scheme, FString Domain, IWebInterfaceBrowserSchemeHandlerFactory* WebBrowserSchemeHandlerFactory)
  146. {
  147. checkf(WebBrowserSchemeHandlerFactory != nullptr, TEXT("WebBrowserSchemeHandlerFactory must be provided."));
  148. CefRefPtr<CefSchemeHandlerFactory> Factory = new FCefInterfaceSchemeHandlerFactory(WebBrowserSchemeHandlerFactory);
  149. CefRegisterSchemeHandlerFactory(TCHAR_TO_WCHAR(*Scheme), TCHAR_TO_WCHAR(*Domain), Factory);
  150. SchemeHandlerFactories.Emplace(MoveTemp(Scheme), MoveTemp(Domain), MoveTemp(Factory));
  151. }
  152. void FCefInterfaceSchemeHandlerFactories::RemoveSchemeHandlerFactory(IWebInterfaceBrowserSchemeHandlerFactory* WebBrowserSchemeHandlerFactory)
  153. {
  154. checkf(WebBrowserSchemeHandlerFactory != nullptr, TEXT("WebBrowserSchemeHandlerFactory must be provided."));
  155. SchemeHandlerFactories.RemoveAll([WebBrowserSchemeHandlerFactory](const FFactory& Element)
  156. {
  157. return ((FCefInterfaceSchemeHandlerFactory*)Element.Factory.get())->IsUsing(WebBrowserSchemeHandlerFactory);
  158. });
  159. }
  160. void FCefInterfaceSchemeHandlerFactories::RegisterFactoriesWith(CefRefPtr<CefRequestContext>& Context)
  161. {
  162. if (Context)
  163. {
  164. for (const FFactory& SchemeHandlerFactory : SchemeHandlerFactories)
  165. {
  166. Context->RegisterSchemeHandlerFactory(TCHAR_TO_WCHAR(*SchemeHandlerFactory.Scheme), TCHAR_TO_WCHAR(*SchemeHandlerFactory.Domain), SchemeHandlerFactory.Factory);
  167. }
  168. }
  169. }
  170. FCefInterfaceSchemeHandlerFactories::FFactory::FFactory(FString InScheme, FString InDomain, CefRefPtr<CefSchemeHandlerFactory> InFactory)
  171. : Scheme(MoveTemp(InScheme))
  172. , Domain(MoveTemp(InDomain))
  173. , Factory(MoveTemp(InFactory))
  174. {
  175. }
  176. #endif