WebSchemeHandler.cpp 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182
  1. //
  2. // Copyright (c) 2014-2016, THUNDERBEAST GAMES LLC All rights reserved
  3. //
  4. // Permission is hereby granted, free of charge, to any person obtaining a copy
  5. // of this software and associated documentation files (the "Software"), to deal
  6. // in the Software without restriction, including without limitation the rights
  7. // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
  8. // copies of the Software, and to permit persons to whom the Software is
  9. // furnished to do so, subject to the following conditions:
  10. //
  11. // The above copyright notice and this permission notice shall be included in
  12. // all copies or substantial portions of the Software.
  13. //
  14. // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
  15. // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
  16. // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
  17. // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
  18. // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
  19. // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
  20. // THE SOFTWARE.
  21. //
  22. #include "include/cef_browser.h"
  23. #include "include/cef_callback.h"
  24. #include "include/cef_frame.h"
  25. #include "include/cef_resource_handler.h"
  26. #include "include/cef_response.h"
  27. #include "include/cef_request.h"
  28. #include "include/cef_scheme.h"
  29. #include "include/wrapper/cef_helpers.h"
  30. #include <Atomic/Math/MathDefs.h>
  31. #include <Atomic/Resource/ResourceCache.h>
  32. #include <Atomic/IO/FileSystem.h>
  33. #include "WebString.h"
  34. #include "WebBrowserHost.h"
  35. #include "WebSchemeHandler.h"
  36. namespace Atomic
  37. {
  38. static WeakPtr<WebBrowserHost> webBrowserHost_;
  39. // Implementation of the schema handler for atomic://resources/ requests.
  40. class ResourceSchemeHandler : public CefResourceHandler
  41. {
  42. public:
  43. ResourceSchemeHandler() : fileLength_(0), offset_(0)
  44. {
  45. }
  46. virtual bool ProcessRequest(CefRefPtr<CefRequest> request,
  47. CefRefPtr<CefCallback> callback) OVERRIDE
  48. {
  49. CEF_REQUIRE_IO_THREAD();
  50. if (webBrowserHost_.Null())
  51. return false;
  52. ConvertCEFString(request->GetURL(), url_);
  53. //shave off the atomic:// part
  54. url_ = url_.SubstringUTF8(9);
  55. if (IsAbsolutePath(url_))
  56. {
  57. file_ = new File(webBrowserHost_->GetContext(), url_, FILE_READ);
  58. }
  59. else
  60. {
  61. //shave off the resources part so we can grab the value from the resource cache
  62. url_ = url_.SubstringUTF8(10);
  63. ResourceCache* cache = webBrowserHost_->GetSubsystem<ResourceCache>();
  64. file_ = cache->GetFile(url_, false);
  65. }
  66. if (!file_->IsOpen())
  67. return false;
  68. fileLength_ = file_->GetSize();
  69. // Indicate the headers are available.
  70. callback->Continue();
  71. return true;
  72. }
  73. virtual void GetResponseHeaders(CefRefPtr<CefResponse> response,
  74. int64& response_length,
  75. CefString& redirectUrl) OVERRIDE
  76. {
  77. CEF_REQUIRE_IO_THREAD();
  78. String pathName, fileName, ext;
  79. SplitPath(url_, pathName, fileName, ext);
  80. if (ext == ".js")
  81. response->SetMimeType("text/javascript");
  82. else if (ext == ".ts")
  83. response->SetMimeType("text/typescript");
  84. response->SetStatus(200);
  85. // Set the resulting response length
  86. response_length = fileLength_;
  87. }
  88. virtual void Cancel() OVERRIDE
  89. {
  90. CEF_REQUIRE_IO_THREAD();
  91. }
  92. virtual bool ReadResponse(void* data_out,
  93. int bytes_to_read,
  94. int& bytes_read,
  95. CefRefPtr<CefCallback> callback) OVERRIDE
  96. {
  97. bool has_data = false;
  98. bytes_read = 0;
  99. if (offset_ < fileLength_)
  100. {
  101. // Copy the next block of data into the buffer.
  102. int transfer_size = Min(bytes_to_read, static_cast<int>(fileLength_ - offset_));
  103. file_->Read(data_out, transfer_size);
  104. offset_ += transfer_size;
  105. bytes_read = transfer_size;
  106. has_data = true;
  107. if (offset_ >= fileLength_)
  108. file_->Close();
  109. }
  110. return has_data;
  111. }
  112. private:
  113. SharedPtr<File> file_;
  114. unsigned fileLength_;
  115. String url_;
  116. unsigned offset_;
  117. IMPLEMENT_REFCOUNTING(ResourceSchemeHandler);
  118. };
  119. // Implementation of the factory for for creating schema handlers.
  120. class ResourceSchemeHandlerFactory : public CefSchemeHandlerFactory
  121. {
  122. public:
  123. // Return a new scheme handler instance to handle the request.
  124. virtual CefRefPtr<CefResourceHandler> Create(CefRefPtr<CefBrowser> browser,
  125. CefRefPtr<CefFrame> frame,
  126. const CefString& scheme_name,
  127. CefRefPtr<CefRequest> request) OVERRIDE
  128. {
  129. CEF_REQUIRE_IO_THREAD();
  130. return new ResourceSchemeHandler();
  131. }
  132. IMPLEMENT_REFCOUNTING(ResourceSchemeHandlerFactory);
  133. };
  134. void RegisterWebSchemeHandlers(WebBrowserHost* host)
  135. {
  136. webBrowserHost_ = host;
  137. CefRegisterSchemeHandlerFactory("atomic", "resources",
  138. new ResourceSchemeHandlerFactory());
  139. }
  140. }