Phillip Pearson - Second p0st

tech notes and web hackery from the guy that brought you bzero, python community server, the blogging ecosystem, the new zealand coffee review and the internet topic exchange

2003-9-4

The Topic Exchange does blogrolls and images now

Getting further from what it was originally meant for (you can blame Marc Canter for this!), but towards something else useful :-)

You can now use it to host blogrolls. Here's one:


Click the '(ite)' link at the bottom to get to the documentation and see how to make your own one.

You can also upload images, but please don't upload too many as I have limited hard disk space ...
... more like this: []

What do you call links into the middle of HTML documents?

A workmate just asked me: what do you call the points in the web page with markup like this:

    <a name="foo"></a>

(so you can jump to them with <a href="#foo">foo</a>).

In German apparently they are called anchor points (Ankerpunkt). What do we call them in English? Just anchors?

Update: it looks like anchor is correct.

BTW that page links to a note on relationships in HTML links that talks about various ways you can specify more information about the meaning of your link. This is a topic that comes up fairly often in the blogosphere, but I've never see that note before. Here are some examples:

If you like RSS ...

    <a href="http://blogs.law.harvard.edu/tech/rss" rel="supports">

... or if you don't ...

    <a href="http://blogs.law.harvard.edu/tech/rss" rel="refutes">

... and Dave Winer might write this:

    <a href="http://blogs.law.harvard.edu/tech/rss" rel="made">

(and then justify it with something like <a href="http://www.cadenhead.org/workbench/stories/2003/05/02/whoCreatedRss.html" rel="supports"> :-)

It seems that the idea of typed links was forgotten in 1995, then revived in 1996, then forgotten again. The HTML 4 spec defines another set of link types, which no longer includes things like supports and refutes. Oh well ...

I can't resist a challenge

The Microsoft.com Web Services went live yesterday, attracting an snarky-sounding post from Mark Pilgrim and a confused-sounding one from Dave Winer.

Having never done anything with SOAP before, I thought I might as well start here and hack up a Python wrapper for the service.

Presenting: microsoft_com.py

I won't go into the details of how to use it right here, because I've already written them on that link above and in a big comment at the start of the code. The interesting thing is what it took to put this together.

It seems that SOAP is still not very widely supported. The Microsoft.com Web Services require you to use Microsoft and IBM's new WS-Security extension to pass your authentication information. This isn't all that hard, but it's the sort of thing that usually comes for free with your protocol library. From what I can see, .NET and one or two Java libraries support it, but anyone on another platform has to do it all by hand.

Luckily, the web service documentation had some example WS-Security headers I could use as templates. Even so, I spent several hours trying to get SOAPPy to generate the right XML in the SOAP-ENV:Header block, then eventually gave up and switched to the much lighter-weight ZSI library. ZSI doesn't do as much for you, but it also doesn't stop you from doing much. The following snippet generates the XML I need, and a quick hack to ZSI/client.py let me pass it in in place of the authentication header it was expecting.

    wsse = Element('wsse:Security')
    wsse.set('xmlns:wsse', 'http://schemas.xmlsoap.org/ws/2002/07/secext')
    wsse.set('xmlns:wsu', 'http://schemas.xmlsoap.org/ws/2002/07/utility')
    ut = SubElement(wsse, 'wsse:UsernameToken')
    def mkelem(parent, tagname, text, **attrs):
        if tagname.find(':') == -1:
            tagname = 'wsse:' + tagname
        x = SubElement(parent, tagname)
        x.text = text
        for k,v in attrs.items():
            x.set(k, v)
    mkelem(ut, 'Username', mstoken.token)
    created = time.strftime('%Y-%m-%dT%H:%M:%SZ')
    nonce = sha.new(str(random.random())).digest()
    digest = sha.new(nonce + created + mstoken.pin).digest()
    mkelem(ut, 'Password', binascii.b2a_base64(digest), Type='wsse:PasswordDigest')
    mkelem(ut, 'Nonce', binascii.b2a_base64(nonce))
    mkelem(ut, 'wsu:Created', created)

    tree = ElementTree(wsse)
    wsse = StringIO()
    tree.write(wsse)
    wsse_header = wsse.getvalue()


After that, ws.microsoft.com started accepting my calls, and it wasn't so hard from then on. Being used to XML-RPC, it feels weird to be encoding and decoding XML all the time when calling remote methods, but a bit of hacking (see the SoapClass class in the code) made most of that fairly trivial.

And now we have it, the first non-Microsoft client for the Microsoft.com Web Services.

Share and enjoy!
... more like this: []