AdSense Mobile Ad

Sunday, October 4, 2009

(Poor man's) Web redirection using a servlet filter

A couple of months ago I bought another domain because we're just in the middle of a re-branding and, obviously, the domain name was one of the first things to choose. We will keep the old domain in order to ease the migration of the systems we're running. Migrating the web was easy but, nowadays, there's some people who's resisting the re-branding process and who's still using our old name and our old domain.

After consulting the company that hosts our old domain, they answered this: 2.5 Eur/Month for web and email redirection. Since we don't need mail redirection, paying a couple of bucks just to send a couple of HTTP headers seemed much to me, that's why I decided to do it myself.

Setting up Sun Java System Application Server on Solaris 10

First of all, I set up a new sparse and shared-IP zone. At the end of the installation I checked the startup script for the Sun Java System Application Server that ships with Solaris 10. If you need a Java application server, you'd better go and install the latest version. As I'm going to run just one servlet filter, using the bundled server seemed like fine to me.

The bundled server is installed in /usr/appserver and isn't either SMF-managed:

$ svcs S84appserv
STATE          STIME    FMRI
legacy_run     Mar_13   lrc:/etc/rc3_d/S84appserv


If you examine the startup script, you'll notice that it looks for domains installed in the /var/appserver/domains directory. Of such domains, this scripts starts those who configured the autostart feature, which is simply an empty file named [domain-dir]/config/autostart.

Creating a domain

To create a domain you need to use the /usr/sbin/asadmin command. In my case, I used the following command:

/usr/sbin/asadmin create-domain --domaindir /var/appserver/domains --adminport 4848 --adminuser admin --instanceport 8080 --savemasterpassword=true my-web

  • --domaindir /var/appserver/domains is necessary to create the domain in the directory searched by the legacy startup script.
  • --adminport and --instanceport are used to configure the ports used respectively by the admin console and the applications you'll deploy in this domain.
  • --savemasterpassword, or an equivalent technique, is necessary because the startup script is non interactive and cannot ask you about the master password.

Once the domain was done, I touched the autostart file to trigger the startup of the domain:

$ touch /var/appserver/domains/my-web/config/autostart

You can now start your domain by using the startup script:

# /etc/rc3.d/S84appserv start

To test your installation you can use your favorite browser to connect to the admin console on the port you specified (in this case, 4848) or to view the welcome file (on port 8080).

Creating a redirecting servlet filter

To redirect clients' HTTP requests to the new domains we just need to send a HTTP 301 status code (moved permanently) and the new location in the Location HTTP header. Omitting the boiler plate code of a standard Java Servlet filter, the code is just a two liners:

response.setHeader("Location", "http://www.newdomain.es/");
response.setStatus(response.SC_MOVED_PERMANENTLY);

Please note that the setHeader and the setStatus method aren't methods of the ServletResponse class: they're included into the HttpServletResponse class.

The last thing to do is mapping the filter in the web module deployment descriptor:

$ cat WEB-INF/web.xml

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    <filter>
        <filter-name>RedirFilter</filter-name>
        <filter-class>es.reacts.filters.RedirFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RedirFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

The application server bundled with Solaris 10 will complain with an not so intuitive "Unsupported minor.major 49.0 error" if you don't compile your application with a Java 1.4 compiler. Once this was done, you just have to deploy the web module into your server in the root (/) context path.


Setting up the network

The last part of the job was setting up the network. First of all, I removed the DNS A record identifying the www machine (which pointed to our hosting company web server) and substituted with a CNAME pointing to the machine of ours where I deployed the Java web module and then I configured our border router to map port 80 to the port where the Sun Java System Application Server is listening.

Manipulating URIs before redirecting

The filter described so far redirects a request to the root of an application to another URL. The basic problem with this example is that, if a client requests an URI beneath the root of an application, unless such URI is mapped to a valid resource into the application, the application server will return an HTTP 404 status code (not found). The filter semantics is such, indeed: they're executed before the request is handled by its target and, if it does not exist, they're not triggered at all.

To avoid such problems, if you want a catch-all redirection, or if you prefer to process the request before redirecting it, you can deploy a servlet and map it to the URIs you want to catch. And if you want to catch them all, mapping /* is all you need.

The final version of the web.xml of the web module I deployed is the following:

<?xml version="1.0" encoding="UTF-8"?>
<web-app version="2.4" xmlns="http://java.sun.com/xml/ns/j2ee" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://java.sun.com/xml/ns/j2ee http://java.sun.com/xml/ns/j2ee/web-app_2_4.xsd">
    
    <filter>
        <filter-name>RedirFilter</filter-name>
        <filter-class>es.reacts.filters.RedirFilter</filter-class>
    </filter>
    <filter-mapping>
        <filter-name>RedirFilter</filter-name>
        <url-pattern>/*</url-pattern>
    </filter-mapping>
    <servlet>
        <servlet-name>Default</servlet-name>
        <servlet-class>es.reacts.servlets.Default</servlet-class>
    </servlet>
    <servlet-mapping>
        <servlet-name>Default</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
    <session-config>
        <session-timeout>
            30
        </session-timeout>
    </session-config>
    <welcome-file-list>
        <welcome-file>index.jsp</welcome-file>
        </welcome-file-list>
    </web-app>

A Virtual Hosts based solution

As I described in another post, if you're an Apache HTTP Server user, there's an out-of-the-box, more flexible and easier solution: Virtual Hosts.


Wednesday, September 30, 2009

iPhone user experience: is it ready for a color-blind person?

I own an iPhone since a couple of months and I must admit that, as far as it concerns my user experience as a color-blind person, it is the best mobile device I worked with in a long time. It isn't perfect, though.

If you're wondering what color-blindness is, you can start reading this Wikipedia article. I seldom notice the effect of such an impairment and when I do, I'm usually interacting with a computer.

There exist many forms of color blindness and mine is called protanopia. Protanopia differs from other forms, such as deuteranopia, because we experience an abnormal dimming of light at some wavelength with the result that, for example, red is easily confused with black.

In the case of the iPhone, I must admit that I'm experiencing just one problem: missed calls. There's a fancy icon down there indicating the number of unchecked missed call. When you open the corresponding window, guess what? Missed calls are "highlighted" using the good ol' red fonts while received or dialed calls are black. The background? White, just to make it worse. I tried looking for some other color scheme but there's none. Just the good ol' "iPhone experience" that Apple is providing us.

This rare impairment affects almost 1% of the male population. Not much, indeed. But for us, there are no red characters to catch our attention. They just fade to black, hiding between the others. If you're working with a color-blind person, please follow good sense: don't rely on colors and please, do not use red to catch their eyes. Just rely on the tools your word processor is offering you, such as that yellow marker whose existence you probably wondered about sometimes.

Sunday, September 27, 2009

Googlle?


As I'm a customary animal, everyday I open my browser and go along the same Internet path. As I'm a faithful Google user, one of the pages I often open is iGoogle. Today I thought my eyes were failing when I realized I was seeing the simplest and oddest Google doodle I've ever seen. Who can I ask about it? Google, of course. The first thing I did was saving that doodle to the disk and its very name gave the answer:
11th_birthday.gif.

Happy birthday Google!

Pushing gmail to your iPhone (without GPush)

As I told you some posts ago I bought GPush and struggled to make it work. At the end I started to be notified about incoming mail, although with some glitches from time to time. Now, very shortly after GPush was released, you don't need it anymore: Google Sync is now pushing mail to your iPhone.

This is really good news because now you can sync your mail, your calendar and your contacts with your iPhone. As I was already using Google Sync for contacts and calendars, setting up GMail push was really easy: just the flip of a switch!



If you haven't set up your Google Sync account on your iPhone, just follow the instructions on the Google Sync web site.

As far as I can tell, mail is pushed to the iPhone almost instantaneously. Nonetheless, there's a thing I'm not really happy about. I miss is a notification popup: no one is ever shown and the counter on the mail icon is the only information you're given when a mail is pushed:


I would expect a mail to be managed just like an SMS or even a phone call: checking periodically sort of defies the purpose of a push notification...

Thursday, September 10, 2009

Ellison's statement to Sun customers

Yes, this is marketing. But it sheds light (and hope) upon us, concerned Solaris users, who were wondering about what will happen to our favorite OS. Here's what Oracle CEO, Larry Ellison, is saying about the merger.

Bad news for HP, Dell and IBM, indeed. "We're in it to win it." Let's give Larry a chance.