karlcow

Opening The Web one bug at a time

Subscribe to RSS feed

Posts tagged with "implementation"

Flex your box

, , , ...

When talking with Web developers, sometimes the topic of Flexbox implementation pops up. It goes one of two ways.

  • “Why hasn’t Opera implemented Flexbox? It’s already there in other browsers.”
  • “When will W3C catch up with the reality of implementations?”

Depending on your mood of the day, I hit my head against the wall or I take the meditation position of a buddhist monk. The answer is basically Flexbox is not yet finished. Opera waited for the spec to stabilise. Flexbox is implemented in browsers incompatibly, and not according to whatever last version of the specification. Nobody gains from that? W3C is not late but having a specification which is a moving target (Working Drafts).

The issue is that Flexbox is not Flexbox. Opera didn’t rush on implementing the earlier Flexbox drafts. There were competing proposals on the table and it was, in this case, a good move. The current implementations of Flexbox found in other browser vendors were based on the old Working Drafts of the specification. Tab Atkins (Google) is the editor of the Flexbox specification which has changed drastically and in incompatible ways. It is part of the process of Web development which includes testing options and then revising them for better ones. Flexbox is Dead, Long Live Flexbox! by Tab gives an overview of what happened. The irony being that now Flexbox is now closer to the original specification than it was in the last series of drafts.

Well, the experiment has ended. The spec has returned to a form very similar to the original. I’m a little sad about this, but it’s the right choice. Unfortunately, if you limit yourself to making the box-model properties flexible, several useful things are simply impossible, and several others are overly difficult.

Be aware that there are still a few things which are different.

Why do I blog this?

Because there is a fine line in standardization work between something which is really deployed and something which is deployed for testing. When we are advocating for technologies, introducing new concepts, creating demos based on Working Drafts, these are likely to break at a point in time. Some features will be dropped, some will be changed a few times, or the specification and its implementation will be dropped entirely. Web developers are eager to use new shiny things. It is good for having practical Web developers feedback on the technology, but when it comes to production sites, there is a high risk.

Wrong To Be Right - application/xhtml+xml

, , , ...

Update 30 March 2011: The issue with Starbucks Web site has been fixed. There are still other sites exhibiting the issue. A fix has been proposed by Rohan Singh

I have always been experimenting with XHTML. When properly served as application/xhtml+xml, it becomes a powerful tool to check the quality of your markup. The browser will throw an error if the code is not well-formed. It doesn’t solve the accessibility or semantics issues, but it helps a bit for constraining the quality of your code. On the other hand, it introduces issues in terms of scripting if you decide to change the Content-Type at the end of the chain.

Accept and Content-Type in HTTP

A browser (client) and a server exchange messages on how to handle a specific piece of information identified by a URI. So When a client is requesting http://www.opera.com, it sends along some HTTP headers. One of these headers specifies the type of format the browser is able to process and the order in which it would like to process. This header is Accept:. Each browser has a slight different Accept: header.

Table of Accept headers for some HTTP clients
Browser Accept header
Opera Desktop 11.0 text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Opera Mobile Emulator text/html, application/xml;q=0.9, application/xhtml+xml, multipart/mixed, application/vnd.wap.multipart.mixed, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1
Firefox 4 text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Safari 5 application/xml,application/xhtml+xml,text/html;q=0.9,text/plain;q=0.8,image/png,*/*;q=0.5
curl */*
IE9 image/gif, image/jpeg, image/pjpeg, application/x-ms-application, application/vnd.ms-xpsdocument, application/xaml+xml, application/x-ms-xbap, application/vnd.ms-excel, application/vnd.ms-powerpoint, application/msword, application/x-shockwave-flash, */*

Usually the server replies with the most appropriate format matching what the client is requesting. So if the client is asking application/xhtml+xml and the server has the representation of this resource in this format it will send it along with the appropriate Content-Type, in this case application/xhtml+xml.

The issue

Some high profiles Web sites all under Microsoft IIS are behaving strangely. Let’s use curl as we did it previously and its possibility to send specific User-Agent: information and Accept: HTTP headers. We will do our tests on Starbucks Web site.

Curl Accept: /

A very simple one, curl by default sends Accept: */*. It means “send me anything you could have for this URI and I will do my best to understand it”

curl -sI http://www.starbucks.com

The server returns a Content-Type: application/xhtml+xml. Fair enough, we said we were accepting anything.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 41954
Content-Type: application/xhtml+xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.0
p3p: CP="CAO PSA OUR"
Set-Cookie: ASP.NET_SessionId=40pk0kfikyv2lnr3t10yckjl; path=/; HttpOnly
Set-Cookie: skin=; path=/
X-Powered-By: ASP.NET
Date: Thu, 03 Mar 2011 16:58:38 GMT

