1/*
2 * Copyright (C) 2017 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. AND ITS CONTRIBUTORS ``AS IS''
14 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
15 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
16 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
17 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
18 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
19 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
20 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
21 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
22 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
23 * THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "config.h"
27#include "WebURLSchemeHandler.h"
28
29#include "WebPageProxy.h"
30#include "WebURLSchemeTask.h"
31
32namespace WebKit {
33using namespace WebCore;
34
35static uint64_t generateWebURLSchemeHandlerIdentifier()
36{
37 static uint64_t nextIdentifier = 1;
38 return nextIdentifier++;
39}
40
41WebURLSchemeHandler::WebURLSchemeHandler()
42 : m_identifier(generateWebURLSchemeHandlerIdentifier())
43{
44}
45
46WebURLSchemeHandler::~WebURLSchemeHandler()
47{
48 ASSERT(m_tasks.isEmpty());
49}
50
51void WebURLSchemeHandler::startTask(WebPageProxy& page, WebProcessProxy& process, uint64_t taskIdentifier, ResourceRequest&& request, SyncLoadCompletionHandler&& completionHandler)
52{
53 auto result = m_tasks.add(taskIdentifier, WebURLSchemeTask::create(*this, page, process, taskIdentifier, WTFMove(request), WTFMove(completionHandler)));
54 ASSERT(result.isNewEntry);
55
56 auto pageEntry = m_tasksByPageIdentifier.add(page.pageID(), HashSet<uint64_t>());
57 ASSERT(!pageEntry.iterator->value.contains(taskIdentifier));
58 pageEntry.iterator->value.add(taskIdentifier);
59
60 platformStartTask(page, result.iterator->value);
61}
62
63WebProcessProxy* WebURLSchemeHandler::processForTaskIdentifier(uint64_t taskIdentifier) const
64{
65 auto iterator = m_tasks.find(taskIdentifier);
66 if (iterator == m_tasks.end())
67 return nullptr;
68 return iterator->value->process();
69}
70
71void WebURLSchemeHandler::stopAllTasksForPage(WebPageProxy& page, WebProcessProxy* process)
72{
73 auto iterator = m_tasksByPageIdentifier.find(page.pageID());
74 if (iterator == m_tasksByPageIdentifier.end())
75 return;
76
77 auto& tasksByPage = iterator->value;
78 Vector<uint64_t> taskIdentifiersToStop;
79 taskIdentifiersToStop.reserveInitialCapacity(tasksByPage.size());
80 for (auto taskIdentifier : tasksByPage) {
81 if (!process || processForTaskIdentifier(taskIdentifier) == process)
82 taskIdentifiersToStop.uncheckedAppend(taskIdentifier);
83 }
84
85 for (auto& taskIdentifier : taskIdentifiersToStop)
86 stopTask(page, taskIdentifier);
87
88}
89
90void WebURLSchemeHandler::stopTask(WebPageProxy& page, uint64_t taskIdentifier)
91{
92 auto iterator = m_tasks.find(taskIdentifier);
93 if (iterator == m_tasks.end())
94 return;
95
96 iterator->value->stop();
97 platformStopTask(page, iterator->value);
98
99 removeTaskFromPageMap(page.pageID(), taskIdentifier);
100 m_tasks.remove(iterator);
101}
102
103void WebURLSchemeHandler::taskCompleted(WebURLSchemeTask& task)
104{
105 auto takenTask = m_tasks.take(task.identifier());
106 ASSERT_UNUSED(takenTask, takenTask->ptr() == &task);
107 removeTaskFromPageMap(task.pageID(), task.identifier());
108
109 platformTaskCompleted(task);
110}
111
112void WebURLSchemeHandler::removeTaskFromPageMap(PageIdentifier pageID, uint64_t taskID)
113{
114 auto iterator = m_tasksByPageIdentifier.find(pageID);
115 ASSERT(iterator != m_tasksByPageIdentifier.end());
116 ASSERT(iterator->value.contains(taskID));
117 iterator->value.remove(taskID);
118 if (iterator->value.isEmpty())
119 m_tasksByPageIdentifier.remove(iterator);
120}
121
122} // namespace WebKit
123