588d1eb404f7e69f089d31297b720a69d02aef9c
[WebKit-https.git] / Source / WebCore / inspector / NetworkResourcesData.cpp
1 /*
2  * Copyright (C) 2011 Google 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 are
6  * met:
7  *
8  * 1. Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
11  * 2. Redistributions in binary form must reproduce the above
12  * copyright notice, this list of conditions and the following disclaimer
13  * in the documentation and/or other materials provided with the
14  * distribution.
15  *
16  * THIS SOFTWARE IS PROVIDED BY GOOGLE INC. AND ITS CONTRIBUTORS
17  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
18  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
19  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL GOOGLE INC.
20  * OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
21  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
22  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
26  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 #include "config.h"
30 #include "NetworkResourcesData.h"
31
32 #if ENABLE(INSPECTOR)
33
34 namespace {
35 // 10MB
36 static int maximumResourcesContentSize = 10 * 1000 * 1000;
37 }
38
39 namespace WebCore {
40
41 // ResourceData
42 NetworkResourcesData::ResourceData::ResourceData(unsigned long identifier, const String& loaderId)
43     : m_identifier(identifier)
44     , m_loaderId(loaderId)
45     , m_hasContent(false)
46     , m_isContentPurged(false)
47     , m_type(InspectorPageAgent::OtherResource)
48 {
49 }
50
51 String NetworkResourcesData::ResourceData::content()
52 {
53     return m_hasContent ? m_contentBuilder.toString() : String();
54 }
55
56 void NetworkResourcesData::ResourceData::appendContent(const String& content)
57 {
58     m_contentBuilder.append(content);
59     m_hasContent = true;
60 }
61
62 unsigned NetworkResourcesData::ResourceData::purgeContent()
63 {
64     unsigned length = m_contentBuilder.toStringPreserveCapacity().length();
65     m_contentBuilder.clear();
66     m_isContentPurged = true;
67     m_hasContent = false;
68     return length;
69 }
70
71 // NetworkResourcesData
72 NetworkResourcesData::NetworkResourcesData()
73     : m_contentSize(0)
74 {
75 }
76
77 NetworkResourcesData::~NetworkResourcesData()
78 {
79     clear();
80 }
81
82 void NetworkResourcesData::resourceCreated(unsigned long identifier, const String& loaderId)
83 {
84     ensureNoDataForIdentifier(identifier);
85     m_identifierToResourceDataMap.set(identifier, new ResourceData(identifier, loaderId));
86 }
87
88 void NetworkResourcesData::responseReceived(unsigned long identifier, const String& frameId, const String& url)
89 {
90     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
91     if (!resourceData)
92         return;
93     resourceData->setFrameId(frameId);
94     resourceData->setUrl(url);
95 }
96
97 void NetworkResourcesData::setResourceType(unsigned long identifier, InspectorPageAgent::ResourceType type)
98 {
99     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
100     if (!resourceData)
101         return;
102     resourceData->setType(type);
103 }
104
105 InspectorPageAgent::ResourceType NetworkResourcesData::resourceType(unsigned long identifier)
106 {
107     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
108     if (!resourceData)
109         return InspectorPageAgent::OtherResource;
110     return resourceData->type();
111 }
112
113 void NetworkResourcesData::addResourceContent(unsigned long identifier, const String& content)
114 {
115     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
116     if (!resourceData)
117         return;
118     if (resourceData->isContentPurged())
119         return;
120     if (ensureFreeSpace(content.length()) && !resourceData->isContentPurged()) {
121         if (!resourceData->hasContent())
122             m_identifiersDeque.append(identifier);
123         resourceData->appendContent(content);
124         m_contentSize += content.length();
125     }
126 }
127
128 void NetworkResourcesData::addCachedResource(unsigned long identifier, CachedResource* cachedResource)
129 {
130     if (!m_identifierToResourceDataMap.contains(identifier))
131         return;
132     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
133
134     resourceData->setCachedResource(cachedResource);
135 }
136
137 void NetworkResourcesData::addResourceSharedBuffer(unsigned long identifier, PassRefPtr<SharedBuffer> buffer, const String& textEncodingName)
138 {
139     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
140     if (!resourceData)
141         return;
142     resourceData->setBuffer(buffer);
143     resourceData->setTextEncodingName(textEncodingName);
144 }
145
146 NetworkResourcesData::ResourceData* NetworkResourcesData::data(unsigned long identifier)
147 {
148     return m_identifierToResourceDataMap.get(identifier);
149 }
150
151 void NetworkResourcesData::clear(const String& preservedLoaderId)
152 {
153     m_identifiersDeque.clear();
154
155     ResourceDataMap preservedMap;
156
157     ResourceDataMap::iterator it;
158     ResourceDataMap::iterator end = m_identifierToResourceDataMap.end();
159     for (it = m_identifierToResourceDataMap.begin(); it != end; ++it) {
160         ResourceData* resourceData = it->second;
161         if (!preservedLoaderId.isNull() && resourceData->loaderId() == preservedLoaderId)
162             preservedMap.set(it->first, it->second);
163         else
164             delete resourceData;
165     }
166     m_identifierToResourceDataMap.swap(preservedMap);
167 }
168
169 void NetworkResourcesData::ensureNoDataForIdentifier(unsigned long identifier)
170 {
171     ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
172     if (resourceData) {
173         if (resourceData->hasContent())
174             m_contentSize -= resourceData->purgeContent();
175         delete resourceData;
176         m_identifierToResourceDataMap.remove(identifier);
177     }
178 }
179
180 bool NetworkResourcesData::ensureFreeSpace(int size)
181 {
182     if (size > maximumResourcesContentSize)
183         return false;
184
185     while (size > maximumResourcesContentSize - m_contentSize) {
186         unsigned long identifier = m_identifiersDeque.takeFirst();
187         ResourceData* resourceData = m_identifierToResourceDataMap.get(identifier);
188         if (resourceData)
189             m_contentSize -= resourceData->purgeContent();
190     }
191     return true;
192 }
193
194 } // namespace WebCore
195
196 #endif // ENABLE(INSPECTOR)