Artikel - 27.7.2005 - 14.8.2005

trac - Easy Software Project Management

trac is a web interface for Subversion repositories. However, it is not just the appropriate web interface - it also includes a wiki, a bug tracking system, a milestone management, and very comfortably created reports based on the bug tracking. And all of this in a very easy-to-install package - on Debian, an apt-get install trac is sufficient and then with trac-admin initenv a Trac instance can be created. It also looks quite appealing and the functions are very well integrated - links from the tickets to the wiki or links from changeset descriptions to the wiki or the bug tracking are easy to make and of course help enormously in managing software changes. Additionally, there is a nice timeline that documents and links changes to the system over time - among other things, also to a very comfortable changeset browser.

I have now thrown away all the handmade stuff for TooFpy and switched to trac. Just the possibility of assigning my ToDo list, which was previously managed in the source tree, to planned releases via tickets brings a lot of overview to the project.

Yep, anyone who has to manage a software project should definitely take a look at trac, because anyone who is not necessarily a control fetishist will certainly be happier with the rather open structure of trac than with some overengineered parts.

RBL Operator Again

After I already wrote about it in April, it's now also in the Heise Ticker: RFC-ignorant: All .de domains under suspicion of spam. The ignoramuses of RFC-Ignorant will certainly not change their minds, but perhaps now the one or other provider will remove this absurd block list from the mail configuration.

Privacy Update under OS X

In IRC, identd, and Privacy I complained that proxies with SOCKS support were rather thin on the ground - meanwhile, things have improved significantly. Because X-Chat Aqua is now in a state that can be described as very usable - after many years of using Snak, I have actually switched.

X-Chat Aqua supports SOCKS and thus allows direct use of tor. However, this is not SOCKS4A - therefore, DNS resolutions are still visible. Ideally, you simply enter the server's IP address, so no name resolution needs to occur.

With Jabber, things now look very good with PSI - PSI is very usable under OS X and the display problems of older versions have also been fixed. And PSI also works with tor.

Browsing over tor was already possible before, but with the current Mac OS X Builds of tor, it is also very easy to install. Tip: I created my own network configuration, with which I can easily change the proxy settings. With this, I can then simply turn Privoxy+Tor on and off in the Apple menu as needed. Of course, this only works with browsers that get their proxy settings from the system settings.

Using ssh over tor is easily done with the ProxyCommand stuff. Instructions are in the Torify HowTo. Many of the tips mentioned there also work under OS X, as there is a normal Unix underneath.

On the Bavaria Fuss

Nothing comes to mind other than a hearty: Keep it up, Mr. Stoiber! - it's true, the Left Party couldn't wish for a better election helper than the raging dwarf from the backwoods. Okay, his outbursts lack a certain degree of appropriateness - it's quite annoying when people in Bavaria are supposedly so terribly smart, but the head of state once again doesn't understand what democracy means. Well, whatever happens, Mr. Stoiber, one thing is certain: we will not be governed by Bavaria. And the way you are currently dismantling Mrs. Merkel, suddenly everything is possible again for the SPD. Thanks to you and your colleague Schönbohm, who with their absurd statements have probably mobilized more East German voters than Gysi and Lafontaine together ...

Mac OS X Intel hacked to run on standard PCs

It's quite bitter when OS X Intel is already hacked before it's actually available:

MacBidouille reports that the Apple Developer kit version of Mac OS X x86, released to developers in early June, has been "hacked" to work with a PC notebook. The report includes a video showing Mac OS X x86 booting natively on a Pentium M 735-based notebook.

And this despite TPM and similar tricks. Maybe Apple should switch back to PowerPC after all, which is not more secure, but at least there's no alternative hardware at bargain prices like with Intel.

RIP last.fm

In das Netzbuch: last.fm verhärmt sich selbst Ralf describes how last.fm is leaving reality. I will also have to say goodbye to my earlier recommendation - there are already enough proprietary streaming clients, we don't need another one - especially not if it doesn't even work properly. Too bad - it was a nice way to discover new and interesting music. But not like this.

SCO-Patent-Fallout?

Speculation is rife that a lawsuit by an eFax company against competitors for using Asterisk could be related to SCO and all the nonsense surrounding it:

Now, Groklaw is speculating about the extent to which the move could be a general patent attack on free software. The reason for this is a close connection between the SCO Group and j2. Among the supporters of the software company, which has been in a heated dispute over intellectual property in Linux components, particularly with IBM, for a long time, is the investment firm Krevlin Advisors. It is also a major shareholder in j2.

But even if there's nothing to the rumors, the whole thing will certainly be idiotic and annoying again - and yet another proof that software patents and business method patents are utter nonsense. In any case, Asterisk (essentially a telephone system implemented in software) could soon become another battleground - if only because it may appear as a threat to one or another manufacturer of smaller telephone systems. And the market for telephone systems is, after all, characterized by very strange sales strategies and even stranger contractual situations (not without reason, telephone system maintenance contracts are occasionally declared invalid for violating good morals).

Sooo cool!

BlackDog is a PowerPC computer with 64 MB of memory and a 512 MB flash disc in a mini case that you can plug into any PC with Windows or Linux via the USB port. The PowerPC processor then takes over the keyboard, mouse, and screen, and starts its Debian Linux, whose desktop you can then see on the PC.

The device runs solely on USB power and also has additional biometric access control via fingerprint. Wow. A nice little hacker kit for on the go, you just need to find a host computer.

And it is completely open and hackable in terms of architecture - there is even a hacking competition to develop interesting applications for it. Although I already know what I would put on it - all the necessary network tools. I think I need to motivate the boss at the company to take a closer look at what you can do with such a device. I haven't had such a strong desire to have something for a long time.

Information about the Canon EOS 5D has surfaced

The rumors about the Canon EOS 5D already sound quite interesting - a full-frame sensor camera for 3500 could certainly tempt me. The previous contenders in the full-frame sector were just outrageously expensive (yes, the 5D is too, but the utopia has come a bit closer).

Oracle Cluster File System 2 for Linux

The Oracle Cluster File System could already be a nice alternative to GFS and Coda - at least if this really happens:

The Linux developer responsible for the Linux Kernel 2.6, Andrew Morton, wants to include the Oracle Cluster File System version 2 in the official Linux Kernel as soon as possible. Linux 2.6.14 could already contain OCFS 2 and would then be the first cluster component in the official Linux Kernel.

The previous cluster file systems suffer from the lack of integration - most of the time you can't use them in every kernel version. What is interesting to me is how independent the nodes really are and whether there is also a single point of failure in the Oracle Cluster File System, as there is e.g. the Locking daemon in OpenGFS. So far, we have not been very successful in evaluating cluster file systems in the company, actually they were all somehow stupid ...

The Hidden Boot Code of the Xbox

In The Hidden Boot Code of the Xbox the X-Box-Linux programmers explain how the security code of the X-Box is structured and how Microsoft built in 3 errors in 512 bytes of code. Lots of kindergarten security mistakes. - as Bruce Schneier calls it.

Also nice is the conclusion of the article:

