Monthly Archives: November 2008

HTTP Accept-Ranges support improved

I thought I’d blog about this, hoping some web developers may find it useful.

Previously, Mozilla’s HTTP protocol implementation did not check the presence of the Accept-Ranges response header.  The job of this header is to tell the client whether it can perform HTTP range requests, and if so, in what units should it express its range requests.  Practically, the only unit used by web servers is bytes, so this header’s job in the real world is to tell the server whether it can perform range requests at all.

The main purpose of performing range requests is either supporting download resume (where you close the connection, and next time you request the resource, you specify the remaining range of the file in your HTTP request) or downloading files in smaller chunks simultaneously like download manager applications do (where they perform several range requests side by side in order to start downloading on multiple channels instead of a single channel).

Bad news was that the Accept-Ranges header was not checked in Mozilla at all.  So, if a server would send the Accept-Ranges: none response header, in order to tell the client that the download is not resumable, Mozilla was not aware of this fact, and would show the download as resumable to the user.  And this is bad, because for example a user might have such a download in progress, and when closing Firefox, it wouldn’t prompt the user about the in-progress download, because it would blindly think that it’s actually resumable, so it would pause the download hoping to resume it next time Firefox starts, but that of course didn’t work.

In an IRC discussion with biesi, we noted the bug, so I filed and fixed bug 462707, which will appear in Firefox 3.1 and later versions.  This makes Mozilla a little bit more conformant to the HTTP specification. 

Tagged with: , ,
Posted in Blog

Testing in Mozilla talk

I gave a talk on Mozilla Software testing approach as part of my Software Testing course.  You can find the slides (built using S5) here.  I introduced a number of tools that we use for automated and manual testing, and also gave an overview on parts of the process employed to use the tests in real life.

You can grab the slides.  I hope that they’ll be useful to you.

Update: I made a mistake when writing this post, which caused the links not work.  I’ve fixed that, so now you can really see the slides. 

Update 2: I uploaded the presentation to the Mozilla Library, which is a collection of Mozilla-related presentations.  Thanks to Clint for pointing this out!

Tagged with: , ,
Posted in Blog

Software Testing: The Mozilla Approach

I gave a talk on Mozilla Software testing approach as part of my Software Testing course.  You can find the slides (built using S5) here.  I introduced a number of tools that we use for automated and manual testing, and also overviewed parts of the process employed to use the tests in real life.

You can grab the slides.  I hope that they’ll be useful to you.

Posted in Talks

ABC Meme (or “Expose Yourself”)

Started by Benjamin.  Here are my results.

 The i and w entries were links to my local project pages hosted on a local Apache. 

Tagged with:
Posted in Blog

Persian Firefox: Sneak Peak

Look what we’re building!

Persian Firefox (فایرفاکس فارسی)

Tagged with: , , , ,
Posted in Blog

First Private Browsing extension

I did expect the community to get interested in extending the Private Browsing mode by developing extensions, but I didn’t expect it to happen this soon!  I’m happy to announce that the first Private Browsing extension has been developed by the community member Kurt Schultz! This extension adds a toolbar and a status bar button to Firefox for quick access to the Private Browsing feature, and lets you toggle a few of the underlying preferences as a bonus!  Grab it while it’s hot from AMO!

Here’s a screenshot provided by Kurt:

Toggle Private Browsing extension in action

Thanks for the great work, Kurt!

Tagged with: , , ,
Posted in Blog

Prepare your add-on for Private Browsing

Private Browsing is one of the new features of Firefox which extension developers should start to handle in their extensions.  The API for this new mode is quite straightforward, and easy to use.  In addition, theme developers may want to style Firefox differently inside the Private Browsing mode.  That is also insanely easy to do.  In this article, I’m going to give you an overview of how the API works, plus with some sample code.  Note that what I’m explaining here is based the latest features landed on Mozilla trunk, and I don’t expect any of them to break before the final release of Firefox 3.1, but we may land extra API support if add-on developers demand it, so make sure to leave your comments.

Notice: This post is targeted at Mozilla extension developers and theme designers.  See my previous post for a general overview of the Private Browsing mode.

Private Browsing mode for extension developers

First, a bit of background is in order.  Many extensions may store data which can be used to reveal the places that the user has visited.  Examples include a download manager/helper extension, an extension which manipulates Places information, an extension which stores or otherwise manipulates cookies, etc.  You may be wondering what it takes to ensure that your extension respects the user’s choice about the private mode.  The most important thing to note here is that the Private Browsing mode does not magically handle what your extension does in saving browsing history data; that is the job of each extension.

At the heart of our Private Browsing implementation lies the Private Browsing service.  This service, which can be accessed using the contract ID @mozilla.org/privatebrowsing;1, implements the nsIPrivateBrowsingService interface.  Here is the definition of this interface:

[scriptable, uuid(49d6f133-80c0-48c7-876d-0b70bbfd0289)]
interface nsIPrivateBrowsingService : nsISupports
{
    // When read, determines whether the private browsing mode is currently
    // active.  Setting to true enters the private browsing mode, and setting
    // to false leaves the private browsing mode.
    // Setting this value while handling one of the notifications generated
    // by the private browsing service throws NS_ERROR_FAILURE.
    attribute boolean privateBrowsingEnabled;

    // Determine whether the private browsing mode has been started
    // automatically at application startup.
    // This value will never be true if privateBrowsingEnabled is false.
    readonly attribute boolean autoStarted;
};

The privateBrowsingEnabled attribute is the most important one.  To get the current status of the Private Browsing service, it’s enough to get the value of this attribute.  To switch to the Private Browsing mode, this attribute should be set to true, and to exit this mode, it should be set to false.  The autoStarted attribute can be queried to determine whether the browser.privatebrowsing.autostart preference has triggered the private mode automatically at startup.

There are a number of notifications which the Private Browsing service sends out in order to notify extensions about the Private Browsing related events that happen at runtime.  When the Private Browsing mode is about to initiate, the service sends out the private-browsing-cancel-vote notification in order to ask all the observers if they are all OK with entering the private browsing mode.  The data parameter if this notification will be set to enter.  The subject parameter of this notification will be set to a nsISupportsPRBool object.  Extensions are supposed to set this object to true if they wish to prevent the browser from entering the Private Browsing mode (for example, if the extension is downloading a file which can’t be interrupted).  If none of the observers vote to cancel the mode transition, the Private Browsing mode will be activated.  This sends a private-browsing notification with the data parameter set to enter.

The reverse case happens when the Private Browsing service is requested to leave the private mode.  First, a private-browsing-cancel-vote notification is sent to check if all modules can handle the private mode switch.  The data parameter will be set to exit this time.  If no extension sets the subject parameter to true, then the private mode will be turned off, and a private-browsing notification will be sent with the data parameter set to exit.  One extra point to mention here is that the subject parameter of the private-browsing notification will be a nsISupportsPRBool which determines whether the mode is being terminated normally, or because of an application shutdown (true standing for the case of an application shutdown).

A few code samples will be useful here, to demonstrate the API.

Sample 1: check the status of the Private Browsing mode

This sample shows the most basic usage of the Private Browsing service: querying the current status of Private Browsing.

var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
                    .getService(Components.interfaces.nsIPrivateBrowsingService);

// are we currently in the Private Browsing mode?
var inPrivateBrowsingMode = pbs.privateBrowsingEnabled;

Sample 2: listen for Private Browsing notifications

This sample first defines a helper object to make the process of listening for Private Browsing mode changes easier, and then shows a small sample of how this can be used.

// Helper object to register listeners for Private Browsing mode changes
function PrivateBrowsingListener() {
  this.init();
}
PrivateBrowsingListener.prototype = {
  _os: null,
  _inPrivateBrowsing: false, // whether we are in private browsing mode
  _watcher: null, // the watcher object

  init : function () {
    this._inited = true;
    this._os = Components.classes["@mozilla.org/observer-service;1"]
                         .getService(Components.interfaces.nsIObserverService);
    this._os.addObserver(this, "private-browsing", false);
    this._os.addObserver(this, "quit-application", false);
    try {
      var pbs = Components.classes["@mozilla.org/privatebrowsing;1"]
                          .getService(Components.interfaces.nsIPrivateBrowsingService);
      this._inPrivateBrowsing = pbs.privateBrowsingEnabled;
    } catch(ex) {
      // ignore exceptions in older versions of Firefox
    }
  },

  observe : function (aSubject, aTopic, aData) {
    if (aTopic == "private-browsing") {
      if (aData == "enter") {
        this._inPrivateBrowsing = true;
        if (this.watcher &&
            "onEnterPrivateBrowsing" in this._watcher) {
          this.watcher.onEnterPrivateBrowsing();
        }
      } else if (aData == "exit") {
        this._inPrivateBrowsing = false;
        if (this.watcher &&
            "onExitPrivateBrowsing" in this._watcher) {
          this.watcher.onExitPrivateBrowsing();
        }
      }
    } else if (aTopic == "quit-application") {
      this._os.removeObserver(this, "quit-application");
      this._os.removeObserver(this, "private-browsing");
    }
  },

  get inPrivateBrowsing() {
    return this._inPrivateBrowsing;
  },

  get watcher() {
    return this._watcher;
  },

  set watcher(val) {
    this._watcher = val;
  }
};

// Here's how to use this helper

var listener = new PrivateBrowsingListener();

if (listener.inPrivateBrowsing) {
  // we are in the private mode!
} else {
  // we are not in the private mode!
}

listener.watcher = {
  onEnterPrivateBrowsing : function() {
    // we have just entered the private browsing mode!
  },

  onExitPrivateBrowsing : function() {
    // we have just left the private browsing mode!
  }
};

Please note that the onEnterPrivateBrowsing and onExitPrivateBrowsing functions are optional, and you can avoid declaring one if you don’t need it.  Also, note that the PrivateBrowsingListener object is safe to use in previous version of Firefox which did not have the Private Browsing service available.

Sample 3: turn Private Browsing on or off

This sample shows how extensions can switch to and from the Private Browsing mode.

var pbs = Components.classes["@mozilla.org/browser/privatebrowsing;1"]
                    .getService(Components.interfaces.nsIPrivateBrowsingService);

// enter the Private Browsing mode
pbs.privateBrowsingEnabled = true;

// now, whatever we do remains private!

// exit the Private Browsing mode
pbs.privateBrowsingEnabled = false;

Sample 4: prevent leaving the Private Browsing mode

This sample shows how an extension can prevent the browser from turning the Private Browsing mode off.

var os = Components.classes["@mozilla.org/observer-service;1"]
                   .getService(Components.interfaces.nsIObserverService);
os.addObserver(function (aSubject, aTopic, aData) {
    aSubject.QueryInterface(Components.interfaces.nsISupportsPRBool);
    // if another extension has not already canceled entering the private mode
    if (!aSubject.data) {
      if (aData == "exit") { // if we are leaving the private mode
        aSubject.data = true; // cancel the operation
      }
    }
  }, "private-browsing-cancel-vote", false);

Private Browsing mode for theme designers

Our goal here was to enable a CSS-only mechanism to allow theme designers to style the browser both outside and inside of the Private Browsing mode.  I simply added the browsingmode attribute to the window element in browser.xul.  The value of this attribute is normal when the user is outside the Private Browsing mode, and it’s switched to private when the user turns the Private Browsing mode on.  This allows having CSS rules to select any element inside the browser’s window inside the private browsing mode specifically, and styling them to your heart’s content.  For example, suppose that you would like the location bar to appear with a gray background while we’re inside the Private Browsing mode.  This can simply be done like below:

[browsingmode=private] #urlbar {
  background: #eee;
}

We have tried to keep everything as simple as we could, so if you feel there’s something which can be improved in the API, or need to ask a question, please do not hesitate to leave a comment here.  You’re feedback is appreciated.  Yes, really!

Update:  Modified Sample 2 to work in previous versions of Firefox.

Tagged with: , , ,
Posted in Blog

Don’t leave a trace: Private Browsing in Firefox

Today, a major feature was added to the pre-release versions of Firefox 3.1, called Private Browsing.  I’ve been working for quite some time on this, so I thought it may be a good time to write about what this feature is and how to use it.

As you may know, while you browse the web, your browser usually records a lot of data which will later be used to improve your browsing experience.  For example, it records a history of all the web pages you have visited, so that later if you need help remembering a site you visited a while back, it can assist you in finding that site.  Now, that is great, but there is a downside: those data can be used to trace your online activities.  For example, if your coworker sits at your computer, she can view all of your browsing history, which may not be what you want.

Suppose you’re doing something online, and you don’t want your coworkers know about it.  An example scenario would be looking for a new employer while at work!  One option would be to do your work, and then clear the data that Firefox has stored for you, such as history, cookies, cache, ….  But the problem is that this action will also remove the parts of your online activities data which you don’t want to hide, so the history that Firefox records can no longer be used to find a web site you had visited a month before.  Private Browsing will help you here.

Private Browsing aims to help you make sure that your web browsing activities don’t leave any trace on your own computer.  It is very important to note that Private Browsing is not a tool to keep you anonymous from websites or your ISP, or for example protect you from all kinds of spyware applications which use sophisticated techniques to intercept your online traffic.  Private Browsing is only about making sure that Firefox doesn’t store any data which can be used to trace your online activities, no more, no less.

So how does one actually use this feature?  It couldn’t be simpler!  To start, just select Private Browsing from the Tools menu.

To start, just select Private Browsing from the Tools menu.

You will see a dialog box which asks you whether you want to save and close all of your current windows and tabs, and start the Private Browsing mode.  Click Start Private Browsing to start your private session.

Click Start Private Browsing to start your private session.

After you do this, your non-private browsing session is closed and a new private session is opened, showing you the screen below.  (Before you mention, the ugly icon you see there is something I created as a placeholder!  This icon will be replaced in the final release of Firefox 3.1.)

Start of the Private Browsing mode

As you see, not much is different in the Firefox window inside the Private Browsing mode, except for the (Private Browsing) text added to the title bar at the top of the window.  That is intentional: after all, if you’re doing something online that you don’t want your coworkers to know about, you don’t want to raise their attention with a big sign saying PRIVATE as they pass by and glance over your shoulder. 

At this stage, you can start browsing web sites, without ever having to worry that Firefox might store something on your computer which can be used to tell which pages you have visited.  Once you’re done, just uncheck the same menu item in the Tools menu to close your private session.

Once you're done, just uncheck the same menu item in the Tools menu to close your private session.

 This action discards all of the data from your private session, and will restore your non-private browsing session, just like it was before entering the Private Browsing mode.

This action will restore your non-private browsing session, just like it was before entering the Private Browsing mode.

Now, as I mentioned at the top of this post, this feature is available in pre-release versions of Firefox 3.1 (what we geeks call nightly builds).  This feature will be included in Firefox 3.1 Beta 2 which will be released soon, so if you want to try it, you can give it a shot then.  And of course, it will appear in the final release of Firefox 3.1, so if you’re not the type who test beta software, you can wait until Firefox 3.1 is released.

Update:  As many people seem interested in knowing this, there is a way to make Firefox always start in Private Browsing mode.  Go to the about:config page, click I’ll be careful, I promise, type browser.privatebrowsing.autostart in the Filter text box, double click the entry to make its value true.  After doing this, the next time you start Firefox, it will start in private browsing mode automatically.  To turn this off, use the same steps to change the value of this preference to false.  There is a plan to provide an easier method to set this option in the final release of Firefox 3.1.

Tagged with: , , ,
Posted in Blog