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.
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