Search code examples
customizationg-wanhttp-error

Custom 404 response for GWAN


When people request a servlet that is not found on csp folder it will show a "404 Not Found" Response

Not Found

The requested URL was not found on this server.

is there a way we can check a servlet exists or not, to create custom 404 page?


Solution

  • Just like Gil said. You can use HDL_HTTP_ERRORS to intercept HTTP errors. To make it more clear here is a sample connection handler that replaces 404 error with a custom error message.

    #include "gwan.h" 
    int init(int argc, char *argv[])
    {
       u32 *states = (u32*)get_env(argv, US_HANDLER_STATES);
       *states =  (1 << HDL_HTTP_ERRORS);
       return 0;
    }
    
    int main(int argc, char *argv[])
    {
       if((long)argv[0] != HDL_HTTP_ERRORS)
          return 255; // Continue if not an error
    
       // get the HTTP reply code
       int *status = (int*)get_env(argv, HTTP_CODE);
       if(!status || *status != 404)
          return 255; // Continue if not a 404 error
    
       static char custom_err[] = 
          "<!DOCTYPE HTML><html><head><title>404 Not Found</title><meta http-equiv=\"Content-Type\" content=\"text/html; charset=utf-8\"><link href=\"/imgs/errors.css\" rel=\"stylesheet\" type=\"text/css\"></head>"
          "<body><h1>Not Found</h1>"
          "<p>This is a custom 404 not found error. What makes you think that this link exist?!!</p></body></html>";
    
       static char header[] = 
          "HTTP/1.1 %s\r\n"
          "Server:  G-WAN\r\n"
          "Date: %s\r\n"
          "Content-Type:  text/html; charset=UTF-8\r\n"
          "Content-Length: %u\r\n\r\n";
    
       int len = sizeof(custom_err)-1;
       char *date = (char*)get_env(argv, SERVER_DATE);
       // Set our http reply headers
       build_headers(argv, header,
                 http_status(*status),
                 date, // current server date
                 len); // Reply length
    
       // Set our reply using our custom error
       set_reply(argv, custom_err, len, *status);
    
       return 2; // End request then send reply
    }
    
    void clean(int argc, char *argv[]) {}
    

    Take note if you are returning a 404 error from a servlet. Make sure you do a

    xbuf_empty(get_reply(argv));
    

    to empty the contents of the reply buffer. It will not reach HDL_HTTP_ERRORS if there are any content on the reply buffer. It will just reply with whatever the reply buffer has.