mongoose-web-server

How can I redirect 404 to a specific html file in Mongoose?


I am trying to do this with the option url_rewrites in struct mg_serve_http_opts:

struct mg_serve_http_opts httpOptions;
httpOptions.url_rewrites = "404=/error.html";

Accordingly to Mongoose documentation, if I pass a number as uri_pattern, then "it is treated as HTTP error code, and file_or_directory_path should be an URI to redirect to"

Source: https://cpr.readthedocs.io/en/latest/opt/mongoose/docs/Options/

But I am working with mongoose 6.18, and checking the source code, the HTTP error code uri_pattern seems to have been removed. Is there any other way to do this? I can also upgrade to mongoose 7.1 if necessary, but I really wouldn't like to downgrade to mongoose 5.6.

Thanks.


Solution

  • I managed to find a solution to this problem for mongoose 6.18. It's not a generic solution like url_rewrites, which would have worked with any HTTP error code, but it's a solution that works well for HTTP 404.

    During the event handler, I have to manually parse the URL and check if the requested file exists. It it does, I serve the HTTP page as normal; if it doesn't, I serve the error file.

    This is the event handler code:

    static const char *documentRoot = "/var/www/html";
    
    
    static void eventHandler( struct mg_connection *connection, int event, void *eventData )
    {
        char resource[4096];
        memset( resource, 0, sizeof(resource));
    
    
        switch( event )
        {
            case MG_EV_HTTP_REQUEST:
            {
                struct http_message* httpMessage = (struct http_message*)eventData;
    
    
                /*
                 * Build absolute path to the requested file.
                 */
                strcpy( resource, documentRoot );
                strncat( resource, httpMessage->uri.p, httpMessage->uri.len );
    
    
                /*
                 * Check if the requested file exists in the filesystem.
                 */
                struct stat info;
                if( stat( resource, &info ) == 0 )
                {
                    struct mg_serve_http_opts httpOptions;
                    memset( &httpOptions, 0, sizeof(httpOptions));
    
                    httpOptions.document_root = documentRoot;
                    mg_serve_http( connection, httpMessage, httpOptions );
                }
                else
                {
                    struct mg_str mimeType;
                    memset( &mimeType, 0, sizeof(mimeType));
    
                    struct mg_str extraHeaders;
                    memset( &extraHeaders, 0, sizeof(extraHeaders));
    
    
                    /*
                     * Build absolute path to the 404 html file.
                     */
                    strcpy( resource, documentRoot );
                    strcat( resource, "/error404.html" );
    
    
                    mimeType.p = "text/html";
                    mimeType.len = strlen( mimeType.p );
                    mg_http_serve_file( connection, httpMessage, resource, mimeType, extraHeaders );
                }
            }
            break;
            default:;
        }
    }