GeckoFilter C version

typedef struct
      HttpDir super; /* GeckoFilter inherits from HttpDir */
      /* The original HttpDir service function, which we will overload. */ 
      HttpDir_Service orgServiceFunc;
} GeckoFilter;

   The C code constructor
GeckoFilter_constructor(GeckoFilter* o,
                        const char* dirName)
   /* Run super class constructor */
   HttpDir_constructor((HttpDir*)o, /* Manually downcast to super class */

   /* Overload the original service function and save the original
    * service function in orgServiceFunc. We need the original
    * service function in our GeckoFilter_doService, see below.
   o->orgServiceFunc = HttpDir_overloadService(

/* Our service function is called when the Virtual File System delegates
   a client request to the GeckoFilter.
static int
GeckoFilter_doService(GeckoFilter* o,
                      const char* relPath,
                      HttpCommand* cmd) 
   /* Extract the HTTP parameter "User-Agent". The user agent tells us which
    * browser that is doing the request.
    * The "User-Agent" string for Mozilla looks like:
    * User-Agent: Mozilla/5.0 (Windows; U; Windows NT 5.0; en-US; rv:1.4) Gecko/2003024
   HttpRequest* request = HttpCommand_getRequest(cmd);
   HttpResponse* response = HttpCommand_getResponse(cmd);
   const char* userAgent = HttpRequest_getHeaderValue(request, "User-Agent");

   /* Check if the string contains "Gecko", which tells us if this is a
    * Gecko based browser such as the Mozilla Web-Browser.
   if(userAgent && strstr(userAgent, "Gecko"))
      /* Yes this is a "Gecko" based Web-Browser.
       * Let the original service function complete the request.
      return (*o->orgServiceFunc)((HttpDir*)o, relPath, response);
      /* No, this is NOT a "Gecko" based Web-Browser. */
      /* Deny the request */
                              403, /* 403 Forbidden */
                              "You do not use a Gecko based browser");

      /* Barracuda makes it possible to have duplicate directories. If one
       * branch cannot find the requested page, the next bransh with the same
       * name is searched. "Not found" is signalled by returning -1. We want
       * to stop the seach since we already sent a response. We signal
       * success, "page found", by returning 0.
      return 0;