logo

WebKitGTK

Collection of patches on top of WebKitGTK

ApplicationCacheResourceLoader.cpp (5149B)


  1. /*
  2. * Copyright (C) 2018 Apple Inc. All Rights Reserved.
  3. *
  4. * Redistribution and use in source and binary forms, with or without
  5. * modification, are permitted provided that the following conditions
  6. * are met:
  7. * 1. Redistributions of source code must retain the above copyright
  8. * notice, this list of conditions and the following disclaimer.
  9. * 2. Redistributions in binary form must reproduce the above copyright
  10. * notice, this list of conditions and the following disclaimer in the
  11. * documentation and/or other materials provided with the distribution.
  12. *
  13. * THIS SOFTWARE IS PROVIDED BY APPLE INC. ``AS IS'' AND ANY
  14. * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  15. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
  16. * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR
  17. * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
  18. * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
  19. * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
  20. * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
  21. * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  22. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  23. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  24. */
  25. #include "config.h"
  26. #include "ApplicationCacheResourceLoader.h"
  27. #include "CachedResourceLoader.h"
  28. namespace WebCore {
  29. RefPtr<ApplicationCacheResourceLoader> ApplicationCacheResourceLoader::create(unsigned type, CachedResourceLoader& loader, ResourceRequest&& request, CompletionHandler<void(ResourceOrError&&)>&& callback)
  30. {
  31. ResourceLoaderOptions options;
  32. options.storedCredentialsPolicy = StoredCredentialsPolicy::Use;
  33. options.credentials = FetchOptions::Credentials::Include;
  34. options.applicationCacheMode = ApplicationCacheMode::Bypass;
  35. options.certificateInfoPolicy = CertificateInfoPolicy::IncludeCertificateInfo;
  36. CachedResourceRequest cachedResourceRequest { WTFMove(request), options };
  37. auto resource = loader.requestRawResource(WTFMove(cachedResourceRequest));
  38. if (!resource.has_value()) {
  39. callback(makeUnexpected(Error::CannotCreateResource));
  40. return nullptr;
  41. }
  42. return adoptRef(*new ApplicationCacheResourceLoader { type, WTFMove(resource.value()), WTFMove(callback) });
  43. }
  44. ApplicationCacheResourceLoader::ApplicationCacheResourceLoader(unsigned type, CachedResourceHandle<CachedRawResource>&& resource, CompletionHandler<void(ResourceOrError&&)>&& callback)
  45. : m_type(type)
  46. , m_resource(WTFMove(resource))
  47. , m_callback(WTFMove(callback))
  48. {
  49. m_resource->addClient(*this);
  50. }
  51. ApplicationCacheResourceLoader::~ApplicationCacheResourceLoader()
  52. {
  53. if (auto callback = WTFMove(m_callback))
  54. callback(makeUnexpected(Error::Abort));
  55. if (m_resource)
  56. m_resource->removeClient(*this);
  57. }
  58. void ApplicationCacheResourceLoader::cancel(Error error)
  59. {
  60. auto protectedThis = makeRef(*this);
  61. if (auto callback = WTFMove(m_callback))
  62. callback(makeUnexpected(error));
  63. if (m_resource) {
  64. m_resource->removeClient(*this);
  65. m_resource = nullptr;
  66. }
  67. }
  68. void ApplicationCacheResourceLoader::responseReceived(CachedResource& resource, const ResourceResponse& response, CompletionHandler<void()>&& completionHandler)
  69. {
  70. ASSERT_UNUSED(resource, &resource == m_resource);
  71. CompletionHandlerCallingScope completionHandlerCaller(WTFMove(completionHandler));
  72. if (response.httpStatusCode() == 404 || response.httpStatusCode() == 410) {
  73. cancel(Error::NotFound);
  74. return;
  75. }
  76. if (response.httpStatusCode() / 100 != 2) {
  77. cancel(Error::NotOK);
  78. return;
  79. }
  80. m_applicationCacheResource = ApplicationCacheResource::create(m_resource->url(), response, m_type);
  81. }
  82. void ApplicationCacheResourceLoader::dataReceived(CachedResource&, const char* data, int length)
  83. {
  84. m_applicationCacheResource->data().append(data, length);
  85. }
  86. void ApplicationCacheResourceLoader::redirectReceived(CachedResource&, ResourceRequest&& newRequest, const ResourceResponse&, CompletionHandler<void(ResourceRequest&&)>&& callback)
  87. {
  88. m_hasRedirection = true;
  89. bool isRedirectionDisallowed = (m_type & ApplicationCacheResource::Type::Manifest) || (m_type & ApplicationCacheResource::Explicit) || (m_type & ApplicationCacheResource::Fallback);
  90. if (isRedirectionDisallowed) {
  91. cancel(Error::RedirectForbidden);
  92. callback({ });
  93. return;
  94. }
  95. callback(WTFMove(newRequest));
  96. }
  97. void ApplicationCacheResourceLoader::notifyFinished(CachedResource& resource)
  98. {
  99. auto protectedThis = makeRef(*this);
  100. ASSERT_UNUSED(resource, &resource == m_resource);
  101. if (m_resource->errorOccurred()) {
  102. cancel(Error::NetworkError);
  103. return;
  104. }
  105. if (auto callback = WTFMove(m_callback))
  106. callback(WTFMove(m_applicationCacheResource));
  107. CachedResourceHandle<CachedRawResource> resourceHandle;
  108. std::swap(resourceHandle, m_resource);
  109. if (resourceHandle)
  110. resourceHandle->removeClient(*this);
  111. }
  112. } // namespace WebCore