Archive for the ‘HTML’ Category

A world without Twitter

Friday, July 9th, 2010

This post has been rolling around in my mind for a while — along with my bank balance, the song “Gee, Officer Krupke”, and Jennifer Aniston’s … nevermind. I was inspired to finally commit it to paper, or whatever the heck this big rectangular white thing is, by a recent tweet from @danielpunkass, AKA Daniel Jalkut, AKA Mr. MarsEdit, AKA The Boston Strangler. As John Lennon might say if he were alive today, and unable to come up with any new ideas in the last 40 years: imagine there’s no Twitter. It’s easy if you try. Command-r, command-r.

The credit, or blame, goes to @rentzsch for luring me onto Twitter. Not once, but twice. The first time was as a requirement for attending the C4[2] conference. My initial run on Twitter came to a halt later when I famously (for some definition of famous) took a 5-month hiatus. At C4[3], however, ‘Wolf’ (as he is known in the porn industry) persuaded me to return to Twitter. You can see why C4 was evil and had to be abolished.

For a whale, err, while, Twitter was fairly stable, relatively speaking. Lately, though, the uptime has been absolutely horrid, even when there’s no World Cup game. The only thing that never fails is the status blog. (Why don’t they make Twitter out of the status blog? Or the black box?) The Twitter developers don’t really inspire confidence; they keep pushing code changes that are supposed to improve reliability but end up causing outages. Furthermore, after all this time they’ve still failed to implement any convenient way to follow conversation threads on Twitter. The @reply is only the most rudimentary step in this direction. To me, that suggests the developers have completely missed what is important and special about Twitter, the social aspect.

Another threat to Twitter’s future, besides the continued technical suckage and danger of collapsing under its own weight, is the need to make money. We’ve grown accustomed to receiving this service for free, but Twitter is not a charity, it’s a for-profit corporation. We’re starting to see this manifested in ‘promoted’ trends. Third-party spammers have existed on Twitter from the beginning, of course, but the question is whether commercialization will transform Twitter itself into something repulsive (cf. iAds). On the other hand, there’s a possibility that Twitter cannot make itself commercial enough. If Twitter doesn’t generate sufficient revenue to sustain itself and make a profit over the long term, it may have to close up shop and go out of business. It certainly wouldn’t be the first dot-com service to disappear. I believe that if Google wanted, they could create a serious competitor to Twitter, backed with Google’s superior knowledge, reliability, and bandwidth. Indeed, I’m surprised that Google hasn’t attempted this already. Maybe they don’t see any profit in it. But that doesn’t bode well for Twitter either.

As good programmers, we always have a backup. (Right? Right? Redundant and off-site, right?) The purpose of this post is to consider, what is our backup to Twitter? If Twitter dies, or if we’re compelled to leave, where do we go? We could go back to our pre-Twitter existence, back to our spouses, children, neighbors, and back to writing long blog posts instead of pithy 140- character tweets. We could, but blech! The un-tweeted life is not worth living. There would always be something missing. Twitter allows us to connect regularly with many friends that we don’t get to see very often (and to make arrangements when we do see them). It introduces us to people that we’d never meet or be able to talk to otherwise. It provides a unmoderated, unstructured forum for sharing crucial tidbits of information and knowledge with people we trust and respect (as well as everyone else, for better or worse). Twitter is like Cheers for the internet, except without Sam Malone. Oh wait, it’s got Sam Malone. The problem is, we don’t have a good backup. Without Twitter, we’ve got nothing. (Please don’t even mention Gary’s Old Towne Tavern.)

Admittedly, there are some alternatives to Twitter, a few services that are similar, but they all suffer from the same inherent limitations as Twitter. They present a single point of failure. If Twitter’s servers are overloaded, then the service becomes unusable. Everyone gets the fail whale. In order to reliably handle the traffic, a centralized service require a large amount of resources, and thus money. So the only hope for a reliable, centralized Twitter-like service is heavily commercialization, and it’s not clear that a heavily commercialized service is one we’d want to spend our time on. Would a profit train be recognizable as the little Twitter we know and (sometimes) love? Besides, any centralized service is still prone to catastrophic failure. Even the mighty Amazon goes down.

So I had this idea. In the shower. (With Jennifer Aniston.) What if we made a distributed Twitter? Like DVCS. All the hip young programmers today use DVCS, whether that’s Git, or Mercurial, or … yeah, Git or Mercurial. The key to DVCS is that there’s no single point of failure, no centralized repository. Each working copy is its own repository, with the entire commit history. And you can commit locally! If one repository goes offline or disappears entirely, the other repositories can continue operating indefinitely without it. Nothing is lost. Similarly, each user of Dwitter (clever, huh?) would install Dwitter software on a web server, which would keep a record not only of the user’s own dweets but also the dweets of everyone the user follows.

When you follow someone, your Dwitter server would send a request containing information such as your name and server address to the Dwitter server of the person you follow. The followee’s Dwitter server stores this information, and then when that person dweets, his/her/its/their Dwitter server would send the dweet to the Dwitter servers of all followers. To prevent connection overload, the rate of sending out dweets to followers would be limited, perhaps to something like 1.5 followers per second. This would allow a dweet to be propagated to 5000 followers in less than an hour. And if you compose another dweet while your followers are still getting notified of the previous dweet, the dweet notifications would get consolidated for the followers who haven’t yet been notified. Furthermore, any Dwitter user directly mentioned in a dweet would receive immediate notification of the dweet, prior to anyone else, to facilitate quick conversation.

Obviously, this system won’t scale for someone who has a million Twitter followers. However, the only people who have a million Twitter followers are celebrities. There are plenty of other, better outlets for celebrity news, we don’t need Twitter for that. Note that celebrities did not make Twitter popular. Rather, celebrities came to Twitter because it was already popular. What makes the presence of celebrities on Twitter mostly useless is that they rarely participate in the culture of Twitter, they don’t foster conversation. You can’t have a conversation with a million followers, because that doesn’t scale either.

A potentially more serious problem for the distributed version of Twitter is the difficulty of use. Running your own Dwitter server requires a fair bit of technical knowledge. It’s much more difficult than going to a web site and signing up for an account. This may exclude mom and pop from joining Dwitter. However, I personally don’t consider the loss of mom and pop to be worse than the loss of celebrities. Frankly, I don’t want my mom following me on Twitter. Have you read my tweets? She’d make me wash my mouth out with soap! Almost all of the people I follow are programmers. They should be fully capable of setting up a Dwitter server on their own internet domain. Even though Twitter is completely public (except for protected tweets, you bastards), the irony is that it’s best suited for insulated groups such as programmers. 140 characters is not enough to teach outsiders your terminology and concepts. When you tweet, you’re forced to leave out a lot and to use shorthand that only likeminded people will understand. Tweeting is kind of like sending out coded messages. (@IwayAmwayAwayUssianrayYspay)

Even with the distributed system, there may be options for less technical users. WordPress operates under a similar model. You can install WordPress software on your own web server and run your blog yourself, or you can sign up to have a hosted blog on wordpress.com, where they take care of the technical aspects for you. The key is that even if one hosted Dwitter service fails, that would only prevent new dweets from the hosted accounts. The rest of the Dwitterverse would go on as usual, and the archives of the hosted dweet accounts would continue to exist on the Dwitter servers of their followers.

I don’t personally have the expertise to design a distributed Twitter-like service. I have some web knowledge, but I’m mainly a desktop programmer. Nonetheless, I will take all glory and riches arising from this idea. All I ask in return for all the glory and riches is that the designers of the new service don’t create a half-assed API. I’m tired of crappy, fatally flawed designs becoming popular by virtue of being first to market. Indeed, this is how Twitter itself became popular. Please, do it right the first time. Or I’ll be looking for an alternative to you too.

Safari extension: autocomplete

Thursday, June 10th, 2010

Safari has a feature called form autocompletion, or AutoFill, that reads the username and password you type into a web form, saves them to your keychain, and automatically fills them in from the keychain the next time you visit the web form. This feature is completely opt-in: you can enable and disable it in Safari’s preferences, and even when it’s enabled, Safari will ask you before saving the username and password from each web form. Many other web browsers have a similar feature; it appears to have been introduced by Internet Explorer.

Unfortunately, a number of web sites (including my bank, for example) choose to disable autocompletion in a misguided attempt at security. Autocompletion can be disabled by using the attribute autocomplete=off in a web form. The idea behind disabling autocompletion seems to be that it leaves the account holder vulnerable to someone else accessing the computer and logging into the account. I believe that this is misguided for at least two reasons. First, autocompletion is opt-in, so the user can decide whether to save passwords on a particular machine. Anyone who chooses to save their passwords on a public terminal is an idiot. Indeed, anyone who logs in to their bank account on a public terminal deserves to be hacked and lose all their money, because who knows what manner of keyloggers or other malware could be running on the machine? I feel safe turning on AutoFill on my computer because I’m the only person who ever has access to it.

