mirror of
https://github.com/mozilla/gecko-dev.git
synced 2024-11-25 05:41:12 +00:00
Bug 337051: Add origin and referrer URL metadata to downloaded files on OS X. r=mstange,pamadini
This commit is contained in:
parent
27cb0a7981
commit
0a5546331b
@ -26,6 +26,8 @@ interface mozIDownloadPlatform : nsISupports
|
||||
*
|
||||
* @param aSource
|
||||
* Source URI of the download
|
||||
* @param aReferrer
|
||||
* Referrer URI of the download
|
||||
* @param aTarget
|
||||
* Downloaded file
|
||||
* @param aContentType
|
||||
@ -34,7 +36,7 @@ interface mozIDownloadPlatform : nsISupports
|
||||
* True for private downloads
|
||||
* @return none
|
||||
*/
|
||||
void downloadDone(in nsIURI aSource, in nsIFile aTarget,
|
||||
void downloadDone(in nsIURI aSource, in nsIURI aReferrer, in nsIFile aTarget,
|
||||
in ACString aContentType, in boolean aIsPrivate);
|
||||
|
||||
/**
|
||||
|
@ -679,7 +679,13 @@ this.DownloadIntegration = {
|
||||
}
|
||||
}
|
||||
|
||||
let aReferrer = null;
|
||||
if (aDownload.source.referrer) {
|
||||
aReferrer: NetUtil.newURI(aDownload.source.referrer);
|
||||
}
|
||||
|
||||
gDownloadPlatform.downloadDone(NetUtil.newURI(aDownload.source.url),
|
||||
aReferrer,
|
||||
new FileUtils.File(aDownload.target.path),
|
||||
aDownload.contentType,
|
||||
aDownload.source.isPrivate);
|
||||
|
@ -24,6 +24,7 @@
|
||||
|
||||
#ifdef XP_MACOSX
|
||||
#include <CoreFoundation/CoreFoundation.h>
|
||||
#include "../../../../../xpcom/io/CocoaFileUtils.h"
|
||||
#endif
|
||||
|
||||
#ifdef MOZ_WIDGET_ANDROID
|
||||
@ -69,7 +70,32 @@ static void gio_set_metadata_done(GObject *source_obj, GAsyncResult *res, gpoint
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget,
|
||||
#ifdef XP_MACOSX
|
||||
// Caller is responsible for freeing any result (CF Create Rule)
|
||||
CFURLRef CreateCFURLFromNSIURI(nsIURI *aURI) {
|
||||
nsAutoCString spec;
|
||||
if (aURI) {
|
||||
aURI->GetSpec(spec);
|
||||
}
|
||||
|
||||
CFStringRef urlStr = ::CFStringCreateWithCString(kCFAllocatorDefault,
|
||||
spec.get(),
|
||||
kCFStringEncodingUTF8);
|
||||
if (!urlStr) {
|
||||
return NULL;
|
||||
}
|
||||
|
||||
CFURLRef url = ::CFURLCreateWithString(kCFAllocatorDefault,
|
||||
urlStr,
|
||||
NULL);
|
||||
|
||||
::CFRelease(urlStr);
|
||||
|
||||
return url;
|
||||
}
|
||||
#endif
|
||||
|
||||
nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIURI* aReferrer, nsIFile* aTarget,
|
||||
const nsACString& aContentType, bool aIsPrivate)
|
||||
{
|
||||
#if defined(XP_WIN) || defined(XP_MACOSX) || defined(MOZ_WIDGET_ANDROID) \
|
||||
@ -130,6 +156,33 @@ nsresult DownloadPlatform::DownloadDone(nsIURI* aSource, nsIFile* aTarget,
|
||||
::CFNotificationCenterPostNotification(center, CFSTR("com.apple.DownloadFileFinished"),
|
||||
observedObject, nullptr, TRUE);
|
||||
::CFRelease(observedObject);
|
||||
|
||||
// Add OS X origin and referrer file metadata
|
||||
CFStringRef pathCFStr = NULL;
|
||||
if (!path.IsEmpty()) {
|
||||
pathCFStr = ::CFStringCreateWithCharacters(kCFAllocatorDefault,
|
||||
(const UniChar*)path.get(),
|
||||
path.Length());
|
||||
}
|
||||
if (pathCFStr) {
|
||||
CFURLRef sourceCFURL = CreateCFURLFromNSIURI(aSource);
|
||||
CFURLRef referrerCFURL = CreateCFURLFromNSIURI(aReferrer);
|
||||
|
||||
CocoaFileUtils::AddOriginMetadataToFile(pathCFStr,
|
||||
sourceCFURL,
|
||||
referrerCFURL);
|
||||
CocoaFileUtils::AddQuarantineMetadataToFile(pathCFStr,
|
||||
sourceCFURL,
|
||||
referrerCFURL);
|
||||
|
||||
::CFRelease(pathCFStr);
|
||||
if (sourceCFURL) {
|
||||
::CFRelease(sourceCFURL);
|
||||
}
|
||||
if (referrerCFURL) {
|
||||
::CFRelease(referrerCFURL);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
if (mozilla::Preferences::GetBool("device.storage.enabled", true)) {
|
||||
// Tell DeviceStorage that a new file may have been added.
|
||||
|
@ -21,6 +21,12 @@ nsresult GetFileCreatorCode(CFURLRef aUrl, OSType* aCreatorCode);
|
||||
nsresult SetFileCreatorCode(CFURLRef aUrl, OSType aCreatorCode);
|
||||
nsresult GetFileTypeCode(CFURLRef aUrl, OSType* aTypeCode);
|
||||
nsresult SetFileTypeCode(CFURLRef aUrl, OSType aTypeCode);
|
||||
void AddOriginMetadataToFile(const CFStringRef filePath,
|
||||
const CFURLRef sourceURL,
|
||||
const CFURLRef referrerURL);
|
||||
void AddQuarantineMetadataToFile(const CFStringRef filePath,
|
||||
const CFURLRef sourceURL,
|
||||
const CFURLRef referrerURL);
|
||||
|
||||
} // namespace CocoaFileUtils
|
||||
|
||||
|
@ -136,4 +136,119 @@ nsresult SetFileTypeCode(CFURLRef url, OSType typeCode)
|
||||
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
|
||||
}
|
||||
|
||||
void AddOriginMetadataToFile(const CFStringRef filePath,
|
||||
const CFURLRef sourceURL,
|
||||
const CFURLRef referrerURL) {
|
||||
typedef OSStatus (*MDItemSetAttribute_type)(MDItemRef, CFStringRef, CFTypeRef);
|
||||
static MDItemSetAttribute_type mdItemSetAttributeFunc = NULL;
|
||||
|
||||
static bool did_symbol_lookup = false;
|
||||
if (!did_symbol_lookup) {
|
||||
did_symbol_lookup = true;
|
||||
|
||||
CFBundleRef metadata_bundle = ::CFBundleGetBundleWithIdentifier(CFSTR("com.apple.Metadata"));
|
||||
if (!metadata_bundle) {
|
||||
return;
|
||||
}
|
||||
|
||||
mdItemSetAttributeFunc = (MDItemSetAttribute_type)
|
||||
::CFBundleGetFunctionPointerForName(metadata_bundle, CFSTR("MDItemSetAttribute"));
|
||||
}
|
||||
if (!mdItemSetAttributeFunc) {
|
||||
return;
|
||||
}
|
||||
|
||||
MDItemRef mdItem = ::MDItemCreate(NULL, filePath);
|
||||
if (!mdItem) {
|
||||
return;
|
||||
}
|
||||
|
||||
CFMutableArrayRef list = ::CFArrayCreateMutable(kCFAllocatorDefault, 2, NULL);
|
||||
if (!list) {
|
||||
::CFRelease(mdItem);
|
||||
return;
|
||||
}
|
||||
|
||||
// The first item in the list is the source URL of the downloaded file.
|
||||
if (sourceURL) {
|
||||
::CFArrayAppendValue(list, ::CFURLGetString(sourceURL));
|
||||
}
|
||||
|
||||
// If the referrer is known, store that in the second position.
|
||||
if (referrerURL) {
|
||||
::CFArrayAppendValue(list, ::CFURLGetString(referrerURL));
|
||||
}
|
||||
|
||||
mdItemSetAttributeFunc(mdItem, kMDItemWhereFroms, list);
|
||||
|
||||
::CFRelease(list);
|
||||
::CFRelease(mdItem);
|
||||
}
|
||||
|
||||
void AddQuarantineMetadataToFile(const CFStringRef filePath,
|
||||
const CFURLRef sourceURL,
|
||||
const CFURLRef referrerURL) {
|
||||
CFURLRef fileURL = ::CFURLCreateWithFileSystemPath(kCFAllocatorDefault,
|
||||
filePath,
|
||||
kCFURLPOSIXPathStyle,
|
||||
false);
|
||||
|
||||
CFDictionaryRef quarantineProps = NULL;
|
||||
Boolean success = ::CFURLCopyResourcePropertyForKey(fileURL,
|
||||
kLSItemQuarantineProperties,
|
||||
&quarantineProps,
|
||||
NULL);
|
||||
|
||||
// If there aren't any quarantine properties then the user probably
|
||||
// set up an exclusion and we don't need to add metadata.
|
||||
if (!success || !quarantineProps) {
|
||||
::CFRelease(fileURL);
|
||||
return;
|
||||
}
|
||||
|
||||
// We don't know what to do if the props aren't a dictionary.
|
||||
if (::CFGetTypeID(quarantineProps) != ::CFDictionaryGetTypeID()) {
|
||||
::CFRelease(fileURL);
|
||||
::CFRelease(quarantineProps);
|
||||
return;
|
||||
}
|
||||
|
||||
// Make a mutable copy of the properties.
|
||||
CFMutableDictionaryRef mutQuarantineProps =
|
||||
::CFDictionaryCreateMutableCopy(kCFAllocatorDefault, 0, (CFDictionaryRef)quarantineProps);
|
||||
::CFRelease(quarantineProps);
|
||||
|
||||
// Add metadata that the OS couldn't infer.
|
||||
|
||||
if (!::CFDictionaryGetValue(mutQuarantineProps, kLSQuarantineTypeKey)) {
|
||||
CFStringRef type = kLSQuarantineTypeOtherDownload;
|
||||
|
||||
CFStringRef scheme = ::CFURLCopyScheme(sourceURL);
|
||||
if (::CFStringCompare(scheme, CFSTR("http"), kCFCompareCaseInsensitive) == kCFCompareEqualTo ||
|
||||
::CFStringCompare(scheme, CFSTR("http"), kCFCompareCaseInsensitive) == kCFCompareEqualTo) {
|
||||
type = kLSQuarantineTypeWebDownload;
|
||||
}
|
||||
::CFRelease(scheme);
|
||||
|
||||
::CFDictionarySetValue(mutQuarantineProps, kLSQuarantineTypeKey, type);
|
||||
}
|
||||
|
||||
if (!::CFDictionaryGetValue(mutQuarantineProps, kLSQuarantineOriginURLKey)) {
|
||||
::CFDictionarySetValue(mutQuarantineProps, kLSQuarantineOriginURLKey, referrerURL);
|
||||
}
|
||||
|
||||
if (!::CFDictionaryGetValue(mutQuarantineProps, kLSQuarantineDataURLKey)) {
|
||||
::CFDictionarySetValue(mutQuarantineProps, kLSQuarantineDataURLKey, sourceURL);
|
||||
}
|
||||
|
||||
// Set quarantine properties on file.
|
||||
::CFURLSetResourcePropertyForKey(fileURL,
|
||||
kLSItemQuarantineProperties,
|
||||
mutQuarantineProps,
|
||||
NULL);
|
||||
|
||||
::CFRelease(fileURL);
|
||||
::CFRelease(mutQuarantineProps);
|
||||
}
|
||||
|
||||
} // namespace CocoaFileUtils
|
||||
|
Loading…
Reference in New Issue
Block a user