/src/mozilla-central/toolkit/components/thumbnails/PageThumbsProtocol.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ |
2 | | /* This Source Code Form is subject to the terms of the Mozilla Public |
3 | | * License, v. 2.0. If a copy of the MPL was not distributed with this |
4 | | * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ |
5 | | |
6 | | /** |
7 | | * Implementation of moz-page-thumb protocol. This accesses and displays |
8 | | * screenshots for URLs that are stored in the profile directory. |
9 | | */ |
10 | | |
11 | | #include "nsIPageThumbsStorageService.h" |
12 | | #include "PageThumbsProtocol.h" |
13 | | #include "nsIURI.h" |
14 | | #include "nsIFileURL.h" |
15 | | #include "nsIFile.h" |
16 | | #include "nsIChannel.h" |
17 | | #include "nsComponentManagerUtils.h" |
18 | | #include "nsNetUtil.h" |
19 | | #include "mozilla/dom/URLSearchParams.h" |
20 | | #include "nsStandardURL.h" |
21 | | |
22 | | using mozilla::dom::URLParams; |
23 | | using mozilla::net::nsStandardURL; |
24 | | |
25 | | NS_IMPL_ISUPPORTS(PageThumbsProtocol, nsIProtocolHandler); |
26 | | |
27 | | // PageThumbsProtocol::GetScheme |
28 | | |
29 | | NS_IMETHODIMP |
30 | | PageThumbsProtocol::GetScheme(nsACString& aScheme) |
31 | 0 | { |
32 | 0 | aScheme.AssignLiteral("moz-page-thumb"); |
33 | 0 | return NS_OK; |
34 | 0 | } |
35 | | |
36 | | // PageThumbsProtocol::GetDefaultPort |
37 | | |
38 | | NS_IMETHODIMP |
39 | | PageThumbsProtocol::GetDefaultPort(int32_t *aDefaultPort) |
40 | 0 | { |
41 | 0 | *aDefaultPort = -1; |
42 | 0 | return NS_OK; |
43 | 0 | } |
44 | | |
45 | | // PageThumbsProtocol::GetProtocolFlags |
46 | | |
47 | | NS_IMETHODIMP |
48 | | PageThumbsProtocol::GetProtocolFlags(uint32_t *aProtocolFlags) |
49 | 0 | { |
50 | 0 | *aProtocolFlags = (URI_DANGEROUS_TO_LOAD | URI_IS_LOCAL_RESOURCE | |
51 | 0 | URI_NORELATIVE | URI_NOAUTH); |
52 | 0 | return NS_OK; |
53 | 0 | } |
54 | | |
55 | | // PageThumbsProtocol::NewURI |
56 | | |
57 | | NS_IMETHODIMP |
58 | | PageThumbsProtocol::NewURI(const nsACString& aSpec, |
59 | | const char *aOriginCharset, |
60 | | nsIURI *aBaseURI, nsIURI **_retval) |
61 | 0 | { |
62 | 0 | return NS_MutateURI(NS_SIMPLEURIMUTATOR_CONTRACTID) |
63 | 0 | .SetSpec(aSpec) |
64 | 0 | .Finalize(_retval); |
65 | 0 | } |
66 | | |
67 | | // PageThumbsProtocol::NewChannel |
68 | | |
69 | | NS_IMETHODIMP |
70 | | PageThumbsProtocol::NewChannel2(nsIURI* aURI, |
71 | | nsILoadInfo *aLoadInfo, |
72 | | nsIChannel** _retval) |
73 | 0 | { |
74 | 0 | // Get the file path for the URL |
75 | 0 | nsCOMPtr <nsIFile> filePath; |
76 | 0 | nsresult rv = GetFilePathForURL(aURI, getter_AddRefs(filePath)); |
77 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
78 | 0 | |
79 | 0 | // Get a file URI from the local file path |
80 | 0 | nsCOMPtr <nsIURI> fileURI; |
81 | 0 | rv = NS_NewFileURI(getter_AddRefs(fileURI), filePath); |
82 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
83 | 0 | |
84 | 0 | // Create a new channel with the file URI created |
85 | 0 | nsCOMPtr <nsIChannel> channel; |
86 | 0 | nsCOMPtr <nsIIOService> ios = do_GetIOService(); |
87 | 0 | rv = ios->NewChannelFromURIWithLoadInfo(fileURI, aLoadInfo, getter_AddRefs(channel)); |
88 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
89 | 0 | |
90 | 0 | channel->SetOriginalURI(aURI); |
91 | 0 | channel.forget(_retval); |
92 | 0 | return NS_OK; |
93 | 0 | } |
94 | | |
95 | | NS_IMETHODIMP |
96 | | PageThumbsProtocol::NewChannel(nsIURI* aURI, nsIChannel** _retval) |
97 | 0 | { |
98 | 0 | return NewChannel2(aURI, nullptr, _retval); |
99 | 0 | } |
100 | | |
101 | | // PageThumbsProtocol::AllowPort |
102 | | |
103 | | NS_IMETHODIMP |
104 | | PageThumbsProtocol::AllowPort(int32_t aPort, const char *aScheme, bool *_retval) |
105 | 0 | { |
106 | 0 | *_retval = false; |
107 | 0 | return NS_OK; |
108 | 0 | } |
109 | | |
110 | | // PageThumbsProtocol::ParseProtocolURL |
111 | | // |
112 | | // Extracts the URL from the query parameter. The URI is passed in in the form: |
113 | | // 'moz-page-thumb://thumbnail/?url=http%3A%2F%2Fwww.mozilla.org%2F'. |
114 | | |
115 | | nsresult |
116 | | PageThumbsProtocol::ParseProtocolURL(nsIURI* aURI, nsString& aParsedURL) |
117 | 0 | { |
118 | 0 | nsAutoCString spec; |
119 | 0 | aURI->GetSpec(spec); |
120 | 0 |
|
121 | 0 | // Check that we have the correct host |
122 | 0 | nsAutoCString host; |
123 | 0 | host = Substring(spec, spec.FindChar(':') + 3, 9); |
124 | 0 | if (!host.EqualsLiteral("thumbnail")) { |
125 | 0 | return NS_ERROR_NOT_AVAILABLE; |
126 | 0 | } |
127 | 0 | |
128 | 0 | // Get the path out of the URI |
129 | 0 | nsAutoCString path; |
130 | 0 | nsresult rv = aURI->GetPathQueryRef(path); |
131 | 0 |
|
132 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
133 | 0 | |
134 | 0 | // Since this is a protocol URI and it doesn't parse nicely, we split on where |
135 | 0 | // the start of the query is and parse it from there |
136 | 0 | int32_t queryBegins = path.FindChar('?'); |
137 | 0 | if (queryBegins <= 0) { |
138 | 0 | return NS_ERROR_MALFORMED_URI; |
139 | 0 | } |
140 | 0 | |
141 | 0 | URLParams::Extract(Substring(path, queryBegins + 1), |
142 | 0 | NS_LITERAL_STRING("url"), |
143 | 0 | aParsedURL); |
144 | 0 |
|
145 | 0 | // If there's no URL as part of the query params, there will be no thumbnail |
146 | 0 | if (aParsedURL.IsVoid()) { |
147 | 0 | return NS_ERROR_NOT_AVAILABLE; |
148 | 0 | } |
149 | 0 | |
150 | 0 | return NS_OK; |
151 | 0 | } |
152 | | |
153 | | // PageThumbsProtocol::GetFilePathForURL |
154 | | // |
155 | | // Returns the thumbnail's file path for a given URL |
156 | | |
157 | | nsresult |
158 | | PageThumbsProtocol::GetFilePathForURL(nsIURI* aURI, nsIFile **_retval) |
159 | 0 | { |
160 | 0 | nsresult rv; |
161 | 0 |
|
162 | 0 | // Use PageThumbsStorageService to get the local file path of the screenshot |
163 | 0 | // for the given URL |
164 | 0 | nsAutoString filePathForURL; |
165 | 0 | nsCOMPtr <nsIPageThumbsStorageService> pageThumbsStorage = |
166 | 0 | do_GetService("@mozilla.org/thumbnails/pagethumbs-service;1", &rv); |
167 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
168 | 0 | |
169 | 0 | // Parse the protocol URL to extract the thumbnail's URL |
170 | 0 | nsAutoString parsedURL; |
171 | 0 | rv = ParseProtocolURL(aURI, parsedURL); |
172 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
173 | 0 | |
174 | 0 | rv = pageThumbsStorage->GetFilePathForURL(parsedURL, filePathForURL); |
175 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
176 | 0 | |
177 | 0 | // Find the local file containing the screenshot |
178 | 0 | nsCOMPtr <nsIFile> filePath = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID); |
179 | 0 | rv = filePath->InitWithPath(filePathForURL); |
180 | 0 | if (NS_WARN_IF(NS_FAILED(rv))) return rv; |
181 | 0 | |
182 | 0 | filePath.forget(_retval); |
183 | 0 | return NS_OK; |
184 | 0 | } |
185 | | |