So with the first version of the MCPX, Microsoft was too naive and apparently did not understand basic security concepts. After they had learnt their lesson, they designed a pretty good system with the second version of the MCPX - but the implementation still contained at least three security holes (Visor, MIST, TEA). They were too fast releasing a new version of the MCPX, spending a lot of money in trashing tons of already manufactured MCPX chips and manufacturing updated ones, apparently without any further code audit which should have revealed the security holes.

512 bytes is a very small amount of code (it fits on a single sheet of paper!), compared to the megabytes of code contained in software like Windows, Internet Explorer or Internet Information Server. Three bugs within these 512 bytes compromised the security completely - a bunch of hackers found them within days after first looking at the code. Why hasn't Microsoft Corp. been able to do the same? Why?

Exactly. Why doesn't Microsoft get this right? Why does Microsoft repeatedly fail so badly at security? And don't give me the silly excuse that the bugs at Microsoft are found so quickly because it has so many users - this is basic knowledge that would be required. This is just sloppy.

And now, Mr. McBride?

Shit hits Fan for SCO:

A: There was a release of SCO LinuxWare release 7.1.2 that included the Linux kernel personality and SCO Linux-release 7.1.3 included the Linux kernel personality. At first when it first shipped it did include the Linux kernel packages which were subsequently removed.

I find this somehow fitting when SCO is caught using the Linux kernel - which is under GPL - in their products at least temporarily and delivered with them. Could be one reason why they are now trying to denounce the GPL as un-American and unconstitutional.

Yep. Makes sense.

Not Intelligent Design, but rather the Google-Bombing of the expression naturally.

EU Commission acting alone again

This time with a direct attack on common sense and the bio-system: EU Commission approves import of genetically modified corn:

Controversial genetically modified corn may now be imported into EU countries as animal feed. The EU Commission made this decision unilaterally.

I'll repeat: I am actually pro-EU and see only a functioning European Union as a viable long-term path for our region. But not with an EU Commission that makes arbitrary decisions that go against common sense. And all of this only for the financial benefit of a non-European company whose sole aim is to crack the European market and dominate it just like other markets.

Hand Darl McBride the Frog Pills

Here's the translated Markdown body:

now he's really going off the deep end:

In detail, McBride lists ten points that speak for SCO and against Linux. Thus, OpenServer is supposedly much cheaper than Linux systems that work with hidden annual licenses, has a superior kernel, and offers significantly higher security than Linux systems where security gaps remain open for weeks. McBride repeatedly emphasizes that his company owns Unix and, for this reason, enjoys greater trust among customers. Furthermore, SCO, as the owner, ensures that there are no splinter groups of incompatible system variants.

Rarely seen such a compact block of bullshit

Mathematical Ignorance

It's almost modern to talk about how bad you were at math (I wasn't, I was very good at math - and yes, I really enjoyed math), but when you read James Gosling asking questions about sine/cosine and the meaning of the period definition with 2*Pi, you really scratch your head. Slava Prestov at least sees in this the explanation why most programmers ask really stupid questions about the simplest mathematical problems, when even the big shots in the industry don't understand basic trigonometry ...

You never stop learning

I thought I knew most of the tricks of ssh. But I stumbled upon one that is banal and simple, but was not known to me: the ProxyCommand option. With this option, you can define a tunnel for a specified host that is established before the actual connection is made. With the program nc (Netcat) on the computer one before the target system, you can tunnel through a chain of firewalls wonderfully, especially when working with Auth-Forwarding. Simply build a section similar to this into the .ssh/config:


 Host safe
 Protocol 2
 User me
 HostName 192.168.0.42
 ProxyCommand ssh door nc -q 0 safe 22

Here, when ssh safe is used, a connection to the computer door is established internally via ssh door, and then a Netcat connection to the ssh daemon on the actual target computer safe is created there. This can also be used wonderfully over several ssh hops to transport files directly between two systems through a chain of firewalls. Ssh is just genius, if it didn't exist, you would have to invent it.

(in my case, I needed this for darcs - it can only push repositories over ssh)

on the way to media monoculture

Springer is taking over ProSiebenSat.1 - and will likely soon launch their neoliberal opinion campaign multimedially and then send their trash on all channels. A democracy needs an independent, strong press - but one that does not pursue its own political agenda. Therefore, we can probably say goodnight to another piece of democracy when a corporation like Springer will soon bridge the media gap.

Environmental Clearance Sale in D-Village

It was to be expected, the state government presents environmental policy goals - and what does that bring:

Environmental protection will also have "high priority" in the new NRW state government - promises Environment Minister Eckhard Uhlenberg. But he wants to reduce the influence of nature conservation associations.

And then there are various other niceties, in principle a dismantling of what has always distinguished NRW's environmental policy from the rather weak stance of the federal government (and probably a merit of Mrs. Höhn - not that anyone believes the SPD in NRW has been particularly environmentally conscious).

Store passwords as hashes - safe?

Not quite new (it was new last summer, but I somehow missed it, the underlying paper is even two years old), but still interesting: Project RainbowCrack is a project aimed at creating tools for faster cracking of hashes. Hashes can normally only be resolved through brute force - supported by algorithmic weaknesses (as recently found in MD5 and SHA1). However, there is an approach to create the more complex calculations that arise during the brute-force process (i.e. essentially algorithmic sub-steps) in advance - for example, if you only intend to crack passwords with a maximum number of characters.

Of course, this does not come for free: you trade computing time for storage space. Tables for cracking up to 14-digit Windows passwords occupy a casual 64 GiB of memory. The practical relevance of the approach and the tools may become obvious from this quote:

Some ready to work lanmanager and md5 tables are demonstrated in Rainbow Table section. One interesting stuff among them is the lm #6 table, with which we can break any windows password up to 14 characters in a few minutes.

There is also a web interface to a distributed computing cluster for Project RainbowCrack, through which you can send MD5 hashes to an MD5 cracker, which then - if it is a string with a maximum of 8 characters - spits out the plain text. And this thing is constantly building more Rainbow Tables, making cracking faster and faster.

Just as a warning for those who think that a simple MD5 hash (or ultimately almost any hash) on the password would be sufficient. Unix systems typically use salted hashes - the password is extended by a plain text and then the hash is formed together with it. This extends the password in principle, even if the extension is of course not secret - for the computing time or the table size it doesn't matter, the passwords are simply longer and thus harder to crack. But it is also only a matter of space until they are not secure.

Better are passphrases instead of passwords - just simply normally long sentences. On the one hand, you can often remember these better (many people cannot remember a phone number, but can quote lines from poems) and on the other hand, they are simply longer (and especially flexibly long), so that Rainbow Tables as an attack method are out of the question. The algorithmic weaknesses of MD5 and SHA1 remain, of course.

Shoot-to-Kill Directives - and the World Becomes a First-Person Shooter

Bruce Schneier on Shoot-to-Kill and specifically a proposal by the International Association of Chiefs of Police. Translated from the proposal:

... such a person exhibits "various unusual behaviors" such as wearing a heavy coat or thick jacket in warm weather, carrying a suitcase, shoulder bag, or backpack with bulges or visible wires. The person shows nervousness, avoids eye contact, or sweats profusely. There may be chemical residues on the clothing or hands. The person may be mumbling prayers or rocking back and forth.

Note what is to be done with such persons is clear to the Chiefs of Police: shoot them in the head. Final killing shot. And of course, no further reason is needed for this:

... the threat to the officer does not need to be immediate, as taught in normal procedure. Officers do not need to wait until a person suspected of being an attacker makes a move, as would be necessary in the normal use of firearms. An officer only needs to have a reasonable suspicion that the suspect could detonate a bomb.

Bruce Schneier rightly asks if we would really feel safe if such a directive were implemented. Every pickpocket shows enough characteristics to be shot down at some point if such a dehumanizing directive were actually implemented.

We know how quickly dehumanizing ideas suddenly make it onto the agenda here ...

Django, Apache and FCGI

In Django, lighttpd and FCGI, second take I described a method how to run Django with FCGI behind a lighttpd installation. I did run the Django FCGIs as standalone servers so that you can run them under different users than the webserver. This document will give you the needed information to do the same with Apache 1.3.

Update: I maintain my descriptions now in my trac system. See the Apache+FCGI description for Django.

Update: I changed from using unix sockets to using tcp sockets in the description. The reason is that unix sockets need write access from both processes - webserver and FCGI server - and that's a bit hard to setup right, sometimes. tcp sockets are only a tad bit slower but much easier to set up.

First the main question some might ask: why Apache 1.3? The answer is simple: many people still have Apache 1.3 running as their main server and can't easily upgrade to Apache 2.0 - for example if they run large codebases in mod perl or mod python they will run into troubles with migrating because Apache 2.0 will require mod perl2 or mod python2 and both are not fully compatible with older versions. And even though lighttpd is a fantastic webserver, if you already run Apache 1.3 there might just not be the need for another webserver.

So what do you need - besides the python and django stuff - for Apache 1.3 with FastCGI? Just the mod rewrite module and mod fastcgi module installed, that's all. Both should come with your systems distribution. You will still need all the python stuff I listed in the lighttpd article.

