IMPORTANT! Some of the information in this post is not correct. I will be updating it soon.
Updated: See section on serving the update.xml file
OK, now that we have MAR files, how do we get them to our users?
Setting Up a Firefox Update Server
A Firefox update server is actually not that complex of a setup. Basically a Firefox update server takes a URL that describes a particular Firefox version, and if there is an update available, it returns an XML file that identifies the location of the update. So let’s take a look at this URL.
If you are to go into about:config and search for app.update.url, you would see the following:
https://aus2.mozilla.org/update/1/%PRODUCT%/%VERSION%/%BUILD_ID%/%BUILD_TARGET%/%LOCALE%/%CHANNEL%/update.xml
When Firefox 2.0.0.3 looks for an upgrade (English on Windows), the URL looks like this:
https://aus2.mozilla.org/update/1/Firefox/2.0.0.3/2007030919/WINNT_x86-msvc/en-US/release/update.xml
Most of this URL is self explanatory. The only part we need to explain is BUILD_ID. The build ID of a Firefox is a unique identifer that conveys the exact date down to the hour when a build was created. For the build above, that data is March 9, 2007 at 7:00 PM. You can see the build ID for any Firefox build by type about: in the URL bar. Note that selecting Help->About does not display the complete build ID. If you build a custom version of Firefox, you can see the build ID by looking in the file mozilla/obj/config/nsBuildID.h. If you see a build ID of 0000000000 in this file, it means that you forgot to set MOZILLA_OFFICIAL and BUILD_OFFICIAL before building.
If we look at the URL that is served, it ends in update.xml. So what do these update.xml files look like? Here’s the update.xml to upgrade from Firefox 2.0.0.2 to Firefox 2.0.0.3. (https://aus2.mozilla.org/update/1/Firefox/2.0.0.2/2007021917/WINNT_x86-msvc/en-US/release/update.xml)
<?xml version="1.0"?>
<updates>
<update type="minor"
version="2.0.0.3"
extensionVersion="2.0.0.3"
buildID="2007030919"
detailsURL="http://en-US.www.mozilla.com/en-US/firefox/2.0.0.3/releasenotes/">
<patch type="complete"
URL="http://download.mozilla.org/?product=firefox-2.0.0.3-complete&os=win&lang=en-US"
hashFunction="SHA1"
hashValue="bc64376c13867b5524d71e87f7ad98e727f2d3f4"
size="7617299"/>
<patch type="partial"
URL="http://download.mozilla.org/?product=firefox-2.0.0.3-partial-2.0.0.2&os=win&lang=en-US"
hashFunction="SHA1"
hashValue="2555dcad94c9bc1c7327cb3699844f633888ea4a"
size="270514"/>
</update>
</updates>
Rather then go into a lot of detail here about this file, I’d rather point you to wiki.mozilla.org which has a great explanation of this file. (Incidentally, the wiki you can lots of other great information about the Software Update process) One thing you might be wondering is how to generate the hashValue. Microsoft has a tool available called FCIV that can be used to generate the hashes.
OK, we know the URL and we have the update.xml file, so how do we serve it to the browser?
Update: as Benjamin Smedberg pointed out, I am doing a lot of work for nothing. mod_rewrite can be used to accomplish this task. Create a file called “noupdate.xml” that contains <updates></updates>Then put this in a .htaccess file:
RewriteEngine on
RewriteCond %{REQUEST_FILENAME} !-f
RewriteRule ^(.*) noupdate.xml
What this says is if you find the file, serve it, if you don’t, serve the file that represents the empty update.
At first, it looks like we can just setup directories that correspond to the URL, but this won’t work since we need to send an XML file that looks like:
<updates> </updates>
If there are no updates available. So I’m going to use a simple PHP file to function as our update server. We’ll need to do some changes to our web server configuration as well. Note I am using Apache.
First go into httpd.conf and make sure that mod_rewrite is available. Then go into your main web directory and add or edit the file .htaccess with this:
RewriteEngine on RewriteRule ^/?update/(.*) /update.php/$1 [L]
What this rule says is whenever you see a URL that begins with “update” send it to update.php. The actual update.php file looks like this:
<?php
header("Content-type: text/xml");
$url_array=explode("/",$_SERVER["REQUEST_URI"]);
$noidea=$url_array[2];
$product=$url_array[3];
$version=$url_array[4];
$build_id=$url_array[5];
$build_target=$url_array[6];
$locale=$url_array[7];
$channel=$url_array[8];
$filename=$url_array[9];
$updatefile = "$noidea/$product/$version/$build_id/$build_target/$locale/$channel/$filename";
//echo "$updatefile";
if (file_exists($updatefile)) {
$handle = fopen($updatefile, "r");
$contents = fread($handle, filesize($updatefile));
echo "$contents";
fclose($handle);
} else {
echo '';
echo '';
}
?>
This PHP simply looks for the presence of an update.xml directory structure specified by the URL and if it is available, it returns it, otherwise it returns <updates></updates>
So how do we publish updates then? We simply create an update.xml file and place it in the appropriate subdirectory.
The last step is updating the browser to point to our new update URL. Your first thought might have been to simple update app.update.url in about:config, but that will not work. When app.update.url is queried by Firefox, it always looks for the “default preference” which means that even if a user changes the preference, it won’t be used. For testing purposes, you can add a new preference called “app.update.url.override” that will work, but when you go to deploy your updates, you should set app.update.url in an extension like the CCK. That will cause it to become a “default preference.”
One more installment to go. I’ll try to address some general deployment issues, and if you have questions (any questions), PLEASE let me know.
Could you move the MAR articles you’ve written over to DevMo, and cross-reference them from the XULRunner pages? Software update was a topic of some discussion at the Mountain View Dev Day, particularly the lack of docs on it. What you’ve written here sounds like it could apply to XULRunner-based apps, not just Firefox.
Fantastic offerings, thanks. One further thing that we considered for this process was how to deploy FF in a restricted environment. It wouldnt be hard to write a script to manually push the MAR files and perform a manual install during boot, ../firefox-update/updater ../firefox-update 0 (http://wiki.mozilla.org/Software_Update:Manually_Installing_a_MAR_file), dynamic checking by the script on the process is even possible by looking at a the update.status file (http://wiki.mozilla.org/Software_Update:Processing_Updates). Dont know how well this would work in non-interactive mode, given that updates to extensions are checked on the next launch.
How can you get updates to Firefox users in an enterprise where none of the users have admin privileges?
Eric, you are looking for some software deployment tool, which has a local agent running under some admin/system account. That would do the trick. But you would have to use the deployment tool to update software.
Mike, for me it is an ideal source for disabling auto-update via .htaccess/update.php and the CCK extension. Because updates will be rolled out over my deployment tool.
Hello, Mike
I need your advise.
I want setup my own update server for LAN there more 1200 users already installed various versions Mozilla Thunderbird 2.0.0.x / FireFox 2.0.x.x – 3.0.x as well, I already have a Apache web server.
The strategy with using update.xml + URL(REST) extremely inconvenient because
I must manually create all specific directories, subdirectories and update.xml’s files(?) for all bunch versions usable by my end-users. It’s realy terrible :\
Exist more loyal method create local update server?
You could certainly write some PHP or something to parse the URL and produce the update XML file…
Undeniably believe that that you said. Your favourite justification appeared
to be on the internet the easiest factor to take into
accout of. I say to you, I certainly get annoyed whilst
other people consider worries that they plainly do not recognize about.
You managed to hit the nail upon the highest and also outlined
out the whole thing with no need side-effects , folks
could take a signal. Will probably be back to get more.
Thank you
I was looking for a good blog on bowstrings and came across this one.
Funny where the internet can lead you. I ended up on this site
for over 20 minutes
Great post. I was checking constantly this weblog and I’m inspired!
Extremely useful info specifically the last section 🙂 I take care
of such information much. I used to be looking for this
particular information for a very long time. Thank you and best of luck.
Thаnks for finaⅼly writing about >Deploying Firefox 2 withіn thе Enterprise: Pаrt 5 | Mike’s
Musings <Liked it!
Hello,
it would be really appreciated if you could re-write this document for Firefox 60 and upper because it’s really difficult to find clear documentation on how to create a local update server for firefox (new ESR releases).
Thank you in advance.
Red.