Categories
Software Development

Apache, cgi-bins, and the Authorization header

I had a problem: Server A runs a web service, which requires users to authenticate using the standard HTTP authentication mechanism. Server B should have web pages that use AJAX to query A’s web services. Server B’s web pages also require authentication, using the same scheme, backend and database as server A. There are two problems:

  1. JavaScript web pages can only access web services/pages on the same server using XMLHttpRequest, for security reasons. Solution: Use a forwarding/proxy service. E.g. to access http://a.example.com/service from b.example.com add a service http://b.example.com/servicethat just forwards requests to the web service on A. This solution is quite straight forward.
  2. Since B uses the same authentication scheme as A we need to forward authentication information passed to B’s forwarding service on to A. Unfortunately this is not straight-forward, since the Apache HTTP Server provides no easy way to read the full authentication information passed to it via a cgi-bin. The only available information is the REMOTE_USER environment variable. This is not enough to construct a new Authenticationheader, though, since password information is stored encrypted in the account database.Finally I found a solution in the Zope 2 documentation. Apache’s mod_rewrite comes to the rescue. It allows you to read arbitrary HTTP headers and add arbitrary environment variables before executing a cgi-bin. The following recipe added to the appropriate .htaccess file adds a HTTP_AUTHORIZATION variable:
    RewriteEngine on
    RewriteBase /
    RewriteCond %{HTTP:Authorization}  ^(.*)
    RewriteRule ^(.*)$ $1 [e=HTTP_AUTHORIZATION:%1] 
    
Categories
Javascript

Loading Modules in JavaScript

One of the weaknesses of the JavaScript language is that it does not have the concept of “importing” or “including” other source files or modules. In client-side JavaScript as used in web browsers you have to include all JavaScript files you intend to use in the main HTML file like this:

<html>
    <head>
        <title>...</title>
        <script src="A.js"></script>
        <script src="B.js"></script>
        <script src="S.js"></script>
    </head>
    ...
</body>

In this case S.js is a page-specific JavaScript script that uses features from A.js and B.js.

The standard way to load other JavaScript files dynamically is to add a script element programmatically to the head section of the document, using DOM:

function include(filename) {
    var scriptTag = document.createElement("script");
    scriptTag.setAttribute("lang"), "javascript"));
    scriptTag.setAttribute("type"), "application/javascript"));
    scriptTag.setAttribute("src", filename);
    document.getElementsByTagName("head")[0].appendChild(scriptTag);
}

Unfortunately this approach has some problems as well: The include file is loaded “lazily”, i.e. the next time the JavaScript interpreter hands back control to the browser. (At least it is this way in Firefox.) If, for example, a file A.js defines a function func_a, the following will not work:

include("A.js");
func_a();

My first solution was to use a callback, invoked when the module has been loaded:

function include(filename, callback) {
    var scriptTag = createScriptTag(filename); // as above
    scriptTag.onreadystatechange = function() {
        if (scriptTag.readyState == "complete") {
            callback();
        }
    }
    scriptTag.onload = function() {
        callback(file);
    }
}

This solution uses the non-standard onload (Firefox) or onreadstatechange (IE) events. It is invoked like this:

include("A.js", function() {
    a_func();
});

This solution also has several problems: It is non-standard, it is ugly (though this can’t be helped, due to the asynchronous script loading), and including a module from a module still doesn’t work. To explain the last problem, I will use a script S.js which depends on the function a_func defined in A.js, which in turn depends on b_func defined in B.js. Now the code should look like this:

// S.js
include("A.js", function() {
    a_func();
});

// A.js
include("B.js", function() {
    a_func = function() {
    }
    a_func.prototype = new b_func();
});

// B.js
// ...

The problem is that the callback in S.js is not necessarily processed after the callback in A.js, leading to a_func being undefined.

The solution I have come up with is not particularily nice, but this can’t really be helped. Basically each module has to call a function when it has fully loaded, like this:

// A.js

include.module("B.js", function() {
    // ...

    include.moduleLoaded("A");
});

The main HTML file must load the include.js before loading any other module and modules should only be loaded via include.module. Also my implementation uses “real” module names, e.g. a.b.c instead of a/b/c.js. This allows me to expand the mechanism easily, for example to add a module search path.

Sample implementation

Categories
Software Development

Standards

Mark Pilgrim posted a great article about the problems of many committee standardization processes. Microformats use a different approach: Design for the common case first, think about corner cases only later.

Categories
Debian

I’m back to Debian

So, I finally found time to do Debian work again after a far too long abstinence. Unfortunately I didn’t manage to hand over my Debian stuff gracefully, but fortunately there were people having an eye on them. Jonas Smedegaard had an eye on the Netatalk package and released a security fix for it. The GNOME team, headed by Sebastien Bacher was taking care of ORBit.

The first thing I did was to hotfix some of my packages. Get out a new ORBit release and release a first version of Netatalk 2, a much requested upgrade. This new Netatalk version has many improvements and it’s good to finally have it in Debian, though there is still much work to do. Soon after releasing netatalk-2.0.2-1 I got a bug report concerning CJK support. This is something that needs to go in ASAP, but currently I don’t have the knowledge to review and apply the referenced patch. I’m out of the loop of Netatalk programming as well.

So, let’s have a look at my packages:

gnome-chess
This is currently seriously broken and badly needs a port to GNOME 2. AFAIR there is some unfinished work in GNOME CVS, which I have to look into. But at the moment this package is not high priority.
gnome-pim
Another GNOME 1 package. Before my hiatus I started to rewrite this package for GNOME 2 and there were grand plans for it. These plans are still there and I have continued the port. I hope to have a working pre-release of the new GNOME 2 package out soon, though there’s still lot of work to do, before this can be uploaded to Debian unstable.
gtk-doc
While I’m still listed as maintainer, I handed this package over to Loic Minier a few weeks back, and it seems to be in good hands.
libidl
Base package for ORBit 2. Just updated from 0.8.3-1 to 0.8.5-1,
though the upstream changes were only very minor. No open bugs, this package seems to do fine.
linc
Base package for ORBit 1. Obsolete, see below.
netatalk
As I wrote above I just upgrade this to Netatalk 2.0. While this
was quite a major change (I got rid of the unnecessary netatalk-dev package in the process), I don’t forsee any major problems. The upstream package is quite well tested at this point and included in many other distributions. But you never know …
orbit
ORBit 1 is an old, obsolete package from GNOME 1 days. It has a
few open bugs, but probably nothing that is worth fixing. Instead my energies should be focussed on porting all stuff that still depends on it over to GNOME 2 (see also above).
orbit2
Just upgraded to upstream version 2.12.2. This is a fairly stable,
slowly developed piece of software. Only one open bug in the Debian BTS and that is a wishlist item. This package is also doing fine and needs minimal maintenance.

Now I have to get up to snuff at what’s up with Debian. I completely missed the DPL elections and so I will not vote, since I have not enough information about what’s currently going on. Then there was the interesting proposal about dropping stable support for less-used architectures after sarge. Oh yes, speaking about sarge. It’s still not released. But then I didn’t have high hopes that it would be …