浏览代码

LibWeb: Follow HTTP 3xx redirections when loading images

This basically copies some logic from FrameLoader to ImageLoader.
Ideally we'd share this code, but for now let's just get redirected
images to show up. :^)
Andreas Kling 3 年之前
父节点
当前提交
0e2cd5540a
共有 2 个文件被更改,包括 28 次插入0 次删除
  1. 25 0
      Userland/Libraries/LibWeb/Loader/ImageLoader.cpp
  2. 3 0
      Userland/Libraries/LibWeb/Loader/ImageLoader.h

+ 25 - 0
Userland/Libraries/LibWeb/Loader/ImageLoader.cpp

@@ -21,6 +21,12 @@ ImageLoader::ImageLoader(DOM::Element& owner_element)
 }
 
 void ImageLoader::load(const AK::URL& url)
+{
+    m_redirects_count = 0;
+    load_without_resetting_redirect_counter(url);
+}
+
+void ImageLoader::load_without_resetting_redirect_counter(AK::URL const& url)
 {
     m_loading_state = LoadingState::Loading;
 
@@ -45,6 +51,25 @@ void ImageLoader::resource_did_load()
 {
     VERIFY(resource());
 
+    // For 3xx (Redirection) responses, the Location value refers to the preferred target resource for automatically redirecting the request.
+    auto status_code = resource()->status_code();
+    if (status_code.has_value() && *status_code >= 300 && *status_code <= 399) {
+        auto location = resource()->response_headers().get("Location");
+        if (location.has_value()) {
+            if (m_redirects_count > maximum_redirects_allowed) {
+                m_redirects_count = 0;
+                m_loading_state = LoadingState::Failed;
+                if (on_fail)
+                    on_fail();
+                return;
+            }
+            m_redirects_count++;
+            load_without_resetting_redirect_counter(resource()->url().complete_url(location.value()));
+            return;
+        }
+    }
+    m_redirects_count = 0;
+
     if (!resource()->mime_type().starts_with("image/")) {
         m_loading_state = LoadingState::Failed;
         if (on_fail)

+ 3 - 0
Userland/Libraries/LibWeb/Loader/ImageLoader.h

@@ -35,6 +35,8 @@ public:
     Function<void()> on_animate;
 
 private:
+    void load_without_resetting_redirect_counter(AK::URL const&);
+
     // ^ImageResourceClient
     virtual void resource_did_load() override;
     virtual void resource_did_fail() override;
@@ -57,6 +59,7 @@ private:
     size_t m_loops_completed { 0 };
     LoadingState m_loading_state { LoadingState::Loading };
     NonnullRefPtr<Core::Timer> m_timer;
+    size_t m_redirects_count { 0 };
 };
 
 }