Another reason that disabling autocompletion is misguided is that it encourages the use of weak passwords. For security, I generate very long, random passwords for web sites and save them to my keychain. There’s no way I could memorize even one of my web site passwords, much less all of them. It’s difficult for almost anyone to memorize a bunch of web site passwords. Disabling autocompletion forces the user to type them in manually every time, and this encourages the use of short, easy to remember passwords. Worse, it encourages password sharing among different web sites. Thus, if an attacker can guess or brute-force one password, the attacker suddenly has access of all of a persons’s web site accounts. That’s terrible security.

WebKit, the web engine underlying Safari, respects the autocomplete attribute, and there’s no preference or API to make WebKit ignore the attribute. However, I discovered an excellent script written by Michael Kisor called Autocomplete Always On! that actually patches the WebKit framework itself on your system so that it ignores autocomplete. It works by changing one byte in the file

/System/Library/Frameworks/WebKit.framework/Versions/A/Frameworks/WebCore.framework/Versions/A/WebCore

transforming the string autocomplete into xutocomplete. After that change, WebKit looks for xutocomplete=off but never finds it in the web form, which means autocomplete never gets disabled. WebKit is open source, so we can verify the consequences of the patch.

The only downside of the Autocomplete Always On! script is that it needs to be re-run after any software update to the WebKit framework on your system. I’ve been using the script for years with no trouble … until Safari 5. After installing Safari 5, I discovered that the script was no longer effective in re-enabling autocompletion. This was no flaw in the script, however. Autocomplete Always On! still works as designed on the version of WebKit shipped with Safari 5. The problem is that the Safari 5 binary itself seems to include a new check for the autocomplete attribute in web forms. I’ve verified this behavior in the debugger. If the form contains autocomplete=off, then Safari 5 never calls the (private) WebKit method -[WebHTMLRepresentation elementDoesAutoComplete:], so Safari doesn’t even ask WebKit whether autocomplete is enabled for the web form element. It is possible to patch the Safari binary just like the WebCore binary, after which Safari 5 will call -[WebHTMLRepresentation elementDoesAutoComplete:], making the WebCore patch effective again. Unfortunately, patching the Safari binary breaks codesigning for the application, and the keychain uses codesigning to determine whether an application can access saved passwords.

That’s the bad news. The good news is that Safari 5 also introduced extensions. A Safari extension is like a plug-in, because it can run code inside the browser, but unlike a plug-in, an extension doesn’t run native C or Objective-C code but rather HTML or Javascript code. For example, an extension can specify some Javascript to run on page load. I found a script written by Andreas Huber that removes any autocomplete attributes from a web form, and I cleaned it up a bit for inclusion in a Safari extension. With my autocomplete extension installed, you don’t have to patch WebKit or Safari, because the autocomplete attributes are simply removed from the web page before the browser checks for their existence.

I’m making my autocomplete Safari extension available — in September. No, today! You can download the extension here. To install the extension on your computer, you first need to check “Show Develop menu in menu bar” at the bottom of Safari’s Advanced preferences. Then in the Develop menu, you need to check “Enable Extensions”. After extensions are enabled, you can simply double-click the Safari extension in Finder to install.

Enjoy! In lieu of donations, I am accepting sexual favors. Or an icon.

WordPress Bug Near Friday: HTML Injection Vulnerability

Saturday, December 30th, 2006

No sooner had I posted this, I noticed this. Case closed. I win by TKO.

Bring back STX and ETX

Saturday, December 30th, 2006

Some people think that XML is the greatest invention since sliced bread. (I won’t name names, to protect the non-existent.) In contrast, I think that it’s just a symptom of a disease, a terminal illness infecting the entire computing world. Programmers are supposed to be smart, but we’re actually the ones who are responsible for the spread of the disease. We started and promoted the practice of using printable text to delimit printable text. In my haughty opinion, this was one of the worst ideas in the history of computers (surpassed only by SMTP and MacAppADay). It was doomed to fail from the beginning, kind of like the paradox of the liar. The use of printable text to delimit printable text has been the cause of countless bugs — let’s say 500 billion — and indeed, countless security vulnerabilities. It continues to plague us today.

