1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /* ***** BEGIN LICENSE BLOCK *****
3 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
5 * The contents of this file are subject to the Mozilla Public License Version
6 * 1.1 (the "License"); you may not use this file except in compliance with
7 * the License. You may obtain a copy of the License at
8 * http://www.mozilla.org/MPL/
10 * Software distributed under the License is distributed on an "AS IS" basis,
11 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 * for the specific language governing rights and limitations under the
15 * The Original Code is mozilla.org code.
17 * The Initial Developer of the Original Code is
18 * Netscape Communications Corporation.
19 * Portions created by the Initial Developer are Copyright (C) 1998
20 * the Initial Developer. All Rights Reserved.
23 * Alexey Chernyak <alexeyc@bigfoot.com> (XHTML 1.1 conversion)
24 * Henrik Gemal <mozilla@gemal.dk>
25 * Darin Fisher <darin@netscape.com>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either the GNU General Public License Version 2 or later (the "GPL"), or
29 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
41 #include "nsAboutCache.h"
42 #include "nsIIOService.h"
43 #include "nsIServiceManager.h"
44 #include "nsIInputStream.h"
45 #include "nsIStorageStream.h"
46 #include "nsISimpleEnumerator.h"
47 #include "nsXPIDLString.h"
50 #include "nsNetUtil.h"
54 #include "nsICacheService.h"
56 static PRTime
SecondsToPRTime(PRUint32 t_sec
)
58 PRTime t_usec
, usec_per_sec
;
59 LL_I2L(t_usec
, t_sec
);
60 LL_I2L(usec_per_sec
, PR_USEC_PER_SEC
);
61 LL_MUL(t_usec
, t_usec
, usec_per_sec
);
64 static void PrintTimeString(char *buf
, PRUint32 bufsize
, PRUint32 t_sec
)
67 PRTime t_usec
= SecondsToPRTime(t_sec
);
68 PR_ExplodeTime(t_usec
, PR_LocalTimeParameters
, &et
);
69 PR_FormatTime(buf
, bufsize
, "%Y-%m-%d %H:%M:%S", &et
);
73 NS_IMPL_ISUPPORTS2(nsAboutCache
, nsIAboutModule
, nsICacheVisitor
)
76 nsAboutCache::NewChannel(nsIURI
*aURI
, nsIChannel
**result
)
78 NS_ENSURE_ARG_POINTER(aURI
);
80 PRUint32 bytesWritten
;
83 // Get the cache manager service
84 nsCOMPtr
<nsICacheService
> cacheService
=
85 do_GetService(NS_CACHESERVICE_CONTRACTID
, &rv
);
86 if (NS_FAILED(rv
)) return rv
;
88 nsCOMPtr
<nsIStorageStream
> storageStream
;
89 nsCOMPtr
<nsIOutputStream
> outputStream
;
91 // Init: (block size, maximum length)
92 rv
= NS_NewStorageStream(256, (PRUint32
)-1, getter_AddRefs(storageStream
));
93 if (NS_FAILED(rv
)) return rv
;
95 rv
= storageStream
->GetOutputStream(0, getter_AddRefs(outputStream
));
96 if (NS_FAILED(rv
)) return rv
;
98 mBuffer
.AssignLiteral(
99 "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n"
100 "<!DOCTYPE html PUBLIC \"-//W3C//DTD XHTML 1.1//EN\"\n"
101 " \"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd\">\n"
102 "<html xmlns=\"http://www.w3.org/1999/xhtml\">\n"
103 "<head>\n<title>Information about the Cache Service</title>\n</head>\n"
106 outputStream
->Write(mBuffer
.get(), mBuffer
.Length(), &bytesWritten
);
108 rv
= ParseURI(aURI
, mDeviceID
);
109 if (NS_FAILED(rv
)) return rv
;
111 mStream
= outputStream
;
112 rv
= cacheService
->VisitEntries(this);
114 if (rv
== NS_ERROR_NOT_AVAILABLE
) {
115 mBuffer
.AppendLiteral("<h2>The cache is disabled.</h2>\n");
117 else if (NS_FAILED(rv
)) {
121 if (!mDeviceID
.IsEmpty()) {
122 mBuffer
.AppendLiteral("</pre>\n");
124 mBuffer
.AppendLiteral("</div>\n</body>\n</html>\n");
125 outputStream
->Write(mBuffer
.get(), mBuffer
.Length(), &bytesWritten
);
127 nsCOMPtr
<nsIInputStream
> inStr
;
129 rv
= storageStream
->NewInputStream(0, getter_AddRefs(inStr
));
130 if (NS_FAILED(rv
)) return rv
;
133 rv
= NS_NewInputStreamChannel(&channel
, aURI
, inStr
,
134 NS_LITERAL_CSTRING("text/html"),
135 NS_LITERAL_CSTRING("utf-8"));
136 if (NS_FAILED(rv
)) return rv
;
143 nsAboutCache::GetURIFlags(nsIURI
*aURI
, PRUint32
*result
)
150 nsAboutCache::VisitDevice(const char *deviceID
,
151 nsICacheDeviceInfo
*deviceInfo
,
152 PRBool
*visitEntries
)
154 PRUint32 bytesWritten
, value
;
157 *visitEntries
= PR_FALSE
;
159 if (mDeviceID
.IsEmpty() || mDeviceID
.Equals(deviceID
)) {
161 // We need mStream for this
163 return NS_ERROR_FAILURE
;
165 // Write out the Cache Name
166 deviceInfo
->GetDescription(getter_Copies(str
));
168 mBuffer
.AssignLiteral("<h2>");
170 mBuffer
.AppendLiteral("</h2>\n<br />\n"
173 // Write out cache info
175 mBuffer
.AppendLiteral("\n<tr>\n<td><b>Number of entries:</b></td>\n");
177 deviceInfo
->GetEntryCount(&value
);
178 mBuffer
.AppendLiteral("<td><tt>");
179 mBuffer
.AppendInt(value
);
180 mBuffer
.AppendLiteral("</tt></td>\n</tr>\n"
181 "\n<tr>\n<td><b>Maximum storage size:</b></td>\n");
183 deviceInfo
->GetMaximumSize(&value
);
184 mBuffer
.AppendLiteral("<td><tt>");
185 mBuffer
.AppendInt(value
/1024);
186 mBuffer
.AppendLiteral(" KiB</tt></td>\n</tr>\n"
187 "\n<tr>\n<td><b>Storage in use:</b></td>\n"
190 deviceInfo
->GetTotalSize(&value
);
191 mBuffer
.AppendInt(value
/1024);
192 mBuffer
.AppendLiteral(" KiB</tt></td>\n</tr>\n");
194 deviceInfo
->GetUsageReport(getter_Copies(str
));
196 mBuffer
.AppendLiteral("</table>\n\n<br />");
198 if (mDeviceID
.IsEmpty()) {
199 mBuffer
.AppendLiteral("\n<a href=\"about:cache?device=");
200 mBuffer
.Append(deviceID
);
201 mBuffer
.AppendLiteral("\">List Cache Entries</a>\n"
204 *visitEntries
= PR_TRUE
;
205 mBuffer
.AppendLiteral("<hr />\n<pre>\n");
208 mStream
->Write(mBuffer
.get(), mBuffer
.Length(), &bytesWritten
);
215 nsAboutCache::VisitEntry(const char *deviceID
,
216 nsICacheEntryInfo
*entryInfo
,
219 // We need mStream for this
221 return NS_ERROR_FAILURE
;
224 PRUint32 bytesWritten
;
226 nsXPIDLCString clientID
;
229 rv
= entryInfo
->GetKey(key
);
230 if (NS_FAILED(rv
)) return rv
;
232 rv
= entryInfo
->GetClientID(getter_Copies(clientID
));
233 if (NS_FAILED(rv
)) return rv
;
235 rv
= entryInfo
->IsStreamBased(&streamBased
);
236 if (NS_FAILED(rv
)) return rv
;
238 // Generate a about:cache-entry URL for this entry...
240 url
.AssignLiteral("about:cache-entry?client=");
242 url
.AppendLiteral("&sb=");
243 url
+= streamBased
? '1' : '0';
244 url
.AppendLiteral("&key=");
245 char* escapedKey
= nsEscapeHTML(key
.get());
246 url
+= escapedKey
; // key
251 mBuffer
.AssignLiteral("<b> Key:</b> <a href=\"");
253 mBuffer
.AppendLiteral("\">");
254 mBuffer
.Append(escapedKey
);
255 nsMemory::Free(escapedKey
);
256 mBuffer
.AppendLiteral("</a>");
260 entryInfo
->GetDataSize(&length
);
262 mBuffer
.AppendLiteral("\n<b> Data size:</b> ");
263 mBuffer
.AppendInt(length
);
264 mBuffer
.AppendLiteral(" bytes");
266 // Number of accesses
267 PRInt32 fetchCount
= 0;
268 entryInfo
->GetFetchCount(&fetchCount
);
270 mBuffer
.AppendLiteral("\n<b> Fetch count:</b> ");
271 mBuffer
.AppendInt(fetchCount
);
273 // vars for reporting time
277 // Last modified time
278 mBuffer
.AppendLiteral("\n<b> Last modified:</b> ");
279 entryInfo
->GetLastModified(&t
);
281 PrintTimeString(buf
, sizeof(buf
), t
);
284 mBuffer
.AppendLiteral("No last modified time");
287 mBuffer
.AppendLiteral("\n<b> Expires:</b> ");
288 entryInfo
->GetExpirationTime(&t
);
289 if (t
< 0xFFFFFFFF) {
290 PrintTimeString(buf
, sizeof(buf
), t
);
293 mBuffer
.AppendLiteral("No expiration time");
297 mBuffer
.AppendLiteral("\n\n");
299 mStream
->Write(mBuffer
.get(), mBuffer
.Length(), &bytesWritten
);
301 *visitNext
= PR_TRUE
;
307 nsAboutCache::ParseURI(nsIURI
* uri
, nsCString
&deviceID
)
310 // about:cache[?device=string]
317 rv
= uri
->GetPath(path
);
318 if (NS_FAILED(rv
)) return rv
;
320 nsACString::const_iterator start
, valueStart
, end
;
321 path
.BeginReading(start
);
322 path
.EndReading(end
);
325 if (!FindInReadable(NS_LITERAL_CSTRING("?device="), start
, valueStart
))
328 deviceID
.Assign(Substring(valueStart
, end
));
334 nsAboutCache::Create(nsISupports
*aOuter
, REFNSIID aIID
, void **aResult
)
336 nsAboutCache
* about
= new nsAboutCache();
338 return NS_ERROR_OUT_OF_MEMORY
;
340 nsresult rv
= about
->QueryInterface(aIID
, aResult
);
347 ////////////////////////////////////////////////////////////////////////////////