Curl Accept: text/html

Let’s be more precise. We will tell the server that we want text/html only.

curl -sI -H "Accept: text/html" http://www.starbucks.com/

Neat! The server returns the right Content-Type: text/html. Everything is good! This server is behaving quite well so far.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 41954
Content-Type: text/html; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.0
p3p: CP="CAO PSA OUR"
Set-Cookie: ASP.NET_SessionId=xm0t31ebosa1symnb5xn4gkm; path=/; HttpOnly
Set-Cookie: skin=; path=/
X-Powered-By: ASP.NET
Date: Thu, 03 Mar 2011 17:03:35 GMT

Opera 11.01

I will be using Opera 11.01 with these two parameters :

  • User-Agent: Opera/9.80 (Macintosh; Intel Mac OS X 10.6.6; U; fr) Presto/2.7.62 Version/11.01
  • Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1

We can use Opera Dragonfly to check the headers or use curl by mocking Opera.

curl -sI -H "Accept: text/html, application/xml;q=0.9, application/xhtml+xml, image/png, image/jpeg, image/gif, image/x-xbitmap, */*;q=0.1" -A "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.6; U; fr) Presto/2.7.62 Version/11.01" http://www.starbucks.com/

We then receive from the server Content-Type: application/xhtml+xml. As I said before, it is ok, because we said it was one of the formats we accepted.

HTTP/1.1 200 OK 
Cache-Control: private
Content-Type: application/xhtml+xml; charset=utf-8
Server: Microsoft-IIS/7.0
p3p: CP="CAO PSA OUR"
Set-Cookie: ASP.NET_SessionId=xdtworhtqlte5mxur2zeulay; path=/; HttpOnly
Set-Cookie: skin=; path=/
X-Powered-By: ASP.NET
Date: Thu, 03 Mar 2011 17:09:43 GMT

The big issue is that the server is sending to Opera a file which is obviously not well-formed XHTML and because the server said it was Content-Type: application/xhtml+xml, the XML parser fails to process a none well-formed XML (XHTML). That is a major usability issue for Opera users. Let’s continue a bit our testing.

Firefox 4

This time we will be using Firefox 4.

curl -sI -H "Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8" -A "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b11) Gecko/20100101 Firefox/4.0b11" http://www.starbucks.com/

Hmmm Amazing the server this time is answering with Content-Type: text/html. This starts to be fishy. Note that it is still a valid answer from the server. The client said it could receive both. The server decided to send html.

HTTP/1.1 200 OK
Cache-Control: private
Transfer-Encoding: chunked
Content-Type: text/html; charset=utf-8
Server: Microsoft-IIS/7.0
p3p: CP="CAO PSA OUR"
X-Powered-By: ASP.NET
Date: Thu, 03 Mar 2011 17:06:43 GMT

Stricter Firefox 4 with only “application/xhtml+xml”

This time we will ask the server to send only application/xhtml+xml

curl -sI -H "Accept: application/xhtml+xml" -A "User-Agent: Mozilla/5.0 (Macintosh; Intel Mac OS X 10.6; rv:2.0b11) Gecko/20100101 Firefox/4.0b11" http://www.starbucks.com/

Oh surprise. This time the answer of the server is wrong. The server sent back Content-Type: text/html without respecting the HTTP contract. Fishy, the server does user agent sniffing ?

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 41954
Content-Type: text/html; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.0
p3p: CP="CAO PSA OUR"
Set-Cookie: ASP.NET_SessionId=q41qfc3adwjsidjgtevpxnnk; path=/; HttpOnly
Set-Cookie: skin=; path=/
X-Powered-By: ASP.NET
Date: Thu, 03 Mar 2011 17:24:48 GMT

Opera 11 with only “text/html”

Let’s be sure about the intuition on user agent sniffing. We send Opera user agent and we require to receive text/html.

curl -sI -H "Accept: text/html" -A "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.6; U; fr) Presto/2.7.62 Version/11.01" http://www.starbucks.com/

The server sends to Opera… Content-Type: application/xhtml+xml. This time we can be sure, the server does user agent sniffing.

HTTP/1.1 200 OK
Cache-Control: no-cache
Pragma: no-cache
Content-Length: 41954
Content-Type: application/xhtml+xml; charset=utf-8
Expires: -1
Server: Microsoft-IIS/7.0
p3p: CP="CAO PSA OUR"
Set-Cookie: ASP.NET_SessionId=vfzwujvflotbibe4qet0foxb; path=/; HttpOnly
Set-Cookie: skin=; path=/
X-Powered-By: ASP.NET
Date: Thu, 03 Mar 2011 17:27:51 GMT

Why is this an issue?

