Ticket #536: mod_ssi_recursion-1.4.15.patch

File mod_ssi_recursion-1.4.15.patch, 12.4 kB (added by dustin@…, 16 months ago)

rerursive SSI for 1.4.15

  • src/mod_ssi.c

    # HG changeset patch
    # User Dustin Sallings <dustin@spy.net>
    # Date 1178910589 25200
    # Node ID 228071f87c8e346c3e6e3a1d7542650a01d415dd
    # Parent  ea8607208d0e0278392e07debbb31bbbadb48cb3
    patch queue: mod_ssi_recursion
    
    diff -r ea8607208d0e -r 228071f87c8e src/mod_ssi.c
    a b  
    3636#include <sys/filio.h> 
    3737#endif 
    3838 
     39#define DEFAULT_MAX_SSI_RECURSION 25 
     40 
    3941/* init the plugin data */ 
    4042INIT_FUNC(mod_ssi_init) { 
    4143        plugin_data *p; 
     
    9496#endif 
    9597 
    9698        config_values_t cv[] = { 
    97                 { "ssi.extension",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },       /* 0 */ 
    98                 { NULL,                         NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 
     99                { "ssi.extension",                              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },               /* 0 */ 
     100                { "ssi.max_recursion",                  NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },               /* 1 */ 
     101                { NULL,                                                 NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 
    99102        }; 
    100103 
    101104        if (!p) return HANDLER_ERROR; 
     
    107110 
    108111                s = calloc(1, sizeof(plugin_config)); 
    109112                s->ssi_extension  = array_init(); 
     113                s->ssi_max_recursion  = DEFAULT_MAX_SSI_RECURSION; 
    110114 
    111115                cv[0].destination = s->ssi_extension; 
     116                cv[1].destination = &(s->ssi_max_recursion); 
    112117 
    113118                p->config_storage[i] = s; 
    114119 
     
    150155 
    151156/** 
    152157 * 
    153  *  the next two functions are take from fcgi.c 
     158 *      the next two functions are take from fcgi.c 
    154159 * 
    155160 */ 
    156161 
     
    214219        ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_SOFTWARE"), PACKAGE_NAME"/"PACKAGE_VERSION); 
    215220        ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_NAME"), 
    216221#ifdef HAVE_IPV6 
    217                     inet_ntop(srv_sock->addr.plain.sa_family, 
    218                                srv_sock->addr.plain.sa_family == AF_INET6 ? 
    219                                (const void *) &(srv_sock->addr.ipv6.sin6_addr) : 
    220                                (const void *) &(srv_sock->addr.ipv4.sin_addr), 
    221                                b2, sizeof(b2)-1) 
     222                        inet_ntop(srv_sock->addr.plain.sa_family, 
     223                                   srv_sock->addr.plain.sa_family == AF_INET6 ? 
     224                                   (const void *) &(srv_sock->addr.ipv6.sin6_addr) : 
     225                                   (const void *) &(srv_sock->addr.ipv4.sin_addr), 
     226                                   b2, sizeof(b2)-1) 
    222227#else 
    223                     inet_ntoa(srv_sock->addr.ipv4.sin_addr) 
    224 #endif 
    225                     ); 
     228                        inet_ntoa(srv_sock->addr.ipv4.sin_addr) 
     229#endif 
     230                        ); 
    226231        ssi_env_add(p->ssi_cgi_env, CONST_STRING("GATEWAY_INTERFACE"), "CGI/1.1"); 
    227232 
    228233        ltostr(buf, 
    229234#ifdef HAVE_IPV6 
    230                ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) 
     235                   ntohs(srv_sock->addr.plain.sa_family ? srv_sock->addr.ipv6.sin6_port : srv_sock->addr.ipv4.sin_port) 
    231236#else 
    232                ntohs(srv_sock->addr.ipv4.sin_port) 
    233 #endif 
    234                ); 
     237                   ntohs(srv_sock->addr.ipv4.sin_port) 
     238#endif 
     239                   ); 
    235240 
    236241        ssi_env_add(p->ssi_cgi_env, CONST_STRING("SERVER_PORT"), buf); 
    237242 
    238243        ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_ADDR"), 
    239                     inet_ntop_cache_get_ip(srv, &(con->dst_addr))); 
     244                        inet_ntop_cache_get_ip(srv, &(con->dst_addr))); 
    240245 
    241246        if (con->authed_user->used) { 
    242247                ssi_env_add(p->ssi_cgi_env, CONST_STRING("REMOTE_USER"), 
    243                             con->authed_user->ptr); 
     248                                con->authed_user->ptr); 
    244249        } 
    245250 
    246251        if (con->request.content_length > 0) { 
     
    286291        return 0; 
    287292} 
    288293 
     294URIHANDLER_FUNC(mod_ssi_physical_path); 
     295 
    289296static int process_ssi_stmt(server *srv, connection *con, plugin_data *p, 
    290                             const char **l, size_t n) { 
     297                                const char **l, size_t n) { 
    291298        size_t i, ssicmd = 0; 
    292299        char buf[255]; 
    293300        buffer *b = NULL; 
     
    298305                                SSI_CONFIG, SSI_PRINTENV, SSI_SET, SSI_IF, SSI_ELIF, 
    299306                                SSI_ELSE, SSI_ENDIF, SSI_EXEC } type; 
    300307        } ssicmds[] = { 
    301                 { "echo",     SSI_ECHO }, 
     308                { "echo",         SSI_ECHO }, 
    302309                { "include",  SSI_INCLUDE }, 
    303310                { "flastmod", SSI_FLASTMOD }, 
    304                 { "fsize",    SSI_FSIZE }, 
     311                { "fsize",        SSI_FSIZE }, 
    305312                { "config",   SSI_CONFIG }, 
    306313                { "printenv", SSI_PRINTENV }, 
    307                 { "set",      SSI_SET }, 
    308                 { "if",       SSI_IF }, 
    309                 { "elif",     SSI_ELIF }, 
    310                 { "endif",    SSI_ENDIF }, 
    311                 { "else",     SSI_ELSE }, 
    312                 { "exec",     SSI_EXEC }, 
     314                { "set",          SSI_SET }, 
     315                { "if",           SSI_IF }, 
     316                { "elif",         SSI_ELIF }, 
     317                { "endif",        SSI_ENDIF }, 
     318                { "else",         SSI_ELSE }, 
     319                { "exec",         SSI_EXEC }, 
    313320 
    314321                { NULL, SSI_UNSET } 
    315322        }; 
     
    333340                        enum { SSI_ECHO_UNSET, SSI_ECHO_DATE_GMT, SSI_ECHO_DATE_LOCAL, SSI_ECHO_DOCUMENT_NAME, SSI_ECHO_DOCUMENT_URI, 
    334341                                        SSI_ECHO_LAST_MODIFIED, SSI_ECHO_USER_NAME } type; 
    335342                } echovars[] = { 
    336                         { "DATE_GMT",      SSI_ECHO_DATE_GMT }, 
     343                        { "DATE_GMT",      SSI_ECHO_DATE_GMT }, 
    337344                        { "DATE_LOCAL",    SSI_ECHO_DATE_LOCAL }, 
    338345                        { "DOCUMENT_NAME", SSI_ECHO_DOCUMENT_NAME }, 
    339346                        { "DOCUMENT_URI",  SSI_ECHO_DOCUMENT_URI }, 
    340347                        { "LAST_MODIFIED", SSI_ECHO_LAST_MODIFIED }, 
    341                         { "USER_NAME",     SSI_ECHO_USER_NAME }, 
     348                        { "USER_NAME",     SSI_ECHO_USER_NAME }, 
    342349 
    343350                        { NULL, SSI_ECHO_UNSET } 
    344351                }; 
     
    347354                        const char *var; 
    348355                        enum { SSI_ENC_UNSET, SSI_ENC_URL, SSI_ENC_NONE, SSI_ENC_ENTITY } type; 
    349356                } encvars[] = { 
    350                         { "url",          SSI_ENC_URL }, 
    351                         { "none",         SSI_ENC_NONE }, 
    352                         { "entity",       SSI_ENC_ENTITY }, 
     357                        { "url",                  SSI_ENC_URL }, 
     358                        { "none",                 SSI_ENC_NONE }, 
     359                        { "entity",               SSI_ENC_ENTITY }, 
    353360 
    354361                        { NULL, SSI_ENC_UNSET } 
    355362                }; 
     
    546553                } 
    547554 
    548555                if (0 == stat(p->stat_fn->ptr, &st)) { 
     556                        buffer *tmp = NULL; 
    549557                        time_t t = st.st_mtime; 
    550558 
    551559                        switch (ssicmd) { 
     
    574582                                } 
    575583                                break; 
    576584                        case SSI_INCLUDE: 
    577                                 chunkqueue_append_file(con->write_queue, p->stat_fn, 0, st.st_size); 
     585                                /* do recursive SSI expansion */ 
     586 
     587                                /* prevents infinite loop */ 
     588                                if (buffer_is_equal(con->physical.path, p->stat_fn)) { 
     589                                        buffer_copy_string(srv->tmp_buf, "<!-- your include directives create an infinite loop; aborting -->"); 
     590                                        chunkqueue_append_buffer(con->write_queue, srv->tmp_buf); 
     591                                        break; 
     592                                } 
     593 
     594                                /* only allow predefined recursion depth */ 
     595                                if (con->loops_per_request > p->conf.ssi_max_recursion) { 
     596                                        buffer_copy_string(srv->tmp_buf, "<!-- your include directives recurse deeper than pre-defined max_recursion; aborting -->"); 
     597                                        chunkqueue_append_buffer(con->write_queue, srv->tmp_buf); 
     598                                        break; 
     599                                } 
     600 
     601                                tmp = buffer_init(); 
     602                                /* save path of current document */ 
     603                                buffer_copy_string_buffer(tmp, con->physical.path); 
     604                                /* next sub-document to parse */ 
     605                                buffer_copy_string_buffer(con->physical.path, p->stat_fn); 
     606                                if (mod_ssi_physical_path(srv,con,p) != HANDLER_FINISHED) { 
     607                                        /* the document was not processed, so write it as is */ 
     608                                        chunkqueue_append_file(con->write_queue, con->physical.path, 0, st.st_size); 
     609                                } 
     610                                /* restore saved path */ 
     611                                buffer_copy_string_buffer(con->physical.path, tmp); 
     612                                buffer_free(tmp); 
    578613                                break; 
    579614                        } 
    580615                } else { 
     
    795830                } 
    796831 
    797832                if ((!p->if_is_false) && 
    798                     ((p->if_is_false_level == 0) || 
    799                     (p->if_level < p->if_is_false_level))) { 
     833                        ((p->if_is_false_level == 0) || 
     834                        (p->if_level < p->if_is_false_level))) { 
    800835                        switch (ssi_eval_expr(srv, con, p, expr)) { 
    801836                        case -1: 
    802837                        case 0: 
     
    818853 
    819854                if (p->if_is_false) { 
    820855                        if ((p->if_level == p->if_is_false_level) && 
    821                             (p->if_is_false_endif == 0)) { 
     856                                (p->if_is_false_endif == 0)) { 
    822857                                p->if_is_false = 0; 
    823858                        } 
    824859                } else { 
     
    852887 
    853888                if (p->if_level == p->if_is_false_level) { 
    854889                        if ((p->if_is_false) && 
    855                             (p->if_is_false_endif == 0)) { 
     890                                (p->if_is_false_endif == 0)) { 
    856891                                switch (ssi_eval_expr(srv, con, p, expr)) { 
    857892                                case -1: 
    858893                                case 0: 
     
    896931 
    897932static int mod_ssi_handle_request(server *srv, connection *con, plugin_data *p) { 
    898933        stream s; 
    899 #ifdef  HAVE_PCRE_H 
     934#ifdef  HAVE_PCRE_H 
    900935        int i, n; 
    901936 
    902937#define N 10 
     
    922957        /** 
    923958         * <!--#element attribute=value attribute=value ... --> 
    924959         * 
    925          * config       DONE 
    926          *   errmsg     -- missing 
    927          *   sizefmt    DONE 
    928          *   timefmt    DONE 
    929          * echo         DONE 
    930          *   var        DONE 
    931          *   encoding   -- missing 
    932          * exec         DONE 
    933          *   cgi        -- never 
    934          *   cmd        DONE 
    935          * fsize        DONE 
    936          *   file       DONE 
    937          *   virtual    DONE 
    938          * flastmod     DONE 
    939          *   file       DONE 
    940          *   virtual    DONE 
    941          * include      DONE 
    942          *   file       DONE 
    943          *   virtual    DONE 
    944          * printenv     DONE 
    945          * set          DONE 
    946          *   var        DONE 
    947          *   value      DONE 
     960         * config               DONE 
     961         *       errmsg         -- missing 
     962         *       sizefmt        DONE 
     963         *       timefmt        DONE 
     964         * echo                 DONE 
     965         *       var            DONE 
     966         *       encoding       -- missing 
     967         * exec                 DONE 
     968         *       cgi            -- never 
     969         *       cmd            DONE 
     970         * fsize                DONE 
     971         *       file           DONE 
     972         *       virtual        DONE 
     973         * flastmod             DONE 
     974         *       file           DONE 
     975         *       virtual        DONE 
     976         * include              DONE 
     977         *       file           DONE 
     978         *       virtual        DONE 
     979         * printenv             DONE 
     980         * set                  DONE 
     981         *       var            DONE 
     982         *       value          DONE 
    948983         * 
    949          * if           DONE 
    950          * elif         DONE 
    951          * else         DONE 
    952          * endif        DONE 
     984         * if                   DONE 
     985         * elif                 DONE 
     986         * else                 DONE 
     987         * endif                DONE 
    953988         * 
    954989         * 
    955990         * expressions 
    956          * AND, OR      DONE 
    957          * comp         DONE 
    958          * ${...}       -- missing 
    959          * $...         DONE 
    960          * '...'        DONE 
    961          * ( ... )      DONE 
     991         * AND, OR              DONE 
     992         * comp                 DONE 
     993         * ${...}               -- missing 
     994         * $...                 DONE 
     995         * '...'                DONE 
     996         * ( ... )              DONE 
    962997         * 
    963998         * 
    964999         * 
    9651000         * ** all DONE ** 
    9661001         * DATE_GMT 
    967          *  The current date in Greenwich Mean Time. 
     1002         *      The current date in Greenwich Mean Time. 
    9681003         * DATE_LOCAL 
    969          *  The current date in the local time zone. 
     1004         *      The current date in the local time zone. 
    9701005         * DOCUMENT_NAME 
    971          *  The filename (excluding directories) of the document requested by the user. 
     1006         *      The filename (excluding directories) of the document requested by the user. 
    9721007         * DOCUMENT_URI 
    973          *  The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. 
     1008         *      The (%-decoded) URL path of the document requested by the user. Note that in the case of nested include files, this is not then URL for the current document. 
    9741009         * LAST_MODIFIED 
    975          *  The last modification date of the document requested by the user. 
     1010         *      The last modification date of the document requested by the user. 
    9761011         * USER_NAME 
    977          *  Contains the owner of the file which included it. 
     1012         *      Contains the owner of the file which included it. 
    9781013         * 
    9791014         */ 
    9801015#ifdef HAVE_PCRE_H 
     
    10231058        plugin_config *s = p->config_storage[0]; 
    10241059 
    10251060        PATCH(ssi_extension); 
     1061        PATCH(ssi_max_recursion); 
    10261062 
    10271063        /* skip the first, the global context */ 
    10281064        for (i = 1; i < srv->config_context->used; i++) { 
     
    10391075                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.extension"))) { 
    10401076                                PATCH(ssi_extension); 
    10411077                        } 
     1078                        if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssi.max_recursion"))) { 
     1079                                PATCH(ssi_max_recursion); 
     1080                        } 
    10421081                } 
    10431082        } 
    10441083 
     
    10521091 
    10531092        if (con->physical.path->used == 0) return HANDLER_GO_ON; 
    10541093 
     1094        con->loops_per_request++; 
     1095 
    10551096        mod_ssi_patch_connection(srv, con, p); 
    10561097 
    10571098        for (k = 0; k < p->conf.ssi_extension->used; k++) { 
     
    10781119/* this function is called at dlopen() time and inits the callbacks */ 
    10791120 
    10801121int mod_ssi_plugin_init(plugin *p) { 
    1081         p->version     = LIGHTTPD_VERSION_ID; 
    1082         p->name        = buffer_init_string("ssi"); 
    1083  
    1084         p->init        = mod_ssi_init; 
     1122        p->version         = LIGHTTPD_VERSION_ID; 
     1123        p->name            = buffer_init_string("ssi"); 
     1124 
     1125        p->init            = mod_ssi_init; 
    10851126        p->handle_subrequest_start = mod_ssi_physical_path; 
    10861127        p->set_defaults  = mod_ssi_set_defaults; 
    1087         p->cleanup     = mod_ssi_free; 
    1088  
    1089         p->data        = NULL; 
     1128        p->cleanup         = mod_ssi_free; 
     1129 
     1130        p->data            = NULL; 
    10901131 
    10911132        return 0; 
    10921133} 
  • src/mod_ssi.h

    diff -r ea8607208d0e -r 228071f87c8e src/mod_ssi.h
    a b  
    1515 
    1616typedef struct { 
    1717        array *ssi_extension; 
     18        unsigned short ssi_max_recursion; 
    1819} plugin_config; 
    1920 
    2021typedef struct {