forked from mirrors/gecko-dev
Differential Revision: https://phabricator.services.mozilla.com/D30703 --HG-- extra : moz-landing-system : lando
159 lines
4.8 KiB
C++
159 lines
4.8 KiB
C++
//* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
|
|
/* This Source Code Form is subject to the terms of the Mozilla Public
|
|
* License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
|
|
|
|
/**
|
|
* Implementation of moz-page-thumb protocol. This accesses and displays
|
|
* screenshots for URLs that are stored in the profile directory.
|
|
*/
|
|
|
|
#include "nsIPageThumbsStorageService.h"
|
|
#include "PageThumbsProtocol.h"
|
|
#include "nsIURI.h"
|
|
#include "nsIFileURL.h"
|
|
#include "nsIFile.h"
|
|
#include "nsIChannel.h"
|
|
#include "nsComponentManagerUtils.h"
|
|
#include "nsNetUtil.h"
|
|
#include "mozilla/dom/URLSearchParams.h"
|
|
#include "nsStandardURL.h"
|
|
|
|
using mozilla::dom::URLParams;
|
|
using mozilla::net::nsStandardURL;
|
|
|
|
NS_IMPL_ISUPPORTS(PageThumbsProtocol, nsIProtocolHandler);
|
|
|
|
// PageThumbsProtocol::GetScheme
|
|
|
|
NS_IMETHODIMP
|
|
PageThumbsProtocol::GetScheme(nsACString& aScheme) {
|
|
aScheme.AssignLiteral("moz-page-thumb");
|
|
return NS_OK;
|
|
}
|
|
|
|
// PageThumbsProtocol::GetDefaultPort
|
|
|
|
NS_IMETHODIMP
|
|
PageThumbsProtocol::GetDefaultPort(int32_t* aDefaultPort) {
|
|
*aDefaultPort = -1;
|
|
return NS_OK;
|
|
}
|
|
|
|
// PageThumbsProtocol::GetProtocolFlags
|
|
|
|
NS_IMETHODIMP
|
|
PageThumbsProtocol::GetProtocolFlags(uint32_t* aProtocolFlags) {
|
|
*aProtocolFlags = (URI_DANGEROUS_TO_LOAD | URI_IS_LOCAL_RESOURCE |
|
|
URI_NORELATIVE | URI_NOAUTH);
|
|
return NS_OK;
|
|
}
|
|
|
|
// PageThumbsProtocol::NewChannel
|
|
|
|
NS_IMETHODIMP
|
|
PageThumbsProtocol::NewChannel(nsIURI* aURI, nsILoadInfo* aLoadInfo,
|
|
nsIChannel** _retval) {
|
|
// Get the file path for the URL
|
|
nsCOMPtr<nsIFile> filePath;
|
|
nsresult rv = GetFilePathForURL(aURI, getter_AddRefs(filePath));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
// Get a file URI from the local file path
|
|
nsCOMPtr<nsIURI> fileURI;
|
|
rv = NS_NewFileURI(getter_AddRefs(fileURI), filePath);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
// Create a new channel with the file URI created
|
|
nsCOMPtr<nsIChannel> channel;
|
|
nsCOMPtr<nsIIOService> ios = do_GetIOService();
|
|
rv = ios->NewChannelFromURIWithLoadInfo(fileURI, aLoadInfo,
|
|
getter_AddRefs(channel));
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
channel->SetOriginalURI(aURI);
|
|
channel.forget(_retval);
|
|
return NS_OK;
|
|
}
|
|
|
|
// PageThumbsProtocol::AllowPort
|
|
|
|
NS_IMETHODIMP
|
|
PageThumbsProtocol::AllowPort(int32_t aPort, const char* aScheme,
|
|
bool* _retval) {
|
|
*_retval = false;
|
|
return NS_OK;
|
|
}
|
|
|
|
// PageThumbsProtocol::ParseProtocolURL
|
|
//
|
|
// Extracts the URL from the query parameter. The URI is passed in in the
|
|
// form: 'moz-page-thumb://thumbnail/?url=http%3A%2F%2Fwww.mozilla.org%2F'.
|
|
|
|
nsresult PageThumbsProtocol::ParseProtocolURL(nsIURI* aURI,
|
|
nsString& aParsedURL) {
|
|
nsAutoCString spec;
|
|
aURI->GetSpec(spec);
|
|
|
|
// Check that we have the correct host
|
|
nsAutoCString host;
|
|
host = Substring(spec, spec.FindChar(':') + 3, 9);
|
|
if (!host.EqualsLiteral("thumbnail")) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
// Get the path out of the URI
|
|
nsAutoCString path;
|
|
nsresult rv = aURI->GetPathQueryRef(path);
|
|
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
// Since this is a protocol URI and it doesn't parse nicely, we split on where
|
|
// the start of the query is and parse it from there
|
|
int32_t queryBegins = path.FindChar('?');
|
|
if (queryBegins <= 0) {
|
|
return NS_ERROR_MALFORMED_URI;
|
|
}
|
|
|
|
URLParams::Extract(Substring(path, queryBegins + 1), NS_LITERAL_STRING("url"),
|
|
aParsedURL);
|
|
|
|
// If there's no URL as part of the query params, there will be no thumbnail
|
|
if (aParsedURL.IsVoid()) {
|
|
return NS_ERROR_NOT_AVAILABLE;
|
|
}
|
|
|
|
return NS_OK;
|
|
}
|
|
|
|
// PageThumbsProtocol::GetFilePathForURL
|
|
//
|
|
// Returns the thumbnail's file path for a given URL
|
|
|
|
nsresult PageThumbsProtocol::GetFilePathForURL(nsIURI* aURI,
|
|
nsIFile** _retval) {
|
|
nsresult rv;
|
|
|
|
// Use PageThumbsStorageService to get the local file path of the screenshot
|
|
// for the given URL
|
|
nsAutoString filePathForURL;
|
|
nsCOMPtr<nsIPageThumbsStorageService> pageThumbsStorage =
|
|
do_GetService("@mozilla.org/thumbnails/pagethumbs-service;1", &rv);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
// Parse the protocol URL to extract the thumbnail's URL
|
|
nsAutoString parsedURL;
|
|
rv = ParseProtocolURL(aURI, parsedURL);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
rv = pageThumbsStorage->GetFilePathForURL(parsedURL, filePathForURL);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
// Find the local file containing the screenshot
|
|
nsCOMPtr<nsIFile> filePath = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
|
|
rv = filePath->InitWithPath(filePathForURL);
|
|
if (NS_WARN_IF(NS_FAILED(rv))) return rv;
|
|
|
|
filePath.forget(_retval);
|
|
return NS_OK;
|
|
}
|