Opera gets a different content-type than other browsers which could be fine if the server was sending well-formed XML. Opera is right to fail on this none well-formed content. But unfortunately because nobody cared to test that the markup was well-formed, Opera looks like if it was wrong compared to other browsers. It’s why I call wrong to be right. The consequences are terrible, because the Opera users can’t access these sites and they are penalized because we do the right thing.

What should we do?

  • We try to contact the owners of these Web sites (starbucks, spanair, phenomblue, leisurepro, mcafee, teavana, etc.)
  • We try to identify the library which is in charge of the user-agent sniffing, we have a lead for an unsupported library called MDBF
  • We could PATCH for these specific Web sites, but then we lose the benefits of pressuring the owners of fixing their sites, because they will have the impression it is working.
Really there is no perfect solution, but in the end, the Opera users do not have the freedom of choice.

Magic Strings and User Agent Sniffing

, , , ...

User Agent sniffing is bad most of the time. It creates a lot of issues. It relies on the idea that a Web site should be working only for a few browser vendors. But User Agent sniffing becomes really unacceptable when the site definitely exclude specific browsers based on their user agent string. Even more so when we realize that once the user agent string has been spoofed, it is possible to access and use the content of the Web site.

Let’s take an example from last week, the exact domain name is not important, so let’s call it: http://bad.example.com/. It always starts with one or more bug reports of Opera users saying. I’m a customer of the company Bad Inc. and I’m not able to access the Web site with my browser. Then, we check if it’s a bug in Opera or an issue with the Web site. curl is a wonderful tool to quickly test what’s goint in between the browser and the server.

So let’s start. We check with Firefox, Safari and Opera and look what is working and not working. The combination is not always the same. In this case it was working with Safari, Firefox and not working in Opera. Let’s switch to the command line. The option I in curl creates a HEAD HTTP request.

% curl -sI http://bad.example.com/
HTTP/1.1 404 Not Found

That means that the server is clearly doing “whitelist” user agent sniffing. It allows only what it knows and blocks the rest. Let’s try with a Webkit user agent string.

% curl -sI -A "Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; de-de) AppleWebKit/534.15+ (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4" http://bad.example.com/
HTTP/1.1 200 OK

It is working and with Opera?

% curl -sI -A "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.6; U; fr) Presto/2.7.62 Version/11.00" http://bad.example.com/
HTTP/1.1 404 Not Found

Not working. At this point the issue is clear the next step will be to contact the site and ask them to modify their server side user agent sniffing to include Opera or even better to include everyone else. But I was wondering what exactly triggered the user agent sniffing. For example, I tried to reduce the user agent string to Mozilla only.

% curl -sI -A "Mozilla" http://bad.example.com/
HTTP/1.1 404 Not Found

Not working that’s not it. What about Gecko?

% curl -sI -A "Gecko" http://bad.example.com/
HTTP/1.1 404 Not Found

Not working either… hmmm… ok one more try.

% curl -sI -A "Mozilla Gecko" http://bad.example.com/
HTTP/1.1 200 OK

Bingo! But what about IE it doesn’t have Gecko in its user agent string. after trial and errors I got

% curl -sI -A "Mozilla MSIE 6" http://bad.example.com/
HTTP/1.1 200 OK

with MSIE n, where the n >= 6. Put a 5 in there and it stops working. I thought ok that’s interesting what about adding these strings to Opera.

% curl -sI -A "Opera/9.80 (Macintosh; Intel Mac OS X 10.6.6; U; fr) Presto/2.7.62 Version/11.00 Mozilla Gecko" http://bad.example.com/
HTTP/1.1 404 Not Found

Hmmm. oh! One more try

% curl -sI -A "Mozilla Opera/9.80 (Macintosh; Intel Mac OS X 10.6.6; U; fr) Presto/2.7.62 Version/11.00 Gecko" http://bad.example.com/
HTTP/1.1 200 OK

Bingo! The site is working. Big smile and then head banging on the table on realizing how it is dumb. What did I say? ah yes, do not use user agent sniffing if you do not know what you are doing.

Web Standards Links: 10 January 2011 to 16 January 2011

, , , ...

Web Standards Links: 3 January 2011 to 9 January 2011

, , ,

Be Strict To Be Cool

, ,

Be Strict To Be Cool was my mail signature when I was working at W3C. It was a "clin d'œil" to the Robustness principle (Postel Law), which is basically when you send a message to someone (or a software), be very strict in the syntax and grammar of your message, when you receive a message be flexible enough to deal with bad messages as long as you can interpret it. It is what I called once the Hear-Write Web.

Opera's Open The Web is the initiative to help Web developers to fix their Web sites. It is also a way for customers to identify when Opera browsers specifically, but sometimes others such as Firefox, Safari, Chrome, and IE, do not work with a specific Web site. The ODIN team is then looking at what could be the origin of the issue. Armed with curl, View Source, and the wonderful opensource DragonFly, we explore, analyze and figure our next actions.