Having worked on a feed reader, I do know a thing or two about this issue. I can tell you that it’s a major pain to parse XML feeds. Parsing HTML is even worse, but thankfully we can leave the majority of that to WebKit. It’s hard enough when everything is perfect, but we inevitably run into issues where the text is improperly escaped or not properly escaped. This is no fun for anyone.

Since the beginning, ASCII contained a number of non-printing control characters, but for some reason they have fallen out of favor. Among the control characters are STX (0x2) and ETX (0x3). Their position in the list of character codes indicates their importance: they were used to delimit text. With character codes such as these, parsing data into strings becomes trivial:

  1. Start parsing a string when you see a STX code.
  2. Continue until you see a ETX code, you see a non-character code, you reach a preset maximum length, or you run out of data.
  3. If the last code was ETX, you’ve got a good string. Otherwise, you’ve encountered an error, and you can do whatever error handling you like.
  4. There are no more steps. The characters in the string are all literal, no unescaping necessary.

Unicode has added some similar codes such as SOS and ST. I’d like to see even more control codes, to allow for fine-grained specification of the structure of the text. For example, we could have control codes to delimit words, sentences, paragraphs, etc. This would be similar to tags in HTML but without the use of printable characters to represent the tags.

Why don’t we do this now? One objection is that files containing control characters are not human readable. I think that this is a lame excuse, because no computer file is human readable. Although my hard drive is enclosed, preventing me from examining the files on there, I have burned text files to DVD, and no matter how long I stare and squint at the shiny bottom, all I can see is my own reflection. Anyway, a lot of markup is human readable only in the sense that Derrida is human readable: there is a series of legible text characters, but do you really want to wade through all the crap to make sense of it?

Perhaps the real point underlying this objection is that control-character delimited text would not be readable by simple (i.e., dumb) text editors. This is true, but why should we be ruled by the lowest common denominator? Many modern text editors are quite intelligent and could handle the new format easily. They can already parse various forms of syntax and highlight them for the user. Let’s not let backward compatibility hold us back. That’s certainly not the Apple Way. It’s not entirely the Microsoft Way either; after all, the Word file format makes no concession to simple text editors. Neither does the cross-platform Adobe PDF.

The most powerful objection to using control characters as text delimiters is that we shouldn’t force users to learn how to input control characters along with text. I agree, which is why I think the burden should be placed on computer programs — the text editors and command line interpreters — rather than on users. When taking text input from users, an app should do the following:

  1. Use the context to guess the user’s intention.
  2. Give a visual indication of the guess to the user. Syntax coloring is one example, but the possibilities are endless. Be creative.
  3. Make it easy for the user to correct bad guesses.

In command line interpreters, by the way, there’s no good reason why the space key needs to separate arguments, as opposed to a key for a non-printable character such as escape. It’s the 21st century, by Jove, and we should be finally be able to use any printable character in a file name, including colons, quotes, slashes, and spaces, without having to do voodoo on the command line just to refer to it! (I won’t even mention hierarchical file systems, which are themselves a bad idea. Oops, I just did. Since I mentioned it, the ideal behavior when a user enters a file name is to quickly find the named file or files, which any decent file system should be able to do, and show a visual preview so that the user can verify or choose the correct file, if necessary.)

This rant has been brought to you by BBEdit. The makers of BBEdit, I assume, take no responsibility or credit for the content here, nor do they endorse the opinions I’ve expressed. (Or do they?)

(No, not as far as I know, which is nothing. In any case, I do endorse BBEdit.)

CSS tips for HTML

Thursday, November 9th, 2006

I apologize for the absence of posts recently. I’m not dead! I just thought I’d go for a walk. I was feeling the pressure to be funny constantly, so I’ve contracted with Bobcat Goldthwait to ghostwrite my blog posts for me. Umm, I-I-Arrgh, I want a yacht!

During the hiatus, I’ve also been redesigning my web site. Superficially it looks similar, but under the hood it’s now almost entirely hand-coded (with Smultron). The only iWeb-generated code I kept was the JavaScript photo slide show. The benefits of the redesign are that the pages should load faster, and it’ll be easier for me to update the content, as I just did by adding a link to Mac OS Forge, which has finally emerged from its beauty sleep.

