HTTP Headers, Web Apps and Mobile Safari

I found today that Mobile Safari, the browser bundled with the iPhone, has a very strange and annoying behaviour when it comes to web apps. In fact, when you “install” web applications with the <meta name="apple-mobile-web-app-capable" content="yes" /> tag in the “Home Screen”, the USER_AGENT header sent to the server is different to the one sent when you access the same app manually using Safari..

Here’s a test that proves this assertion: Continue reading

WordPress 2.8 and the get_link() error in line 647 of dashboard.php

Wow, that’s a long title, but it should drive people with this problem right here. If you have upgraded your WordPress installation to 2.8, you might have encountered a nasty error in your Dashboard, which says something about a

Fatal error: Call to a member function on a non-object in /home/user/www/wp-admin/includes/dashboard.php on line 647

This has been reported in the WordPress site but no fix has been provided. I found elsewhere a possible fix, but in my case, the new URL would not be saved at all, and the problem would persist.

I fixed it using a good old method, enabled by Open Sourceā„¢: editing the code directly; I’m posting it here for those of you who would like to do it, until 2.8.1 is released:

[source:php:firstline(646)] $author = $item->get_author(); if ($author == NULL) { $site_link = “”; $publisher = “Someone”; } else { $site_link = esc_url(strip_tags($author->get_link())); if ( !$publisher = esc_html(strip_tags($author->get_name()))) $publisher = __(‘Somebody’); if ($site_link) $publisher = “$publisher“; else $publisher = “$publisher“; } [/source]

10 iPhone Memory Management Tips

Memory management in the iPhone is a hot topic. And since tonight I’m talking about it on tonight’s monthly meetup of the French-speaking Swiss iPhone Developers group, I might as well share some tips here from my own experience.

I won’t go dive through the basics; I think that Scott Stevenson did a great job in his “Learn Objective-C” tutorial at CocoaDevCentral, from where the image below comes. I’m just going to highlight some iPhone-specific issues here and there, and provide some hints on how to solve them.

Continue reading

Basic vs. Digest

In the series of highly boring posts ;) here’s another one; in this case, a simple explanation of two different authentication protocols available in the HTTP standard.

HTTP Basic Authentication Protocol

This is the simplest HTTP Authentication protocol available:

  1. The browser sends a request to a protected resource: GET /index.html
  2. The server looks for the “Authenticated” header in the request; since it does not find it, it replies back with a response with the 401 code (“Unauthorized”). The response contains a “WWW-Authenticate” header, with the value “Basic”. This response is called a “challenge”, and it also contains a “realm” text, which describes the protected resource in clear text (the “realm” is shown in the pop-up window that usually appears for you to type your password when this protocol is used).
  3. The browser creates a new request GET /index.html that contains an HTTP_AUTHORIZATION header, whose value is the word “Basic” followed by the ‘username:password’ string encoded in base 64. This algorithm is a two-way algorithm: you can retrieve the username and password from the base 64-encoded string.
  4. The server receives this response, and since base 64 is a two-way algorithm, it compares the MD5 (or SHA1) password hash to the one stored in the database. If they are the same, the request is processed. Otherwise, the user gets a 401 again.

Continue reading

wp-super-cache problem? Easy fix

I’ve just installed the excellent wp-super-cache plugin to accelerate things a bit in this blog; today somebody sent one of my pages to reddit and I’ve had more users than usual! – by the way, thanks for coming! :)

Update: I admit, it also has a bit to do with the reading of today’s entry in Coding Horror ;) But I love WordPress nonetheless. I prefer it over MovableType (which I used during one year and a half).

The only glitch was: at first, it didn’t work. I think you know the feeling.

The plugin was enabled, everything was activated, yet no files were cached: exactly this same problem. And I found a quick fix to it, hence this post: fire your FTP client of choice and go to /wp-content/cache. If you don’t see a “supercache” folder in there, just create it. Magically, if you have some traffic on your blog and you dig in that folder a couple of seconds later you’ll see already lots of files! No need to modify .htaccess whatsoever.

If you want to populate it, log out of the WordPress admin and start clicking on your blog. This plugin only creates cached files for anonymous visitors! I also turned on the compression so you should start having faster response times.

It was the only thing to do manually to get it working. Hope this helps! Any comments, as usual, more than welcome.

Installing PostgreSQL 8.3 on Leopard

This is the documented path to my discovery of PostgreSQL 8.3, which I’ve never used before. Now that MySQL‘s community is getting hammered to death by Sun, and thanks to all the good things I’ve heard about it over the years (including enhanced performance on multicore systems and greater scalability), I really wanted to install it and play with it.