Sometimes, it is really a browser bug, which is being taken care of by implementers at Opera. But most of the time, the issue is related to bad server settings, bad user agent sniffing, javascript mistakes, rogue server side libraries, etc. Some cases are mind boggling. Proxy and routers introduce their own share of issues too. The most difficult task is not being to analyze the issue but to find the right contact for the Web site. A person who will understand what you are talking about. The communications and marketing departments of big companies are more responsive and very helpful. Something going wrong on their Web site is less customers.


Looking at this daily pile of bugs and issues, I thought today that it might be interesting to collect them little by little and explain them. The goal is not to create a wall of shame, but to help Open The Web by giving hints to Web developers on what has been done wrong in their settings, developments, etc. Often, they just do not realize because it is a case that they never experienced. Everyone is making mistakes. What I'm interested in is how collectively, we leverage our knowledge for creating a better Open Web.

Production of Cookies for Web Developers

, ,

Some cookies are really bad for your health and you have to be careful when you cook them. A very simple cookie looks like that when the server sends it to the client:

Set-Cookie: cookieName=cookieValue

but more often it will looks like this

Set-Cookie: cookieName=cookieValue; Path=/; Domain=example.org

Sometimes they will contain an Expire date.

Set-Cookie: cookieName=cookieValue; Expires=Wed, 09 Jun 2021 10:18:14 GMT

Cookies are defined in the specification 2695 and now in the specification HTTP State Management Mechanism currently written by Adam Barth. The production rules for the servers are strict and defined in the section 4.1. Set-Cookie.

These are a set of rules you have to check when you are coding either javascript or your Web framework to produce cookies.

  • Set-Cookie:SP The space is important. US-ASCII SP (octet 32)
  • cookieName any US-ASCII characters except control characters (octets 0-31) and DEL (octet 127) and, the following characters “(“, “)”, “<”, “>”, “@”, “,”, “;”, “:”, “", “/”, “[“, “]”, “?”, “=”, “{“, “}”, the double quote character itself, US-ASCII SP (octet 32) or the tabulation (octet 9)
  • = no space before and after.
  • cookieValue same than cookieName

Then optionally you can add

  • ;SP The space is important
Just a little reminder because this morning I stumbled across a cookie which was badly defined on a Website:
Set-Cookie: {$aaa|xxx:"zzz"}=foo
the characters {, }, " and : are forbidden here.

Web Standards Links - 13 December to 19 December 2010

, ,

Promoting interoperability is at the heart of Open The Web.

Web standards

Extensions - Add-ons

Mobile

SVG

  • SVG cursors hmmm. Not sure about this wink The era of whizbang cheesy animated smil cursors?

CSS

HTTP

Accessibility

Javascript

HTML5

Opera

Speaker Lust

  • SlideDown Yet Another slidemaker tool. Markdown Syntax and Ruby driver
  • On Speaking
  • SudWeb A conference about Web technologies in the South of France (Nîmes) on May 27, 2011. Call For Speakers before February 7, 2011
  • UX Web. on May 26, 2011. Same place than SudWeb. Call For Speakers before February 28, 2011

Web Standards Links - 6 December to 12 December 2010

, , , ...

WebSoket

HTTP

CSS

I18N

SVG

Web Standards

HTML5 et Web Apps

Javascript

Privacy

Linked Data - Semantic Web

Experimental Stuff

Opera

Opera Mini and Mobile Orientation Switching

, , ,

Caleb, a former colleague, testing the Pheromone Lab Web site on Opera Mini told me: "When you switch from Portrait Mode to Landscape Mode, the page is not resized to the full width of the viewport." Indeed. Was it a bug in his CSS or a bug on Opera Mini? Neither. But first you need to understand what is Opera Mini.

Opera Mini has its main rendering engine (the software which interprets html, CSS, javascript, …) not on the mobile device but on a distant Opera server. When you type an address such as http://example.org/, a request is sent to the Opera Server, which is acting as a client for the Web site on http://example.org/. The Web site sends back an answer to Opera server, which interprets it and make an OBML file. OBML stands for Opera Binary Markup Language which creates a kind of compressed image of the Web page (sometimes 90% of size reduction).


Image from A developer’s look at Opera Mini 5

When you switch the orientation of the device. Opera Mini has just an image to rotate and not the full code to reinterpret for fluid and flexible layouts. You then need to reload the pages so that it is resized for the new landscape mode of the mobile device.

If you need to test your own design with Opera Mobile and Opera Mini, go to the Developer Tools page. You will find an Opera Mobile emulator (full Browser) or the Opera Mini Simulator and the ultimate tool for debugging: DragonFly.