2014-12-19 36 views
0

对于我的项目,我需要学习一些信息,如“FireFox/Gecko文件下载结构概述”(如果有),或者有些“FireFox/Gecko文件下载过程流程图”。到目前为止,我在互联网上找不到这样的东西。有没有关于它的任何信息?非常感谢。 PS:它必须包含通过FireFox浏览器下载的所有文件的路径,这些路径通过网络连接信息API和文件处理API,就像“httpOpenRequest”或“DoFileDownload”API(如果有)一样。Firefox文件下载过程结构图

什么是Firefox下载过程API路径?有没有数字或图表? 请帮助我...

回答

0

您可能需要查看代码才能获取所需的信息。您需要自己构建流程图。

在代码中有几种不同的下载方式。

如果你是在谈论一个Firefox插件进行下载,那么它可能正在使用做Downloads.jsm(尽管这样做旧的方法)。该JavaScript模块的源代码位于resource://gre/modules/Downloads.jsm(该URL仅在Firefox中有效)。似乎有几个文件都位于Firefox分发的根目录中的zip格式文件内的jsloader\resource\gre\modules目录中。您可以复制该文件并将其名称更改为omni.zip,并以普通的.zip文件的形式对其进行访问。

如果您想知道当用户请求时,Firefox如何保存页面:在上下文菜单中定义的oncommand值为gContextMenu.saveLink();。 saveLink()的定义如下:chrome://browser/content/nsContextMenu.js。它做了一些家务管理,然后拨打saveHelper() which is in the same file

saveHelper()代码如下:

// Helper function to wait for appropriate MIME-type headers and 
// then prompt the user with a file picker 
saveHelper: function(linkURL, linkText, dialogTitle, bypassCache, doc) { 
    // canonical def in nsURILoader.h 
    const NS_ERROR_SAVE_LINK_AS_TIMEOUT = 0x805d0020; 

    // an object to proxy the data through to 
    // nsIExternalHelperAppService.doContent, which will wait for the 
    // appropriate MIME-type headers and then prompt the user with a 
    // file picker 
    function saveAsListener() {} 
    saveAsListener.prototype = { 
    extListener: null, 

    onStartRequest: function saveLinkAs_onStartRequest(aRequest, aContext) { 

     // if the timer fired, the error status will have been caused by that, 
     // and we'll be restarting in onStopRequest, so no reason to notify 
     // the user 
     if (aRequest.status == NS_ERROR_SAVE_LINK_AS_TIMEOUT) 
     return; 

     timer.cancel(); 

     // some other error occured; notify the user... 
     if (!Components.isSuccessCode(aRequest.status)) { 
     try { 
      const sbs = Cc["@mozilla.org/intl/stringbundle;1"]. 
         getService(Ci.nsIStringBundleService); 
      const bundle = sbs.createBundle(
        "chrome://mozapps/locale/downloads/downloads.properties"); 

      const title = bundle.GetStringFromName("downloadErrorAlertTitle"); 
      const msg = bundle.GetStringFromName("downloadErrorGeneric"); 

      const promptSvc = Cc["@mozilla.org/embedcomp/prompt-service;1"]. 
          getService(Ci.nsIPromptService); 
      promptSvc.alert(doc.defaultView, title, msg); 
     } catch (ex) {} 
     return; 
     } 

     var extHelperAppSvc = 
     Cc["@mozilla.org/uriloader/external-helper-app-service;1"]. 
     getService(Ci.nsIExternalHelperAppService); 
     var channel = aRequest.QueryInterface(Ci.nsIChannel); 
     this.extListener = 
     extHelperAppSvc.doContent(channel.contentType, aRequest, 
            doc.defaultView, true); 
     this.extListener.onStartRequest(aRequest, aContext); 
    }, 

    onStopRequest: function saveLinkAs_onStopRequest(aRequest, aContext, 
                aStatusCode) { 
     if (aStatusCode == NS_ERROR_SAVE_LINK_AS_TIMEOUT) { 
     // do it the old fashioned way, which will pick the best filename 
     // it can without waiting. 
     saveURL(linkURL, linkText, dialogTitle, bypassCache, false, 
       doc.documentURIObject, doc); 
     } 
     if (this.extListener) 
     this.extListener.onStopRequest(aRequest, aContext, aStatusCode); 
    }, 

    onDataAvailable: function saveLinkAs_onDataAvailable(aRequest, aContext, 
                 aInputStream, 
                 aOffset, aCount) { 
     this.extListener.onDataAvailable(aRequest, aContext, aInputStream, 
             aOffset, aCount); 
    } 
    } 

    function callbacks() {} 
    callbacks.prototype = { 
    getInterface: function sLA_callbacks_getInterface(aIID) { 
     if (aIID.equals(Ci.nsIAuthPrompt) || aIID.equals(Ci.nsIAuthPrompt2)) { 
     // If the channel demands authentication prompt, we must cancel it 
     // because the save-as-timer would expire and cancel the channel 
     // before we get credentials from user. Both authentication dialog 
     // and save as dialog would appear on the screen as we fall back to 
     // the old fashioned way after the timeout. 
     timer.cancel(); 
     channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT); 
     } 
     throw Cr.NS_ERROR_NO_INTERFACE; 
    } 
    } 

    // if it we don't have the headers after a short time, the user 
    // won't have received any feedback from their click. that's bad. so 
    // we give up waiting for the filename. 
    function timerCallback() {} 
    timerCallback.prototype = { 
    notify: function sLA_timer_notify(aTimer) { 
     channel.cancel(NS_ERROR_SAVE_LINK_AS_TIMEOUT); 
     return; 
    } 
    } 

    // set up a channel to do the saving 
    var ioService = Cc["@mozilla.org/network/io-service;1"]. 
        getService(Ci.nsIIOService); 
    var channel = ioService.newChannelFromURI(makeURI(linkURL)); 
    if (channel instanceof Ci.nsIPrivateBrowsingChannel) { 
    let docIsPrivate = PrivateBrowsingUtils.isWindowPrivate(doc.defaultView); 
    channel.setPrivate(docIsPrivate); 
    } 
    channel.notificationCallbacks = new callbacks(); 

    let flags = Ci.nsIChannel.LOAD_CALL_CONTENT_SNIFFERS; 

    if (bypassCache) 
    flags |= Ci.nsIRequest.LOAD_BYPASS_CACHE; 

    if (channel instanceof Ci.nsICachingChannel) 
    flags |= Ci.nsICachingChannel.LOAD_BYPASS_LOCAL_CACHE_IF_BUSY; 

    channel.loadFlags |= flags; 

    if (channel instanceof Ci.nsIHttpChannel) { 
    channel.referrer = doc.documentURIObject; 
    if (channel instanceof Ci.nsIHttpChannelInternal) 
     channel.forceAllowThirdPartyCookie = true; 
    } 

    // fallback to the old way if we don't see the headers quickly 
    var timeToWait = 
    gPrefService.getIntPref("browser.download.saveLinkAsFilenameTimeout"); 
    var timer = Cc["@mozilla.org/timer;1"].createInstance(Ci.nsITimer); 
    timer.initWithCallback(new timerCallback(), timeToWait, 
         timer.TYPE_ONE_SHOT); 

    // kick off the channel with our proxy object as the listener 
    channel.asyncOpen(new saveAsListener(), null); 
}