mod_fastcgi is a bit quirky in it's installation, I had to play a bit around with it. There are a few pitfalls I can think of:

  • the specification of the socket can't be an absolute path but must be a relative path with respect to the FastCgiIpcDir
  • the specification of the FCGI itself (even though it's purely virtual) must be in a fully qualified form with respect to the document root you want to use. If you use a relative path, it will be relative to the document root of the default virtual host - and that's most surely not the document root you will use if you want to set up a virtual host with the FCGI.
  • the FCGI itself can't be defined within a virtual host - it must be defined in the main server config. That's where the relative addressing problem comes into play.
  • the socket file must be both readable and writeable by the FCGI user and the Apache user. Usually you do this by changing the socket file to group writeable and changing the group of that socket file to a group where both the user and the apache are members of.

Now here is the config snippet you have to add to your httpd.conf. I use the same directories as with the lighttpd sample, you most surely will have to adapt that to your situation.


 FastCgiExternalServer /home/gb/work/myproject/publichtml/admin.fcgi -host 127.0.0.1:8000
FastCgiExternalServer /home/gb/work/myproject/publichtml/main.fcgi -host 127.0.0.1:8001

 <VirtualHost *> ServerAdmin gb@bofh.ms
 Servername www.example.com
 ErrorLog /home/gb/work/myproject/logs/django-error.log
 CustomLog /home/gb/work/myproject/logs/django-access.log combined
 DocumentRoot /home/gb/work/myproject/public_html
 RewriteEngine On
 RewriteRule ^(/admin/.)$ /admin.fcgi$1 [L]
 RewriteRule ^(/main/.)$ /main.fcgi$1 [L]
 </VirtualHost> ```

You have to allow the webserver write access to the logs directory, so you might want to use a different location for them - possibly in `/var/log/apache/ `or whereever your apache puts it's logs. The FastCgiExternalServer directives must be outside of the virtual host definitions, but must point to files within the virtual hosts document root. But those files needn't (and probably shouldn't) exist in the filesystem, they are purely virtual. The given setup reflects the setup I did for the lighttpd scenario.

Now restart your apache, start your django-fcgi.py and you should be able to access your django application. Keep in mind to copy the admin_media files over to the document root, otherwise your admin will look very ugly.

django-fcgi.py --settings=myproject.settings.main --host=127.0.0.1 --port=8000 --daemon django-fcgi.py --settings=myproject.settings.admin --host=127.0.0.1 --port=8001 --daemon


Have fun.

EU Brainless about Copyright Infringements

What nonsense. If the proposal goes through, using open-source software will become risky:

A new draft law by the European Commission aims to allow lawsuits against users in case of suspected copyright infringement in software. In addition to the perpetrator, companies that feel safe due to their licenses would also come under fire. This was reported by the British trade magazine 'ZDNet UK'.

Given the current impression of the SCO case, it should be clear to everyone that such an idea is complete nonsense - because that's exactly what SCO wanted to do, to extort all Linux users. There are hardly any ideas stupid enough that they couldn't occur to a politician ...

Geocaching in Münsterland

Now that I have a Garmin Geko 201, I naturally have to take a look at the information about Geocaching. Does anyone have a good link to Geocaching activists in Münster and the surrounding area? That would be something for our upcoming vacation. Jutta always complains that she doesn't know the Münsterland well enough, so checking out Geocaches would be the ideal method to explore the area.

As a first starting point, I will take a look at the entries on geocaching.de for Ruhrpott and Emsland - we are neither Ruhrpott nor Emsland, but close enough to be included in both.

In addition, I now have a good reason to tell Jutta why I bought the thing.

And when I look at instructions like those for Vaders Stein, it will even be perfect for Jutta - she loves puzzle games. Hey, it could easily become a new hobby ...

Again something new with Django

There's always news, but this time there's a very interesting feature again: the inspectdb command delivers all the tables and fields from a PostgreSQL database in the format of a Python data model. Additionally, foreign keys are also found if they are stored in the database. Very practical if you need to build an interface for an existing database, you save a lot of typing work.

Social Networking

Well, I've also registered in one of these great social (in this case rather business-social) networks, specifically the O'Reilly Connection. Don't want to be considered bitter and aged.

Anyone who manages to find me there can define a connection to me. And laugh at my silly photo ...

But patents are sooo great ...

... but only when your own central bank becomes the target of a patent infringement lawsuit: European Central Bank sued for patent infringement. Will this perhaps wake people up at the EU Council? Oh, forget it, they won't wake up in this life, then they would have to recognize their own corruption ...

Coroutines for Python

Philip J. Eby has provided a patch for the implementation of PEP 342. This means that the chances of Python having coroutines in the future are very good.

And that, in turn, means that Python will get a - albeit primitive - form of continuations. Now all that's missing is for something like statesaver to be integrated into Python - for multishot continuations (ok, first just copyable coroutines, but that would be a start at least).

All of this, of course, just to finally be able to work with continuations in web frameworks. Ok, it's already possible with CherryFlow, but it would be nice if all of this would make it into mainstream Python.

Hell freezes over - a second time

First Intel processors and now more than one mouse button. And even something similar to a scroll wheel. Shocking.

The Illusive setdefaultencoding

Ian Bicking mentioned a nice trick in his article about setdefaultencoding: simply reload the sys module with reload(sys) to make setdefaultencoding available.

setdefaultencoding is used to set the default encoding for bytestrings. Normally, this is ASCII, but it can be changed to iso-8859-1 or utf-8 - if you have setdefaultencoding at all. Unfortunately, it is deleted when the Python runtime environment starts - because the Python developers want to patronize the users again.

reload(sys) is of course something that does not necessarily inspire confidence - sys is after all not an unimportant module. But in my experiments it has worked so far and it definitely helps with the whole Unicode problem if you can give your programs a different encoding as standard.

It would be nicer if setdefaultencoding were not deleted in the standard distribution. Of course, this can also be achieved by patching site.py, but that is not better than reloading sys ...

(Un)trusted platform Apple?

Since it's currently fashionable to explain that one switched when Apple uses TPA - or whatever it might be called in the future: first wait and see. See what Apple does and how - there are always rumors beforehand.

If TPA is actually included: Linux can also be a usable system, even if the interfaces are quite sick (although current XFCE versions don't look that bad) and if there is no more PPC in Apple hardware and you put Linux on it: you can also buy your notebook from IBM. They have nice devices that also work very well under Linux.

And last but not least: just because new Apple hardware is different, it doesn't change the already purchased hardware - and Apple-typically, this usually lasts a few years longer. And under Linux, some Macs even run faster than under OS X.

Where Cease and Desist Notices and Anticipatory Obedience Can Lead

Just what the FFII noticed: Nutzwerk shut down FFII.org (a bit more info as usual at Heise).

Although the corresponding IP address was consistently reachable, the DNS provider registered as the technical contact for the domain FFII.org complied with Nutzwerk's request and shut down the domain FFII.org on the previous Friday afternoon. The name resolution of FFII.org and corresponding subdomains did not work temporarily. After an intervention by the FFII, the DNS provider reactivated the domain that same evening and wants to ask Nutzwerk for a clarification of the demand, according to FFII board member Hartmut Pilch to Golem.de.

A real dilemma: service providers want to protect themselves and unfortunately the Telemedia Act makes life difficult for these service providers: if they are notified of content that constitutes a legal violation, they must remove this content immediately. But how can one assess whether content constitutes a legal violation? Especially when it comes to things like at Nutzwerk - where critical reporting by the company is defined as a legal violation?

In the end, this gives companies a means of censorship without giving service providers (and of course the website operators themselves!) reasonable means of defense. How, for example, is a smaller provider supposed to protect itself from cease-and-desist letters with absurd claim amounts - as the music industry particularly likes to use? Legal protection insurance doesn't help here.

No wonder that some providers see preemptive obedience as the right strategy in such cases - they lose at most the customer they shut down, perhaps a bit of negative press, but taking on a fight against a company with exaggerated ideas, they can't win much.

If you then sit on the board of a privately operated provider like me, you start to wonder what the actual goal of these legislative changes in the context of the Telemedia Act really was ...

Effects of Genetically Modified Rapeseed and Co.

At Isotopp I found a pointer to information about the British evaluation project on genetically modified seeds. Shocking, what effects this has, for example, on related wild plants and what this will mean for us in the long run. But of course, it's all sooo safe and sooo important for us - it's really just about the revenue for the genetic engineering companies, not about what consumers really want.

But of course, every critic of genetically modified seeds is dismissed as a crank by the economy and its henchmen (such as Clement and other politicians).

Dave's new OPML editor with blog

I'm currently playing around with Dave Winer's OPML Editor, which he now uses for his blog. It looks quite fun and has a lot of features. My OPML Blog has collected some of the insights I've gained from it. I certainly won't switch over just like that - that would be Quark, which is not necessarily my target software. But it's fun to play with something completely different again.

Unfortunately, the OPML Editor has inherited some of the ailments of Radio Userland and Frontier, especially the handling of umlauts is not really smooth (I would like to have consistent UTF-8 support finally) and the runtime behavior is better than in Radio, but it still occasionally consumes too much CPU.

The concept of rendered outlines does have a certain charm. However, many parts of the rendering are not really accessible to normal users - you can edit the ancient table layout and make something else out of it, but the OPMLs are implemented with the internal OPML renderer and the HTML fragments are not so easy to change - and thus, for example, changing the language is quite cumbersome, as is the complete removal of layout tables.

More will certainly appear on the OPML blog from time to time, here I will write at most a few conclusions.

HEW Cyclassics 2005

A really nice race - it's always amazing how even a nearly quarter-hour lead isn't enough to bring home a victory in this race. It's also always amazing how the commentators every time say that the main field starts too late - by now they should know.

The Quickstep action was great - taking the victory and the podium positions away from the Fassa Bortolo guys after their sprint build-up is really super. Even if I would of course have preferred to see Zabel up front.

Merkelnix is also cramping

Just so no one thinks only the SPD has brainless slogans to shout into the world: "Make work possible in Germany again" is the reason why they want to increase the value-added tax:

Union Chancellor candidate Angela Merkel defended the planned increase in value-added tax by the CDU and CSU. The Union wants to achieve the goal of reducing labor costs with this, she said in an interview with "Bericht aus Berlin". It is about "making work possible in Germany again and thus enabling social security," the CDU chairwoman continued.

Sorry, but how incredibly stupid is that? Social security through an increase in value-added tax, which hits the hardest those who cannot further reduce their consumption because it already only consists of staple foods and other expenses necessary for survival?

Software Patents - Commentary in the NY Times

The NY Times asks why Bill Gates wants 3,000 new patents and finds a massive siege of the patent office with mountains of software patents, which are often just trivial patents (like the cited patent for adding/removing spaces in documents). The commentator makes a demand in the comment (after considering whether Microsoft should not simply have all the patents it already has revoked):

Perhaps that is going too far. Certainly, we should go through the lot and reinstate the occasional invention embodied in hardware. But patent protection for software? No. Not for Microsoft, nor for anyone else.

And this from the country that has had software patents for a long time and that is repeatedly cited by software patent proponents in the EU as a reason for a necessary worldwide harmonization.

No, software patents are also not popular there and not really useful. Dan Bricklin, known to some as the father of VisiCalc, also thinks so:

Mr. Bricklin, who has started several software companies and defensively acquired a few software patents along the way, says he, too, would cheer the abolition of software patents, which he sees as the bane of small software companies. "The number of patents you can run into with a small product is immense," he said. As for Microsoft's aggressive accumulation in recent years, he asked, "Isn't Microsoft the poster child of success without software patents?"

And why is Microsoft doing this now? The manager responsible gives a reason, as only a business administrator could come up with, it's that stupid:

"We realized we were underpatenting," Mr. Smith explained. The company had seen studies showing that other information technology companies filed about two patents for every $1 million spent on research and development. If Microsoft was spending $6 billion to $7.5 billion annually on its R&D, it would need to file at least 3,000 applications to keep up with the Joneses.

Ok, the idea of patent applications alone being oriented towards numbers from the industry is absurd, but how stupid do you have to be to draw a connection between the number of patents and revenue in the field of research and development?

The NY Times also draws a parallel to the pharmaceutical industry, which - at least according to its own statements - is happy to get a patent for a drug when it invests 20 million in research (which is already critical enough, as can be seen in the fight against AIDS in Africa).

And the fallout is also well summarized in the NY Times:

Last year at a public briefing, Kevin R. Johnson, Microsoft's group vice president for worldwide sales, spoke pointedly of "intellectual property risk" that corporate customers should take into account when comparing software vendors. On the one side, Microsoft has an overflowing war chest and bulging patent portfolio, ready to fight - or cross-license with - any plaintiff who accuses it of patent infringement. On the other are the open-source developers, without war chest, without patents of their own to use as bargaining chips and without the financial means to indemnify their customers.

The question of what Jefferson (the founder of the US patent system) would say about what is now being patented is quite justified. In his sense - which was actually more about protecting real inventive genius from exploitation by corporations - this is definitely not the case.

Election Campaign, Election Agony ...

Münte on the Roll: Linkspartei "politically and legally absurd". I have the impression, however, that he would help the SPD more by giving them a program that appeals to ordinary citizens again, instead of simply stirring up fear of the left and spreading defamation (sorry, but the combination of PDS and WASG in the open list may be strange, but legally flawless - claiming otherwise is simply defamation).

If the SPD cannot achieve more in the election campaign than just to blow the horn of the Union parties against the alleged danger from the left, the SPD will simply put itself out of the political game - with such nonsense, you don't win an election. If the SPD is nothing more than a union with a red tie, it can stay away from me ...

Writing a Simple Filesystem Browser with Django

Dieser Artikel ist mal wieder in Englisch, da er auch für die Leute auf #django interessant sein könnte. This posting will show how to build a very simple filesystem browser with Django. This filesystem browser behaves mostly like a static webserver that allows directory traversal. The only speciality is that you can use the Django admin to define filesystems that are mounted into the namespace of the Django server. This is just to demonstrate how a Django application can make use of different data sources besides the database, it's not really meant to serve static content (although with added authentication it could come in quite handy for restricted static content!).

Even though the application makes very simple security checks on passed in filenames, you shouldn't run this on a public server - I didn't do any security tests and there might be buttloads of bad things in there that might expose your private data to the world. You have been warned. We start as usual by creating the filesystems application with the django-admin.py startapp filesystems command. Just do it like you did with your polls application in the first tutorial. Just as an orientation, this is how the myproject directory does look like on my development machine:


.
|-- apps
| |-- filesystems
| | |-- models
| | |-- urls
| | `-- views
| `-- polls
| |-- models
| |-- urls
| `-- views
|-- public_html
| `-- admin_media
| |-- css
| |-- img
| | `-- admin
| `-- js
| `-- admin
|-- settings
| `-- urls
`-- templates
 `-- filesystems

After creating the infrastructure, we start by building the model. The model for the filesystems is very simple - just a name for the filesystem and a path where the files are actually stored. So here it is, the model:


 from django.core import meta

class Filesystem(meta.Model):

fields = ( meta.CharField('name', 'Name', maxlength=64), meta.CharField('path', 'Path', maxlength=200), )

def repr(self): return self.name

def get_absolute_url(self): return '/files/%s/' % self.name

def isdir(self, path): import os p = os.path.realpath(os.path.join(self.path, path)) if not p.startswith(self.path): raise ValueError(path) return os.path.isdir(p)

def files(self, path=''): import os import mimetypes p = os.path.realpath(os.path.join(self.path, path)) if not p.startswith(self.path): raise ValueError(path) l = os.listdir(p) if path: l.insert(0, '..') return [(f, os.path.isdir(os.path.join(p, f)), mimetypes.guess_type(f)[0] or 'application/octetstream') for f in l]

def file(self, path): import os import mimetypes p = os.path.realpath(os.path.join(self.path, path)) if p.startswith(self.path): (t, e) = mimetypes.guess_type(p) return (p, t or 'application/octetstream') else: raise ValueError(path)

admin = meta.Admin( fields = ( (None, {'fields': ('name', 'path')}), ), list_display = ('name', 'path'), search_fields = ('name', 'path'), ordering = ['name'], )


As you can see, the model and the admin is rather boring. What is interesting, though, are the additional methods isdir , files and file . isdir just checks wether a given path below the filesystem is a directory or not. files returns the files of the given path below the filesystems base path and file returns the real pathname and the mimetype of a given file below the filesystems base path. All three methods check for validity of the passed in path - if the resulting path isn't below the filesystems base path, a ValueError is thrown. This is to make sure that nobody uses .. in the path name to break out of the defined filesystem area. So the model includes special methods you can use to access the filesystems content itself, without caring for how to do that in your views. It's job of the model to know about such stuff.

The next part of your little filesystem browser will be the URL configuration. It's rather simple, it consists of the line in settings/urls/main.py and the myproject.apps.filesystems.urls.filesystems module. Fist the line in the main urls module:


 from django.conf.urls.defaults import *

urlpatterns = patterns('',
 (r'^files/', include('myproject.apps.filesystems.urls.filesystems')),
 )

Next the filesystems own urls module:


 from django.conf.urls.defaults import *

urlpatterns = patterns('myproject.apps.filesystems.views.filesystems',
 (r'^$', 'index'),
 (r'^(?P<filesystem_name>.*?)/(?P<path>.*)$', 'directory'),
 )

You can now add the application to the main settings file so you don't forget to do that later on. Just look for the INSTALLED_APPS setting and add the filebrowser:


 INSTALLED_APPS = (
 'myproject.apps.polls',
 'myproject.apps.filesystems'
 )

One part is still missing: the views. This module defines the externally reachable methods we defined in the urlmapper. So we need two methods, index and directory . The second one actually doesn't work only with directories - if it get's passed a file, it just presents the contents of that file with the right mimetype. The view makes use of the methods defined in the model to access actual filesystem contents. Here is the source for the views module:


 from django.core import template_loader
 from django.core.extensions import DjangoContext as Context
 from django.core.exceptions import Http404
 from django.models.filesystems import filesystems
 from django.utils.httpwrappers import HttpResponse

def index(request):
 fslist = filesystems.getlist(orderby=['name'])
 t = templateloader.gettemplate('filesystems/index')
 c = Context(request, {
 'fslist': fslist,
 })
 return HttpResponse(t.render(c))

def directory(request, filesystem_name, path):
 import os
 try:
 fs = filesystems.getobject(name exact=filesystemname)
 if fs.isdir(path):
 files = fs.files(path)
 tpl = templateloader.gettemplate('filesystems/directory')
 c = Context(request, {
 'dlist': [f for (f, d, t) in files if d],
 'flist': [{'name':f, 'type':t} for (f, d, t) in files if not d],
 'path': path,
 'fs': fs,
 })
 return HttpResponse(tpl.render(c))
 else:
 (f, mimetype) = fs.file(path)
 return HttpResponse(open(f).read(), mimetype=mimetype)
 except ValueError: raise Http404
 except filesystems.FilesystemDoesNotExist: raise Http404
 except IOError: raise Http404

See how the elements of the directory pattern are passed in as parameters to the directory method - the filesystem name is used to find the right filesystem and the path is used to access content below that filesystems base path. Mimetypes are discovered using the mimetypes module from the python distribution, btw.

The last part of our little tutorial are the templates. We need two templates - one for the index of the defined filesystems and one for the content of some path below some filesystem. We don't need a template for the files content - file content is delivered raw. So first the main index template:


{% if fslist %}
<h1>defined filesystems</h1> <ul> {% for fs in fslist %}
<li><a href="{{ fs.get_absolute_url }}">{{ fs.name }}</a></li> {% endfor %}
</ul> {% else %}
<p>Sorry, no filesystems have been defined.</p> {% endif %}

The other template is the directory template that shows contents of a path below the filesystems base path:


 {% if dlist or flist %}
 <h1>Files in //{{ fs.name }}/{{ path }}</h1> <ul> {% for d in dlist %}
 <li> <a href="{{ fs.getabsoluteurl }}{{ path }}{{ d }}/" >{{ d }}</a> </li> {% endfor %}
 {% for f in flist %}
 <li> <a href="{{ fs.getabsoluteurl }}{{ path }}{{ f.name }}" >{{ f.name }}</a> ({{ f.type }})</li> {% endfor %}
 </ul> {% endif %}

Both templates need to be stored somewhere in your TEMPLATE PATH. I have set up a path in the TEMPLATE PATH with the name of the application: filesystems . In there I stored the files as index.html and directory.html . Of course you normally would build a base template for the site and extend that in your normal templates. And you would add a 404.html to handle 404 errors. But that's left as an exercise to the reader.After you start up your development server for your admin (don't forget to set DJANGO SETTINGS MODULE accordingly!) you can add a filesystem to your database (you did do django-admin.py install filesystems sometime in between? No? Do it now, before you start your server). Now stop the admin server, change your DJANGO SETTINGS MODULE and start the main settings server. Now you can surf to http://localhost:8000/files/(at least if you did set up your URLs and server like I do) and browse the files in your filesystem. That's it. Wasn't very complicated, right? Django is really simple to use

Training as a low-wage sector

What lies behind the DIHK's demand for halving the basic apprentice salary and flexibilizing working hours becomes clear when you look at quotes from the DIHK chairman:

"My proposal is to introduce a nationwide basic remuneration of 270 euros," he told the newspaper "Die Welt". He justified his initiative by saying that this would allow more apprenticeships to be financed. "An apprenticeship remuneration of up to 800 euros is simply too high for many businesses."

"Working hours must be better adapted to the needs of the industries." It makes no sense that a 17-year-old restaurant specialist has to leave at 10 p.m. "if all the tables are still occupied."

This is simply about having cheap labor, but not about ensuring proper training. But these demands are not new.

And what the German economy thinks of training can be seen in the fact that the number of training positions has again decreased by 10% compared to the previous year - and thus young people have again been left without training positions, despite all the promises of the economy. Without a non-training fee for larger companies, this will not change either. But complaining that there are no trained skilled workers, the economy can do quite famously ...

Beckstein on the Roll

No idea what the herb is called that he takes, but it leaves severe brain damage: Beckstein wants German Guantanamo. Apart from the fact that he also wants to shoot suspects in the head and pack foreigners into camps because potential terrorists must not be allowed to run around freely (politicians like him, who are completely crazy, are not only allowed to run around freely but also to express their opinions freely), he is also constitutionally hostile:

Beckstein also criticized the ruling of the Federal Constitutional Court, which in a ruling on Lower Saxony legislation had demanded clear limitations on preventive telephone surveillance. The balance between security and freedom of interests must be re-evaluated, said Beckstein: "That the intimate sphere of terrorists should be protected is for me hardly bearable."

I'm sorry, Mr. Beckstein, but you have failed the test. Because the Constitutional Court does not explicitly protect the intimate sphere of terrorists - but the intimate sphere of citizens. And this is listed in the Basic Law as a protected asset.

Why is someone like this not observed by the Federal Office for the Protection of the Constitution? His hostility to the constitution is really documented multiple times ...

Novell will go for SCO's throat

And their considerations on the legal situation would - if they were to hold up in court - really deliver a significant blow to SCO.

The whole SCO-Linux movie is quite exciting, but quite honestly: the lengths between the action scenes are a bit exaggerated.

Pluto out or a new one in?

Astronomers have found a clump of mud outside Pluto's orbit that is at least as large, and likely even significantly larger than Pluto - Planet or Not, Pluto Now Has Far-Out Rival:

Astronomers announced yesterday that they had found a lump of rock and ice that was larger than Pluto and the farthest known object in the solar system. The discovery will probably rekindle debate over the definition of "planet" and whether Pluto still merits the designation.

Now it's about whether Pluto loses its planet status, or the new one also becomes a planet.

On Dealing with Security

Under ISS takes action against publication of Cisco vulnerability talk you can find a description of how Cisco and ISS envision security: massive interference with the freedom of expression of a speaker at the Black-Hat conference. Okay, he was a former ISS employee and probably used information he shouldn't have published - but it's exactly this ridiculous secrecy that undermines security - because attackers will gain this knowledge sooner or later - if security vulnerabilities exist, they will be found sooner or later. If someone reports about it publicly, at least you can defend yourself and take countermeasures. If the publication is suppressed, the end user is ultimately the victim - who has no chance to protect themselves - and even in an emergency by switching to another router manufacturer.

Therefore, it is indeed the case: neither ISS nor Cisco make a good impression in the public eye. On the contrary, their censorship attempts are actually only another argument in future product decisions to decide against Cisco - because you can obviously not trust their security statements.

Bodies in the Basement

Every software has them - some skeletons in the closet that start to stink when you find them. Django unfortunately too. And that is the handling of Unicode. The automatically generated Admin in Django always sends XHTML and utf-8 to the browser. The browsers therefore also send utf-8 back. But there are browsers that use a slightly different format for the data to be sent in such cases - the so-called multipart format. This is used because it is the only guaranteed method in HTTP-POST where you can send a character set along.

Unfortunately, Django parses these multipart-POSTs with the email module from Python. This then diligently produces Unicode strings from the parts marked as utf-8. Which is correct in itself - only in the Django source code there are str() calls scattered everywhere in the source code. And these then naturally crash when they are given unicode with characters above chr(128) in them.

I took a look at the source code, the most realistic approach would be to make sure in Django that Unicode results are then converted back to utf-8, so that only normal Python strings are used internally. That works so far, but then there are still problems with some databases that recognize utf-8 content when saving and then produce Unicode again when reading the content - SQLite is such a database.

Well, this won't be easy to fix. I've already tried it, it's a pretty nasty topic and unfortunately not at all considered in Django - and therefore it crashes at all corners and edges. Let's see if I can't come up with something useful after all ...

What I also noticed: Django sends the Content-type only via a meta tag with http-equiv. That's a nasty hack, it would be much better if the Content-type were set correctly as a header, then nothing can go wrong if, for example, Apache wants to add a Default-Charset. And the browsers would also react in a much more reproducible way.

In any case, this is again the typical case of American programmers. They like to tell you that you just need to switch to Unicode and utf-8 when you report your character encoding problems, but I have never seen software from an American programmer that handled Unicode correctly ...

Otherwise, there are still one or two hinges in Django - especially annoying because they are not documented, but easy to solve: the default time zone in Django is America/Chicago. You just have to write a variable TIME_ZONE with 'Europe/Berlin' as value in your settings file and apply a small patch so that Django can handle the '-' as time zone separator. Oh man, when Americans write software ...

Somehow, my motivation to take a closer look at Ruby on Rails is increasing at the moment, after all, it was Danes who started it and they should at least get such things right (if only that nice automatic administration part of Django were not - that's exactly what I would be after. Why hasn't anyone built something like that for ROR, damn ...)

Update: I have attached a patch to the corresponding ticket for the Unicode problem (just scroll to the very bottom) that at least gets the problem somewhat under control - provided you don't use SQLite, because SQLite always returns Unicode strings and they then cause trouble again. But at least with PostgreSQL, umlauts now work in Django. The solution is not really perfect, but at least it can be brought in with only a little code change. A real solution would probably require larger code changes.

Another patch is attached to the ticket for the time zone problem, with the patch you can then also use TIME_ZONE = 'Europe/Berlin' to get the time specifications, for example in the change history, in the correct time zone.

In such moments you wish you had commit rights to Django, to be able to put such quite manageable patches in yourself

Another update: Adrian was in the chat yesterday and today and the problems with Unicode are largely gone. Only with SQLite there is still trouble, but I already have the patch finished. And the time zone issue is also fixed in the SVN. And he has started unit tests. Very useful, if you can then test the whole framework cleanly in the long run after a patch ...

Liability for Links after the Heise Judgment

After this interview with WDR, the following applies: "Anyone who sets such a link is in trouble":

You really have to be very careful. Due to these new rulings, you have to think: Who am I linking to? In the past, as a private individual, you would say: 'Come on, I'll put a hundred links one after the other' and be quite proud. Today, you really have to consider whether the person you are linking to is really trustworthy. You also have to check these links at regular intervals and see what is happening on the linked page.

Which - if it were actually the case - would factually mean the end of privately operated information offerings in the short or long term, as no one can check all their links. I have almost 5000 articles in my blog, which I certainly won't be able to check to see if there is something somewhere that offends someone.

And thus, this ruling has driven another nail into the coffin of the Internet, simply because judges repeatedly rate the alleged rights of rights extortionists higher than free speech and free reporting.

Sysadmins Day

Lisa9 shows how to properly pay tribute to a sysadmin! Even DAU-friendly with illustrated instructions

Django, lighttpd and FCGI, second take

In my first take at this stuff I gave a sample on how to run django projects behind lighttpd with simple FCGI scripts integrated with the server. I will elaborate a bit on this stuff, with a way to combine lighttpd and Django that gives much more flexibility in distributing Django applications over machines. This is especially important if you expect high loads on your servers. Of course you should make use of the Django caching middleware, but there are times when even that is not enough and the only solution is to throw more hardware at the problem.

Update: I maintain my descriptions now in my trac system. See the lighty+FCGI description for Django.

Caveat: since Django is very new software, I don't have production experiences with it. So this is more from a theoretical standpoint, incorporating knowledge I gained with running production systems for several larger portals. In the end it doesn't matter much what your software is - it only matters how you can distribute it over your server farm.

To follow this documentation, you will need the following packages and files installed on your system:

  • [Django][2] itself - currently fetched from SVN. Follow the setup instructions or use python setup.py install .
  • [Flup][3] - a package of different ways to run WSGI applications. I use the threaded WSGIServer in this documentation.
  • [lighttpd][4] itself of course. You need to compile at least the fastcgi, the rewrite and the accesslog module, usually they are compiled with the system.
  • [Eunuchs][5] - only needed if you are using Python 2.3, because Flup uses socketpair in the preforked servers and that is only available starting with Python 2.4
  • [django-fcgi.py][6] - my FCGI server script, might some day be part of the Django distribution, but for now just fetch it here. Put this script somewhere in your $PATH, for example /usr/local/bin and make it executable.
  • If the above doesn't work for any reason (maybe your system doesn't support socketpair and so can't use the preforked server), you can fetch [django-fcgi-threaded.py][7] - an alternative that uses the threading server with all it's problems. I use it for example on Mac OS X for development.

Before we start, let's talk a bit about server architecture, python and heavy load. The still preferred Installation of Django is behind Apache2 with mod python2. mod python2 is a quite powerfull extension to Apache that integrates a full Python interpreter (or even many interpreters with distinguished namespaces) into the Apache process. This allows Python to control many aspects of the server. But it has a drawback: if the only use is to pass on requests from users to the application, it's quite an overkill: every Apache process or thread will incorporate a full python interpreter with stack, heap and all loaded modules. Apache processes get a bit fat that way.

Another drawback: Apache is one of the most flexible servers out there, but it's a resource hog when compared to small servers like lighttpd. And - due to the architecture of Apache modules - mod_python will run the full application in the security context of the web server. Two things you don't often like with production environments.

So a natural approach is to use lighter HTTP servers and put your application behind those - using the HTTP server itself only for media serving, and using FastCGI to pass on requests from the user to your application. Sometimes you put that small HTTP server behind an Apache front that only uses mod proxy (either directly or via mod rewrite) to proxy requests to your applications webserver - and believe it or not, this is actually a lot faster than serving the application with Apache directly!

The second pitfall is Python itself. Python has a quite nice threading library. So it would be ideal to build your application as a threaded server - because threads use much less resources than processes. But this will bite you, because of one special feature of Python: the GIL. The dreaded global interpreter lock. This isn't an issue if your application is 100% Python - the GIL only kicks in when internal functions are used, or when C extensions are used. Too bad that allmost all DBAPI libraries use at least some database client code that makes use of a C extension - you start a SQL command and the threading will be disabled until the call returns. No multiple queries running ...

So the better option is to use some forking server, because that way the GIL won't kick in. This allows a forking server to make efficient use of multiple processors in your machine - and so be much faster in the long run, despite the overhead of processes vs. threads.

For this documentation I take a three-layer-approach for distributing the software: the front will be your trusted Apache, just proxying all stuff out to your project specific lighttpd. The lighttpd will have access to your projects document root and wil pass on special requests to your FCGI server. The FCGI server itself will be able to run on a different machine, if that's needed for load distribution. It will use a preforked server because of the threading problem in Python and will be able to make use of multiprocessor machines.

I won't talk much about the first layer, because you can easily set that up yourself. Just proxy stuff out to the machine where your lighttpd is running (in my case usually the Apache runs on different machines than the applications). Look it up in the mod_proxy documentation, usually it's just ProxyPass and ProxyPassReverse.

The second layer is more interesting. lighttpd is a bit weird in the configuration of FCGI stuff - you need FCGI scripts in the filesystem and need to hook those up to your FCGI server process. The FCGI scripts actually don't need to contain any content - they just need to be in the file system.

So we start with your Django project directory. Just put a directory public html in there. That's the place where you put your media files, for example the admin media directory. This directory will be the document root for your project server. Be sure only to put files in there that don't contain private data - private data like configs and modules better stay in places not accessible by the webserver. Next set up a lighttpd config file. You only will use the rewrite and the fastcgi modules. No need to keep an access log, that one will be written by your first layer, your apache server. In my case the project is in /home/gb/work/myproject - you will need to change that to your own situation. Store the following content as /home/gb/work/myproject/lighttpd.conf


 server.modules = ( "mod_rewrite", "mod_fastcgi" )
 server.document-root = "/home/gb/work/myproject/public_html"
 server.indexfiles = ( "index.html", "index.htm" )
 server.port = 8000
 server.bind = "127.0.0.1"
 server.errorlog = "/home/gb/work/myproject/error.log"

fastcgi.server = (
"/main.fcgi" => (
"main" => (
"socket" => "/home/gb/work/myproject/main.socket"
 )
 ),
"/admin.fcgi" => (
"admin" => (
"socket" => "/home/gb/work/myproject/admin.socket"
 )
 )
 )

url.rewrite = (
"^(/admin/.*)$" => "/admin.fcgi$1",
"^(/polls/.*)$" => "/main.fcgi$1"
 )

mimetype.assign = (
".pdf" => "application/pdf",
".sig" => "application/pgp-signature",
".spl" => "application/futuresplash",
".class" => "application/octet-stream",
".ps" => "application/postscript",
".torrent" => "application/x-bittorrent",
".dvi" => "application/x-dvi",
".gz" => "application/x-gzip",
".pac" => "application/x-ns-proxy-autoconfig",
".swf" => "application/x-shockwave-flash",
".tar.gz" => "application/x-tgz",
".tgz" => "application/x-tgz",
".tar" => "application/x-tar",
".zip" => "application/zip",
".mp3" => "audio/mpeg",
".m3u" => "audio/x-mpegurl",
".wma" => "audio/x-ms-wma",
".wax" => "audio/x-ms-wax",
".ogg" => "audio/x-wav",
".wav" => "audio/x-wav",
".gif" => "image/gif",
".jpg" => "image/jpeg",
".jpeg" => "image/jpeg",
".png" => "image/png",
".xbm" => "image/x-xbitmap",
".xpm" => "image/x-xpixmap",
".xwd" => "image/x-xwindowdump",
".css" => "text/css",
".html" => "text/html",
".htm" => "text/html",
".js" => "text/javascript",
".asc" => "text/plain",
".c" => "text/plain",
".conf" => "text/plain",
".text" => "text/plain",
".txt" => "text/plain",
".dtd" => "text/xml",
".xml" => "text/xml",
".mpeg" => "video/mpeg",
".mpg" => "video/mpeg",
".mov" => "video/quicktime",
".qt" => "video/quicktime",
".avi" => "video/x-msvideo",
".asf" => "video/x-ms-asf",
".asx" => "video/x-ms-asf",
".wmv" => "video/x-ms-wmv"
 )

I bind the lighttpd only to the localhost interface because in my test setting the lighttpd runs on the same host as the Apache server. In multi server settings you will bind to the public interface of your lighttpd servers, of course. The FCGI scripts communicate via sockets in this setting, because in this test setting I only use one server for everything. If your machines would be distributed, you would use the "host" and "port" settings instead of the "socket" setting to connect to FCGI servers on different machines. And you would add multiple entries for the "main" stuff, to distribute the load of the application over several machines. Look it up in the lighttpd documentation what options you will have.

I set up two FCGI servers for this - one for the admin settings and one for the main settings. All applications will be redirected through the main settings FCGI and all admin requests will be routed to the admin server. That's done with the two rewrite rules - you will need to add a rewrite rule for every application you are using.

Since lighttpd needs the FCGI scripts to exist to pass along the PATH_INFO to the FastCGI, you will need to touch the following files: /home/gb/work/myprojectg/public_html/admin.fcgi ``/home/gb/work/myprojectg/public_html/main.fcgi

They don't need to contain any code, they just need to be listed in the directory. Starting with lighttpd 1.3.16 (at the time of this writing only in svn) you will be able to run without the stub files for the .fcgi - you just add "check-local" => "disable" to the two FCGI settings. Then the local files are not needed. So if you want to extend this config file, you just have to keep some very basic rules in mind:

  • every settings file needs it's own .fcgi handler
  • every .fcgi needs to be touched in the filesystem - this might go away in a future version of lighttpd, but for now it is needed
  • load distribution is done on .fcgi level - add multiple servers or sockets to distribute the load over several FCGI servers
  • every application needs a rewrite rule that connects the application with the .fcgi handler

Now we have to start the FCGI servers. That's actually quite simple, just use the provided django-fcgi.py script as follows:


 django-fcgi.py --settings=myproject.work.main
 --socket=/home/gb/work/myproject/main.socket
 --minspare=5 --maxspare=10 --maxchildren=100
 --daemon

django-fcgi.py --settings=myproject.work.admin
 --socket=/home/gb/work/myproject/admin.socket
 --maxspare=2 --daemon

Those two commands will start two FCGI server processes that use the given sockets to communicate. The admin server will only use two processes - this is because often the admin server isn't the server with the many hits, that's the main server. So the main server get's a higher-than-default setting for spare processes and maximum child processes. Of course this is just an example - tune it to your needs.

The last step is to start your lighttpd with your configuration file: lighttpd -f /home/gb/work/myproject/lighttpd.conf

That's it. If you now access either the lighttpd directly at http://localhost:8000/polls/ or through your front apache, you should see your application output. At least if everything went right and I didn't make too much errors.

Another Questionnaire

From Lisa Sonnabend's mailbox:

As part of my thesis at the Institute for Communication Studies and Media Research at Ludwig-Maximilians-Universität München, I am conducting a survey among weblog readers on the topic of "Credibility of Weblogs". This is one of the first scientific studies on the phenomenon of weblogs in Germany.

It is to be clarified whether weblogs are already considered as trustworthy and competent in certain points such as fairness or impartiality as traditional media – and in which points there are great differences. In addition, the survey examines which special qualities weblogs have from the perspective of the recipients and what importance they have for the users. Based on the results, a prognosis about the future importance of weblogs in the media landscape is to be made.

And I should put the link in the blog so that people can participate. Well, I'll do that, even though I wonder what competence and credibility the old media are supposed to have.

Here goes the questionnaire

Preventive telephone surveillance is not

The Constitutional Court declares preventive telephone surveillance null and void. Primarily affects Lower Saxony, but similar situations exist in other federal states. Good when something is finally put in the way of the whole surveillance fetishism.