Frankly, it’s not easy. At all (actually this is why I think MySQL is so popular, because of the ease of installation!) So hang tight and read on. Continue reading

Extracting e-mails from a vCard file with Python

Let’s say that you have a vCard file. You can export it from your Mac OS X AddressBook.app, or from any other similar application. Now you need to extract some information from it, namely the e-mails, for spamming your friends with some boring news. Typical.

Enter vobject. This Python library is part of the Chandler effort (which seems to be somewhat ill-fated since Mitch Kapor announced he was leaving the project). Anyway, you can download this library from here and then install it using the common sequence:

python setup.py build python setup.py install

Finally, here’s a bit of code to quickly extract the names and e-mail addresses from a vCard file called “vCards.vcf” containing lots of vCard instances, one after the other (AddressBook.app exports data this way, instead of creating on file per contact):

[source:python] import vobject

f = open(“vCards.vcf”) s = “”.join(f.readlines()) f.close()

a = vobject.readComponents(s)

counter = 0

while True: try: # “next()” seems to throw an exception # when there aren’t any more “Components” # in the stream… # Talk about nice flow control! b = a.next() counter += 1 if b.contents.has_key(‘email’): # “repr()” below avoids # unicode –> ascii exceptions print repr(b.fn.value), repr(b.email.value) except: break

print “%d e-mails found.” % counter [/source]

The library documentation, to put it simply, isn’t as good as the library itself (see? I can be politically correct sometimes :) Maybe I missed a better way to iterate over the contents of the whole stream of vCard instances inside the file (using exceptions for that is yuck!), but then again, feel free to add your comments below as usual.

Quick spec from your Python tests

Using Python’s own unittest package, here’s a small script that can iterate over your test suite to output a small, quick, nice list of the tests in your application:

[source:python] import unittest

loader = unittest.TestLoader() tests = loader.loadTestsFromName(‘path.to.your.tests.package’) for test in tests.tests: print test._tests[0].class.name.replace(“Test”, “”) for method in test._tests: print ” %s” % method._testMethodName.replace(“test“, “”).capitalize().replace(“_”, ” “) [/source]

This would yield something like this: Business     Accounts have at least one entry     Clerks cannot close accounts Security     Users can create new accounts     Anonymous users cannot access private areas ...

Of course, you’ll get better results if you follow Google’s naming conventions for your tests… ;) This is not rspec (nor an alternative to it) but it might be useful to some of you.

Just as a reminder for Django users: you might need to

setenv DJANGO_SETTINGS_MODULE application.settings

or

export DJANGO_SETTINGS_MODULE=application.settings

in order to make the script work properly! At least I had to :)

How to build ohcount on Leopard

If you do not know ohcount, you should; the guys at ohloh.net have GPL’d one of their core components, namely the one that allows you to perform source code line counts in your own projects. Neat and useful!

However, the current ohcount distribution (which you can download from this link) does not build out-of-the-box in Leopard. Here’s how I made it work in my own Leopard G4 PowerBook (PPC) computer. Continue reading

Playing with HTTP libraries

It’s fun to find out how to tackle the same task in different programming languages; in this case, it’s all about doing HTTP requests over a network: fortunately, there are networking libraries in virtually all major programming languages. In my current project, I’m generating wrappers easing the access to the core of the project itself, a RESTful API. This way, developers interested in using the API can just take a wrapper, include it in their projects, and start coding right away. No need to know this (relatively low-level) stuff; just use the API. The wrappers themselves are auto-generated from the API definition itself, but that’s another story ;)

Below there is a sample of the different ways I’ve found to do a network access to a remote server, using HTTP Basic Authentication and a couple of headers, in PHP, Ruby, Python, JavaScript, and even Objective-C! I’m even generating ActionScript 3.0 code, but I’m not a Flash coder :) So I’ll post the wrappers that work best at the moment, and in the future I’ll include other examples, particularly for .NET, C++ and Java.

In all the cases below, there is a “request” function or method that takes an HTTP verb (GET, POST, PUT, DELETE, etc), a URL (without the slash “/” at the beginning) and some parameter data, in the form of a dictionary. The function wraps the underlying libraries of each programming language, offering a simpler interface, and allowing for HTTP Basic Authentication (for HTTP Digest Authentication it would be much, much more complex!). There are synchronous (useful for server or command-line applications) and asynchronous versions (for GUI systems). Off to the code! Continue reading