Block Bell's or Rogers's DNS hijacking (domainnotfound.ca)
Friday, July 31, 2009
Yesterday night, while surfing around, I noticed that when a domain name wasn't registered I was being redirected to a Bell search page, a page coming from domainnotfound.ca. If you haven't seen it, it looks like this:
When I saw it, I thought my computer was infected with a virus. After looking around my computer for a few minutes, I figured out what was going on. Bell is hijacking invalid or non-existing DNS entries to display, likely, sponsored search results via their network. Note that I was trying to go to someone's LinkedIn profile and also note how this DNS hijacking process is now telling me that LinkedIn doesn't exist, when it clearly does.
I knew that Rogers already did this, but I don't use Rogers, so I've never seen it in action. But now that Bell is doing, I can see clearly that I don't like it.
First, Bell doesn't ask if you want to participate in this practice. Second, if there is any link sponsorship, I don't see any money coming my way. Third, I already pay for my internet service, so I don't think I should unwillingly become another source of revenue for Bell.
I'm not sure if anyone else out there cares that this traffic shaping happens. I'm not even sure if anyone has noticed. However, there is something you can do, and it's doesn't involve using OpenDNS--read their
privacy policy first: they can see everything you do and they say that they will sell that information (in fact, that's their business model).
An easier solution is to modify your
hosts file in your computer. Your
hosts file helps your computer connect to servers faster, by bypassing the process of DNS table look ups (if you don't know what this means, don't worry about it). So, modify your
hosts file to look like this:
# Copyright (c) 1993-2006 Microsoft Corp.
#
# This is a sample HOSTS file used by Microsoft TCP/IP for Windows.
#
# This file contains the mappings of IP addresses to host names. Each
# entry should be kept on an individual line. The IP address should
# be placed in the first column followed by the corresponding host name.
# The IP address and the host name should be separated by at least one
# space.
#
# Additionally, comments (such as these) may be inserted on individual
# lines or following the machine name denoted by a '#' symbol.
#
# For example:
#
# 102.54.94.97 rhino.acme.com # source server
# 38.25.63.10 x.acme.com # x client host
127.0.0.1 localhost
127.0.0.1 www.domainnotfound.ca
127.0.0.1 bellcanadaassist.infospace.com
127.0.0.1 assist.infospace.com
::1 localhost
The servers that you need to block are
www.domainnotfound.ca,
bellcanadaassist.infospace.com, and
assist.infospace.com.
Technically speaking, you are not really blocking them; what's happening is that whenever a request to either one of these severs is executed, it resolves the address to your machine (127.0.0.1).
Where is this magical
hosts file? In Vista is in
C:\Windows\System32\Drivers\etc
.
Before modifying this file, make a backup of it. Then add these 3 lines to it:
127.0.0.1 www.domainnotfound.ca
127.0.0.1 bellcanadaassist.infospace.com
127.0.0.1 assist.infospace.com
Save the file, and that's it.
With this minor change, Bell can't hijack your mistakes. And don't bother with Bell's "opt-out" option: it still does the hijacking and the company knows that you made a mistake, but it doesn't do the search because a cookie is set to not go to the search page. In other words, opt-out is not really an opt-out option.
If you are a Rogers user, you'll need to figure out which servers are doing the DNS hijacking, but the solution is the same.
Labels: Bell DNS, DNS hijacking
Struts 2 REST Plug-in with HTTP Accept header
Sunday, July 26, 2009
Out of the box, the Struts 2 REST plug-in doesn't handle the HTTP
Accept header. This is a problem if you want to create a true RESTful Java web service, which is supposed to use the communication protocol for content negotiation between client and server.
What the plug-in offers is content negotiation via the URI, which is not a RESTful call. For example, assume that we have a URI that returns a list of users, like so
/users. If we wanted to use the provided content negotiation of the plug-in, and if we wanted an XML representation, we would use the GET request
/users.xml. The plug-in makes the automatic conversion of the model in an action class, provided that we implement the
com.opensymphony.xwork2.ModelDriven
interface (I'll cover how below). The plug-in also provides automatic JSON model representations, with a call to
/users.json. On the plus side, we can extend the plug-in's MIME type handlers (I won't cover this here); nevertheless, whatever you do, the framework will not handle the
Accept header of the HTTP request.
Can we use Struts 2 with the REST plug-in to properly handle the
Accept header? We can, but we have to code around the plug-in's limitations. There are two ways of doing this: on the one hand, we can code a Struts 2 interceptor; on the other hand, we can do what I will explain below. None of the 2 choices available are out of our reach; however, the following solution is easier to understand.
This is the code (see below for the details):
import javax.servlet.http.HttpServletRequest;
import org.apache.struts2.convention.annotation.Result;
import org.apache.struts2.convention.annotation.Results;
import org.apache.struts2.interceptor.ServletRequestAware;
import org.apache.struts2.rest.DefaultHttpHeaders;
import org.apache.struts2.rest.HttpHeaders;
import com.opensymphony.xwork2.ModelDriven;
public class UsersController
implements ModelDriven<Object>, ServletRequestAware {
private String representation;
private HttpServletRequest request;
// GET /users
public String show() {
String acceptHeader = request.getHeader("Accept");
if (acceptHeader == null || acceptHeader.isEmpty()
|| acceptHeader.equals("application/xml")) {
representation = BACK_END_SERVICE.getXML();
} else if (acceptHeader.equals("application/json")) {
representation = BACK_END_SERVICE.getXML();
}
return "SUCCESS";
}
public String getRepresentation() {
return representation;
}
public Object getModel() {
return representation;
}
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
}
This is what's happening: first, we make the action class request aware by implementing the interface
org.apache.struts2.interceptor.ServletRequestAware
; second, in the method handling GET requests for the URI
/users (the
index()
method), we grab the value of the
Accept header of the HTTP request; and, third, we make a decision as to which representation we need to send, depending on the client's preference.
Let me first talk about handling of the Accept header, and then I'll explain the
ModelDriven
interface.
Like I explained above, we need to implement the
org.apache.struts2.interceptor.ServletRequestAware
interface. Struts 2 action classes don't make the HTTP request object available unless specifically told to do so. Once this interface is implemented we get access to the
javax.servlet.http.HttpServletRequest
instance; the instance is available in the private variable
request
. When the action class is instantiated by an HTTP request, the framework updates the reference with this method:
public void setServletRequest(HttpServletRequest request) {
this.request = request;
}
We now have access to the request instance of the action class, and, therefore, we have access to the HTTP
Accept header, as follows:
String acceptHeader = request.getHeader("Accept");
We now decide what representation to send: if the value of the header is empty or
application/xml
, we use our backend service to get an XML representation; if the value is
application/json
, we get a JSON representation. I'm highlighting the method here:
public String show() {
String acceptHeader = request.getHeader("Accept");
if (acceptHeader == null
|| acceptHeader.isEmpty()
|| acceptHeader.equals("application/xml")) {
representation = BACK_END_SERVICE.getXML();
} else if (acceptHeader.equals("application/json")) {
representation = BACK_END_SERVICE.getXML();
}
return "SUCCESS";
}
And there you have it. Our web service is now able to properly handle the HTTP
Accept header. More important, GET requests to
/users are now RESTful calls that don't rely on the URI for content negotiation.
I said I was going to talk about the
com.opensymphony.xwork2.ModelDriven
interface. This interface is not part of the REST plug-in; it's actually part of the Struts 2 framework. The interface is useful for the cases when your action class is not the actual model of the application. In other words, your action class references an actual value object class. So implementing the interface means letting the framework know what type of object to work with for every request (the details are out of the scope of this entry, but it uses reflection to massage the model object). In my example here, I'm letting the action class know that my model is a
String
object with a name of
representation
. The model gets set with the only implemented method of the interface, as follows:
public Object getModel() {
return representation;
}
So, how does the plug-in provide automatic representations with URI calls? This is where the model comes into play. The REST plug-in has content handler classes that read in the model to automatically convert it into an XML or a JSON structure. It's a pretty neat trick; however the functionality is limited, because it's conceivable that we don't want our Java models to be directly represented as XML structures to the client--that would be opening our API too much and violates code encapsulation.
As an aside, a Struts 2 action class is called a REST controller when we are talking about the REST plug-in; however, a REST controller class is the same thing as an Struts 2 action class. The differentiation just makes it easier to distinguish between other action classes in a project.
In my book, RESTful Java Web Services, I use Struts 2 together with the REST plug-in to code a RESTful web service. I also cover this very limitation among others.
Goals and more goals: 50, to be exact; all from Messi
Friday, July 24, 2009
For the last 2 months, I've been coaching my son's under-9 soccer team. It's been a great season. We've had great weather, with a couple of rainy days, but we managed to play a lot of games.
From the beginning, my first goal was to get the kids playing soccer, as opposed to having then running around the ball at all times--like little bees around honey. My second goal was for the kids to have fun. Fun being the most important aspect of any activity at this age. Overall, I think everyone enjoyed playing and everyone learned some of the basics of the game. We lost more games than we won, but the ones we won we won with style. The games got intense, and real technique started to show up.
I'll continue coaching Gabe's teams for as long a he wants to play the game. It delays our summer vacation by a couple of weeks because I have to be there for every game, but it's not a big deal. I enjoy the coaching part. The whole experience brings me back to when I was kid and I was part of the soccer school in
El Flor Blanca (if you look closely, you can see pools where I first learned how to swim). Things were a bit more serious, with 3 different coaches at all times, but at that age is was great to just run around a real soccer stadium.
Now, back to Messi's goals. Perhaps I wrote too long of an introduction than these 2 videos require, but if I were a kid, I'd watch them over and over. Well, even now I still watch them over and over--we can all appreciate real talent at any age.
Part 1Part 2
The importance of a familiar user interface
Thursday, July 23, 2009
When I began writing
this book, I noticed that for the first chapter I was really tense all throughout. My shoulders were tight, my lower back was hurting, my neck was stiff. If I was to have a good experience, I had to do something.
I decided that I needed a new desk, so I got
one, even though the one I had was adequate. After some tweaking and obsessing about the proper ergonomic settings for 2 weeks, I finally found the right height not only for my desk but also for my
chair. Bliss at last, I thought. Not so.
I continued to have a stiff neck. I blamed my bed, my pillow, and my posture. I tried everything, but nothing worked. In the end, I found out why I was having such a terrible time.
What was the problem?
While writing in my writing journal, in the middle of writing the book, I noted that I was enjoying more writing it (a blog like interface) than writing the book (Microsoft's Word interface). But I don't attribute my tense neck entirely to Word's user interface--though, I think Office's UI is too busy now. The problem, it appears, was mental, and it had do with my past experiences.
When I began writing the book I was using Word's "Print Layout." This layout uses the book template the publisher sent me. The thing looks too much like the real thing and this was making me nervous, and, therefore, I was tensing up.
What was the solution?
In my effort to calm down, I tried to understand why I enjoy writing in the first place. More important, I tried to understand why I was tensing up while writing the book. And it hit me: I enjoyed more writing in my blog because I like the freedom of blog writing; it looks so free flowing. I mean that it doesn't look like anything, except black letters on a white canvas. So I switched Word's document view from "Print Layout" to "Web Layout," and I now write freely, without the constraint of a page view. Furthermore, whatever I'm writing doesn't look like a book, but a friendly note that comes out of nowhere.
Of course, I know that what I'm writing will be published in print, but the mind is an interesting thing. Training and past experiences have more of an effect than we would like to admit. In my case, I began writing on the web, without book templates; therefore, I'm at ease when words just keep accumulating at the end each line without page breaks. I can, literally and figuratively, write anything that comes to mind, and I can do it with a relaxed neck.
This is what the
Print Layout looks like:
And this is what the
Web Layout looks like:
This guy is good: Zlatan Ibrahimovic
Saturday, July 18, 2009
This is the newest (
alleged) signing for Barcelona FC: