Youtube: Detecting X-Frame-Options/framebreaking in Python

My current project involves URL shortening. Like many URL shorteners, we wanted to get into frame bars. These are alternately called banners, share bars and "eyebrows". It's basically just putting some small content on the top of the screen, and then wrapping the "real" content in an IFRAME that takes the rest of the screen. Maybe you've seen when LinkedIn does this.

Now, I'm not crazy about the ethics of framing other peoples' content. I'm not even convinced that it would not be ruled illegal some day. In any case, lot's of people are doing it, and we decided we needed to be doing it too. In my case, we're just showing you who shared it, we're not doing ads or anything.

Understandably, many sites don't want you to frame their content. This has lead to a kind of arms race, where content sites use javascript to try to break out of the frame (aka framebreaking), and then the wrapper sites try to break the framebreaker.

This eventually lead to full-fledged support at the browser level for framebreaking, in the form of the X-Frame-Options header. Essentially, a site can publish this HTTP header on all their content, and most modern browsers will display an error/warning if the content is put into a frame (or, at least a frame on another domain). In Firefox, this looks like the following.

This is actually a pretty cool development. However, in order to provide a good user experience when you're frame barring (is that an oxymoron?), you ideally would detect ahead of time whether the site you're framing has this X-Frame-Option set, and just redirect to the content in that case.

Here is some Python code that does just that. It basically just makes an HTTP call to the content server to server.

def is_framing_allowed(url)
   request = urllib2.Request(url)
   request.add_header("Referer", "http://example.com") # you should put your real URL here
   opener = urllib2.urlopen(request)
   # returns True if ANY x-frame-options header is present
   # the only options at present are DENY and SAMEORIGIN, either of which means you can't frame
   return "x-frame-options" in opener.headers.dict

Notice that I'm setting a Referer here. Youtube in particular requires that this be set before it will serve a x-frame-options header:

curl "http://www.youtube.com/watch?v=kdoCBJe0F3o" -D headers.txt >/dev/null 2>&1; cat headers.txt
HTTP/1.1 200 OK
Date: Fri, 21 Jan 2011 18:35:39 GMT
Server: wiseguy/0.6.7
X-Content-Type-Options: nosniff
Set-Cookie: use_hitbox=72c46ff6cbcdb7c5585c36411b6b334edAEAAAAw; path=/; domain=.youtube.com
Set-Cookie: VISITOR_INFO1_LIVE=nMjwYxkZq0Q; path=/; domain=.youtube.com; expires=Sun, 18-Sep-2011 18:35:39 GMT
Set-Cookie: recently_watched_video_id_list=7291701d6005203af93186bd50b882b5WwEAAABzCwAAAGtkb0NCSmUwRjNv; path=/; domain=.youtube.com
Set-Cookie: GEO=1fe4b343c2bea46a564b0990ff037b32cwsAAAAzVVPRyoNiTTnR+w==; path=/; domain=.youtube.com
Expires: Tue, 27 Apr 1971 19:44:06 EST
Cache-Control: no-cache
Content-Type: text/html; charset=utf-8
Transfer-Encoding: chunked

curl "http://www.youtube.com/watch?v=kdoCBJe0F3o" -e "http://example.com" -D headers.txt >/dev/null 2>&1; cat headers.txt
HTTP/1.1 200 OK
Date: Fri, 21 Jan 2011 18:35:55 GMT
...
X-Frame-Options: SAMEORIGIN