In honor of our new site styles, the subject of this post will be CSS. Sorry, folks, one cannot live on Cocoa alone! One also requires marshmallows, and Fritos. You may have heard of collapsing margins, which occurs in a number of contexts, for example, on election day. It also occurs when the bottom margin of a block-level element on a web page adjoins the top margin of another block-level element. The two margins collapse, and the length of the displayed margin becomes the length of the larger of the two adjoining margins. This can be useful, because typically you want a minimum margin around a paragraph of text, and you want a different minimum margin around a heading, but you don’t want a huge gap between the heading and the first paragraph. (Unless you’re trying to turn 8 pages of actual writing into a 15-page term paper. I know who you are, slackers! I was a teacher. Your grade will reflect your ef-fort.)

What you may not realize is that collapsing margins also occurs when the top margin of a block adjoins the top margin of its parent block. If you load the following HTML in a browser, such as Safari or Camino, you’ll see a purple box at the top of the window.


<html lang="en-US">
<head>
<title>Collapsing Margins</title>
<style type="text/css">
body {
	background-color: #000000;
	margin: 0;
	color: #cccccc;
}
#all_content {
	background-color: #590079;
	margin-top: 0;
	margin-bottom: 0;
	margin-left: auto;
	margin-right: auto;
	width: 40em;
	height: 40em;
}
p {
	margin-top: 1em;
	margin-bottom: 1em;
}
</style>
</head>
<body>
<div id="all_content">
</div>
</body>
</html>

This is to be expected, because body and all_content both have top margins of 0. However, if you add a paragraph, <p>This is a paragraph.<p>, inside the element all_content, something unexpected happens. Instead of the purple box at the top of the window with the paragraph spaced from the top of the box, you see the purple box spaced from the top of the window with the paragraph at the very top of the box.

The margins of the paragraph are supposed to be calculated relative to its containing block, which in this case is the element all_content, so you would expect that the margin should appear between the paragraph and the box rather than between the box and the top of the window. The reason the opposite occurs is that even though the box has a top margin of 0, the top margin of the box and the top margin of the paragraph are technically adjoining, which means the margins collapse, and the one true margin becomes the larger of the two top margins. Since margins are transparent, the black background shows through.

The CSS specifications for collapsing margins are, to put it frankly, idiotic. Or to put it more tactfully, they’re insane. Who in the world wide web would want the top margins of parent and child blocks to collapse? I gave the paragraph a non-zero top margin because, well, I wanted it to have a non-zero top margin! I don’t blame the browser developers for complying to the standards; web designers demand and expect the browsers to be standards-compliant. Rather, I blame the standards developers for developing substandard standards. I can’t imagine what they were thinking. Anyway, the workaround for this bug, as I shall call it, is to give the parent block, in this case all_content, a non-zero border-top or padding-top. If the parent has a border or padding, then the top margin of the child does not adjoin the top margin of the parent, the margins do not collapse, and all is right with the world again.

Speaking of standards-compliance, I used to consider Mozilla’s Gecko, the rendering engine behind Camino and Firefox, the standards king. Perhaps it was, in the early days of Safari. I believe that Gecko has lagged behind while WebKit, the rendering engine underlying Safari and Vienna, among others, has caught up and surpassed it. While testing my web site in Camino, I ran into a couple of problems. First, Gecko doesn’t handle the inline-block display property. This bug has been open since 1999. I would advise web designers not to use inline-block if they want their pages to display properly in Gecko browsers.

Second, there is a bug, open since 2004, in how Gecko calculates percentage margins for a float with width: auto. You can see this by comparing how my résumé looks in Safari and Camino, under the “Degrees” heading, for example. (Is this a ploy to get you to read my résumé? No, just a happy coincidence.) Percentage margins are supposed to be calculated relative to the size of the containing block, but Gecko calculates them relative to the size of the float, so that the width of the margin is a percentage of the sum of the widths of the float and margin. This makes the margin far too small. My workaround, as you can see in the HTML source, was to increase the margin’s percentage size somewhat. It still looks too small in Camino, but I don’t want to make it too large in Safari. Although I could have used a table in this situation rather than floats, it made much more sense semantically to arrange the content by columns rather than by rows.

I hope that you enjoyed my rants, err, tips. I promise to talk about Cocoa programming in the next post. I also promise to lower taxes, raise spending, balance the budget, ask not what my country can do for me, fear nothing but fear itself (that is, the form of fear, not those shadowy particular fears), put a chicken in every pot, a car in every garage, and a kitten in every lap. Of course, this all depends on what the meaning of the word “I” is. I want a yacht. Thank you very much. Argh.