Diff for /embedaddon/lighttpd/src/configfile.c between versions 1.1 and 1.1.1.3

version 1.1, 2013/10/14 10:32:48 version 1.1.1.3, 2016/11/02 10:35:00
Line 1 Line 1
   #include "first.h"
   
 #include "server.h"  #include "server.h"
 #include "log.h"  #include "log.h"
 #include "stream.h"  #include "stream.h"
Line 6 Line 8
 #include "configparser.h"  #include "configparser.h"
 #include "configfile.h"  #include "configfile.h"
 #include "proc_open.h"  #include "proc_open.h"
   #include "request.h"
   #include "version.h"
   
 #include <sys/stat.h>  #include <sys/stat.h>
   
Line 18 Line 22
 #include <ctype.h>  #include <ctype.h>
 #include <limits.h>  #include <limits.h>
 #include <assert.h>  #include <assert.h>
   #include <glob.h>
   
   
 static int config_insert(server *srv) {  static int config_insert(server *srv) {
Line 26  static int config_insert(server *srv) { Line 31  static int config_insert(server *srv) {
         buffer *stat_cache_string;          buffer *stat_cache_string;
   
         config_values_t cv[] = {          config_values_t cv[] = {
                { "server.bind",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 0 */                { "server.bind",                       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 0 */
                { "server.errorlog",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 1 */                { "server.errorlog",                   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 1 */
                { "server.errorfile-prefix",     NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 2 */                { "server.errorfile-prefix",           NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 2 */
                { "server.chroot",               NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 3 */                { "server.chroot",                     NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 3 */
                { "server.username",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 4 */                { "server.username",                   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 4 */
                { "server.groupname",            NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 5 */                { "server.groupname",                  NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 5 */
                { "server.port",                 NULL, T_CONFIG_SHORT,  T_CONFIG_SCOPE_SERVER },      /* 6 */                { "server.port",                       NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER     }, /* 6 */
                { "server.tag",                  NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 7 */                { "server.tag",                        NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 7 */
                { "server.use-ipv6",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */                { "server.use-ipv6",                   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 8 */
                { "server.modules",              NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_SERVER },       /* 9 */                { "server.modules",                    NULL, T_CONFIG_ARRAY,   T_CONFIG_SCOPE_SERVER     }, /* 9 */
   
                { "server.event-handler",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 10 */                { "server.event-handler",              NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 10 */
                { "server.pid-file",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 11 */                { "server.pid-file",                   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 11 */
                { "server.max-request-size",     NULL, T_CONFIG_INT, T_CONFIG_SCOPE_CONNECTION },     /* 12 */                { "server.max-request-size",           NULL, T_CONFIG_INT,     T_CONFIG_SCOPE_SERVER     }, /* 12 */
                { "server.max-worker",           NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },       /* 13 */                { "server.max-worker",                 NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER     }, /* 13 */
                { "server.document-root",        NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 14 */                { "server.document-root",              NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 14 */
                { "server.force-lowercase-filenames", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },/* 15 */                { "server.force-lowercase-filenames",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 15 */
                { "debug.log-condition-handling", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },    /* 16 */                { "debug.log-condition-handling",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 16 */
                { "server.max-keep-alive-requests", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },/* 17 */                { "server.max-keep-alive-requests",    NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 17 */
                { "server.name",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 18 */                { "server.name",                       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 18 */
                { "server.max-keep-alive-idle",  NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 19 */                { "server.max-keep-alive-idle",        NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 19 */
   
                { "server.max-read-idle",        NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 20 */                { "server.max-read-idle",              NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 20 */
                { "server.max-write-idle",       NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 21 */                { "server.max-write-idle",             NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 21 */
                { "server.error-handler-404",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 22 */                { "server.error-handler",              NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 22 */
                { "server.max-fds",              NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },       /* 23 */                { "server.max-fds",                    NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER     }, /* 23 */
 #ifdef HAVE_LSTAT  #ifdef HAVE_LSTAT
                { "server.follow-symlink",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 24 */                { "server.follow-symlink",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 24 */
 #else  #else
                 { "server.follow-symlink",                  { "server.follow-symlink",
                  "Your system lacks lstat(). We can not differ symlinks from files."                        "Your system lacks lstat(). We can not differ symlinks from files."
                  "Please remove server.follow-symlinks from your config.",                        "Please remove server.follow-symlinks from your config.",
                  T_CONFIG_UNSUPPORTED, T_CONFIG_SCOPE_UNSET }, /* 24 */                        T_CONFIG_UNSUPPORTED, T_CONFIG_SCOPE_UNSET },
 #endif  #endif
                { "server.kbytes-per-second",    NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 25 */                { "server.kbytes-per-second",          NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 25 */
                { "connection.kbytes-per-second", NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },  /* 26 */                { "connection.kbytes-per-second",      NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 26 */
                { "mimetype.use-xattr",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */                { "mimetype.use-xattr",                NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 27 */
                { "mimetype.assign",             NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 28 */                { "mimetype.assign",                   NULL, T_CONFIG_ARRAY,   T_CONFIG_SCOPE_CONNECTION }, /* 28 */
                { "ssl.pemfile",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 29 */                { "ssl.pemfile",                       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 29 */
   
                { "ssl.engine",                  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 30 */                { "ssl.engine",                        NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 30 */
                 { "debug.log-file-not-found",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 31 */
                 { "debug.log-request-handling",        NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 32 */
                 { "debug.log-response-header",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 33 */
                 { "debug.log-request-header",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 34 */
                 { "debug.log-ssl-noise",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 35 */
                 { "server.protocol-http11",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 36 */
                 { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 37 */
                 { "debug.log-state-handling",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 38 */
                 { "ssl.ca-file",                       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 39 */
   
                { "debug.log-file-not-found",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 31 */                { "server.errorlog-use-syslog",        NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 40 */
                { "debug.log-request-handling",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 32 */                { "server.range-requests",             NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 41 */
                { "debug.log-response-header",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 33 */                { "server.stat-cache-engine",          NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 42 */
                { "debug.log-request-header",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 34 */                { "server.max-connections",            NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER     }, /* 43 */
                { "debug.log-ssl-noise",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 35 */                { "server.network-backend",            NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 44 */
                 { "server.upload-dirs",                NULL, T_CONFIG_ARRAY,   T_CONFIG_SCOPE_SERVER     }, /* 45 */
                 { "server.core-files",                 NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 46 */
                 { "ssl.cipher-list",                   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 47 */
                 { "ssl.use-sslv2",                     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 48 */
                 { "etag.use-inode",                    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 49 */
   
                { "server.protocol-http11",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 36 */                { "etag.use-mtime",                    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 50 */
                { "debug.log-request-header-on-error", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 37 */                { "etag.use-size",                     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 51 */
                { "debug.log-state-handling",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 38 */                { "server.reject-expect-100-with-417", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 52 */
                { "ssl.ca-file",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 39 */                { "debug.log-timeouts",                NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */
                 { "server.defer-accept",               NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 54 */
                 { "server.breakagelog",                NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 55 */
                 { "ssl.verifyclient.activate",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 56 */
                 { "ssl.verifyclient.enforce",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 57 */
                 { "ssl.verifyclient.depth",            NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 58 */
                 { "ssl.verifyclient.username",         NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 59 */
   
                { "server.errorlog-use-syslog",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 40 */                { "ssl.verifyclient.exportcert",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 60 */
                { "server.range-requests",       NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 41 */                { "server.set-v6only",                 NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 61 */
                { "server.stat-cache-engine",    NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 42 */                { "ssl.use-sslv3",                     NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 62 */
                { "server.max-connections",      NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_SERVER },       /* 43 */                { "ssl.dh-file",                       NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 63 */
                { "server.network-backend",      NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_CONNECTION },  /* 44 */                { "ssl.ec-curve",                      NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 64 */
                { "server.upload-dirs",          NULL, T_CONFIG_ARRAY, T_CONFIG_SCOPE_CONNECTION },   /* 45 */                { "ssl.disable-client-renegotiation",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 65 */
                { "server.core-files",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 46 */                { "ssl.honor-cipher-order",            NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 66 */
                { "ssl.cipher-list",             NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 47 */                { "ssl.empty-fragments",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 67 */
                { "ssl.use-sslv2",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 48 */                { "server.upload-temp-file-size",      NULL, T_CONFIG_INT,     T_CONFIG_SCOPE_SERVER     }, /* 68 */
                { "etag.use-inode",              NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 49 */                { "mimetype.xattr-name",               NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER     }, /* 69 */
                { "etag.use-mtime",              NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 50 */                { "server.listen-backlog",             NULL, T_CONFIG_INT,     T_CONFIG_SCOPE_CONNECTION }, /* 70 */
                { "etag.use-size",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 51 */                { "server.error-handler-404",          NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 71 */
                { "server.reject-expect-100-with-417",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER }, /* 52 */                { "server.http-parseopt-header-strict",NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 72 */
                { "debug.log-timeouts",          NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 53 */                { "server.http-parseopt-host-strict",  NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 73 */
                { "server.defer-accept",         NULL, T_CONFIG_SHORT, T_CONFIG_SCOPE_CONNECTION },   /* 54 */                { "server.http-parseopt-host-normalize",NULL,T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER     }, /* 74 */
                { "server.breakagelog",          NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 55 */                { "server.bsd-accept-filter",          NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_CONNECTION }, /* 75 */
                { "ssl.verifyclient.activate",   NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 56 */                { "server.stream-request-body",        NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 76 */
                { "ssl.verifyclient.enforce",    NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 57 */                { "server.stream-response-body",       NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_CONNECTION }, /* 77 */
                { "ssl.verifyclient.depth",      NULL, T_CONFIG_SHORT,   T_CONFIG_SCOPE_SERVER },     /* 58 */ 
                { "ssl.verifyclient.username",   NULL, T_CONFIG_STRING,  T_CONFIG_SCOPE_SERVER },     /* 59 */ 
                { "ssl.verifyclient.exportcert", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 60 */ 
   
                { "server.set-v6only",           NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_CONNECTION }, /* 61 */                { NULL,                                NULL, T_CONFIG_UNSET,   T_CONFIG_SCOPE_UNSET      }
                { "ssl.use-sslv3",               NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 62 */ 
                { "ssl.dh-file",                 NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 63 */ 
                { "ssl.ec-curve",                NULL, T_CONFIG_STRING, T_CONFIG_SCOPE_SERVER },      /* 64 */ 
                { "ssl.disable-client-renegotiation", NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },/* 65 */ 
                { "ssl.honor-cipher-order",      NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 66 */ 
                { "ssl.empty-fragments",         NULL, T_CONFIG_BOOLEAN, T_CONFIG_SCOPE_SERVER },     /* 67 */ 
 
                { "server.host",                 "use server.bind instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.docroot",              "use server.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.virtual-root",         "load mod_simple_vhost and use simple-vhost.server-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.virtual-default-host", "load mod_simple_vhost and use simple-vhost.default-host instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.virtual-docroot",      "load mod_simple_vhost and use simple-vhost.document-root instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.userid",               "use server.username instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.groupid",              "use server.groupname instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.use-keep-alive",       "use server.max-keep-alive-requests = 0 instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
                { "server.force-lower-case-files",       "use server.force-lowercase-filenames instead", T_CONFIG_DEPRECATED, T_CONFIG_SCOPE_UNSET }, 
 
                { NULL,                          NULL, T_CONFIG_UNSET, T_CONFIG_SCOPE_UNSET } 
         };          };
   
        /* all T_CONFIG_SCOPE_SERVER options */
        /* 0 */ 
         cv[0].destination = srv->srvconf.bindhost;          cv[0].destination = srv->srvconf.bindhost;
         cv[1].destination = srv->srvconf.errorlog_file;          cv[1].destination = srv->srvconf.errorlog_file;
         cv[3].destination = srv->srvconf.changeroot;          cv[3].destination = srv->srvconf.changeroot;
         cv[4].destination = srv->srvconf.username;          cv[4].destination = srv->srvconf.username;
         cv[5].destination = srv->srvconf.groupname;          cv[5].destination = srv->srvconf.groupname;
         cv[6].destination = &(srv->srvconf.port);          cv[6].destination = &(srv->srvconf.port);
   
         cv[9].destination = srv->srvconf.modules;          cv[9].destination = srv->srvconf.modules;
   
         cv[10].destination = srv->srvconf.event_handler;          cv[10].destination = srv->srvconf.event_handler;
         cv[11].destination = srv->srvconf.pid_file;          cv[11].destination = srv->srvconf.pid_file;
   
         cv[13].destination = &(srv->srvconf.max_worker);          cv[13].destination = &(srv->srvconf.max_worker);
   
         cv[23].destination = &(srv->srvconf.max_fds);          cv[23].destination = &(srv->srvconf.max_fds);
   
         cv[37].destination = &(srv->srvconf.log_request_header_on_error);          cv[37].destination = &(srv->srvconf.log_request_header_on_error);
         cv[38].destination = &(srv->srvconf.log_state_handling);          cv[38].destination = &(srv->srvconf.log_state_handling);
   
         cv[40].destination = &(srv->srvconf.errorlog_use_syslog);          cv[40].destination = &(srv->srvconf.errorlog_use_syslog);
   
         stat_cache_string = buffer_init();          stat_cache_string = buffer_init();
         cv[42].destination = stat_cache_string;          cv[42].destination = stat_cache_string;
           cv[43].destination = &(srv->srvconf.max_conns);
         cv[44].destination = srv->srvconf.network_backend;          cv[44].destination = srv->srvconf.network_backend;
         cv[45].destination = srv->srvconf.upload_tempdirs;          cv[45].destination = srv->srvconf.upload_tempdirs;
         cv[46].destination = &(srv->srvconf.enable_cores);          cv[46].destination = &(srv->srvconf.enable_cores);
   
         cv[43].destination = &(srv->srvconf.max_conns);  
         cv[12].destination = &(srv->srvconf.max_request_size);  
         cv[52].destination = &(srv->srvconf.reject_expect_100_with_417);          cv[52].destination = &(srv->srvconf.reject_expect_100_with_417);
         cv[55].destination = srv->srvconf.breakagelog_file;          cv[55].destination = srv->srvconf.breakagelog_file;
   
           cv[68].destination = &(srv->srvconf.upload_temp_file_size);
           cv[69].destination = srv->srvconf.xattr_name;
           cv[72].destination = &(srv->srvconf.http_header_strict);
           cv[73].destination = &(srv->srvconf.http_host_strict);
           cv[74].destination = &(srv->srvconf.http_host_normalize);
   
         srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));          srv->config_storage = calloc(1, srv->config_context->used * sizeof(specific_config *));
   
        assert(srv->config_storage);        force_assert(srv->config_storage);
   
         for (i = 0; i < srv->config_context->used; i++) {          for (i = 0; i < srv->config_context->used; i++) {
                   data_config const* config = (data_config const*)srv->config_context->data[i];
                 specific_config *s;                  specific_config *s;
   
                 s = calloc(1, sizeof(specific_config));                  s = calloc(1, sizeof(specific_config));
                assert(s);                force_assert(s);
                 s->document_root = buffer_init();                  s->document_root = buffer_init();
                 s->mimetypes     = array_init();                  s->mimetypes     = array_init();
                 s->server_name   = buffer_init();                  s->server_name   = buffer_init();
                 s->ssl_pemfile   = buffer_init();                  s->ssl_pemfile   = buffer_init();
                 s->ssl_ca_file   = buffer_init();                  s->ssl_ca_file   = buffer_init();
                 s->error_handler = buffer_init();                  s->error_handler = buffer_init();
                s->server_tag    = buffer_init();                s->error_handler_404 = buffer_init();
                 s->server_tag    = buffer_init_string(PACKAGE_DESC);
                 s->ssl_cipher_list = buffer_init();                  s->ssl_cipher_list = buffer_init();
                 s->ssl_dh_file   = buffer_init();                  s->ssl_dh_file   = buffer_init();
                 s->ssl_ec_curve  = buffer_init();                  s->ssl_ec_curve  = buffer_init();
                 s->errorfile_prefix = buffer_init();                  s->errorfile_prefix = buffer_init();
                 #if defined(__FreeBSD__) || defined(__NetBSD__) \
                  || defined(__OpenBSD__) || defined(__DragonflyBSD__)
                   s->bsd_accept_filter = (i == 0)
                     ? buffer_init()
                     : buffer_init_buffer(srv->config_storage[0]->bsd_accept_filter);
                 #endif
                 s->max_keep_alive_requests = 16;                  s->max_keep_alive_requests = 16;
                 s->max_keep_alive_idle = 5;                  s->max_keep_alive_idle = 5;
                 s->max_read_idle = 60;                  s->max_read_idle = 60;
                 s->max_write_idle = 360;                  s->max_write_idle = 360;
                   s->max_request_size = 0;
                 s->use_xattr     = 0;                  s->use_xattr     = 0;
                 s->ssl_enabled   = 0;                  s->ssl_enabled   = 0;
                 s->ssl_honor_cipher_order = 1;                  s->ssl_honor_cipher_order = 1;
                 s->ssl_empty_fragments = 0;                  s->ssl_empty_fragments = 0;
                 s->ssl_use_sslv2 = 0;                  s->ssl_use_sslv2 = 0;
                s->ssl_use_sslv3 = 1;                s->ssl_use_sslv3 = 0;
                s->use_ipv6      = 0;                s->use_ipv6      = (i == 0) ? 0 : srv->config_storage[0]->use_ipv6;
                s->set_v6only    = 1;                s->set_v6only    = (i == 0) ? 1 : srv->config_storage[0]->set_v6only;
                s->defer_accept  = 0;                s->defer_accept  = (i == 0) ? 0 : srv->config_storage[0]->defer_accept;
 #ifdef HAVE_LSTAT  #ifdef HAVE_LSTAT
                 s->follow_symlink = 1;                  s->follow_symlink = 1;
 #endif  #endif
Line 205  static int config_insert(server *srv) { Line 222  static int config_insert(server *srv) {
                 s->ssl_verifyclient_depth = 9;                  s->ssl_verifyclient_depth = 9;
                 s->ssl_verifyclient_export_cert = 0;                  s->ssl_verifyclient_export_cert = 0;
                 s->ssl_disable_client_renegotiation = 1;                  s->ssl_disable_client_renegotiation = 1;
                   s->listen_backlog = (0 == i ? 1024 : srv->config_storage[0]->listen_backlog);
                   s->stream_request_body = 0;
                   s->stream_response_body = 0;
   
                   /* all T_CONFIG_SCOPE_CONNECTION options */
                 cv[2].destination = s->errorfile_prefix;                  cv[2].destination = s->errorfile_prefix;
   
                 cv[7].destination = s->server_tag;                  cv[7].destination = s->server_tag;
                 cv[8].destination = &(s->use_ipv6);                  cv[8].destination = &(s->use_ipv6);
                 cv[61].destination = &(s->set_v6only);  
                 cv[54].destination = &(s->defer_accept);  
   
                cv[12].destination = &(s->max_request_size);
                /* 13 max-worker */ 
                 cv[14].destination = s->document_root;                  cv[14].destination = s->document_root;
                 cv[15].destination = &(s->force_lowercase_filenames);                  cv[15].destination = &(s->force_lowercase_filenames);
                 cv[16].destination = &(s->log_condition_handling);                  cv[16].destination = &(s->log_condition_handling);
                 cv[17].destination = &(s->max_keep_alive_requests);                  cv[17].destination = &(s->max_keep_alive_requests);
                 cv[18].destination = s->server_name;                  cv[18].destination = s->server_name;
                 cv[19].destination = &(s->max_keep_alive_idle);                  cv[19].destination = &(s->max_keep_alive_idle);
   
                 cv[20].destination = &(s->max_read_idle);                  cv[20].destination = &(s->max_read_idle);
                 cv[21].destination = &(s->max_write_idle);                  cv[21].destination = &(s->max_write_idle);
                 cv[22].destination = s->error_handler;                  cv[22].destination = s->error_handler;
 #ifdef HAVE_LSTAT  #ifdef HAVE_LSTAT
                 cv[24].destination = &(s->follow_symlink);                  cv[24].destination = &(s->follow_symlink);
 #endif  #endif
                 /* 23 -> max-fds */  
                 cv[25].destination = &(s->global_kbytes_per_second);                  cv[25].destination = &(s->global_kbytes_per_second);
                 cv[26].destination = &(s->kbytes_per_second);                  cv[26].destination = &(s->kbytes_per_second);
                 cv[27].destination = &(s->use_xattr);                  cv[27].destination = &(s->use_xattr);
                 cv[28].destination = s->mimetypes;                  cv[28].destination = s->mimetypes;
                 cv[29].destination = s->ssl_pemfile;                  cv[29].destination = s->ssl_pemfile;
                 cv[30].destination = &(s->ssl_enabled);  
   
                   cv[30].destination = &(s->ssl_enabled);
                 cv[31].destination = &(s->log_file_not_found);                  cv[31].destination = &(s->log_file_not_found);
                 cv[32].destination = &(s->log_request_handling);                  cv[32].destination = &(s->log_request_handling);
                 cv[33].destination = &(s->log_response_header);                  cv[33].destination = &(s->log_response_header);
                 cv[34].destination = &(s->log_request_header);                  cv[34].destination = &(s->log_request_header);
                 cv[35].destination = &(s->log_ssl_noise);                  cv[35].destination = &(s->log_ssl_noise);
                 cv[53].destination = &(s->log_timeouts);  
   
                 cv[36].destination = &(s->allow_http11);                  cv[36].destination = &(s->allow_http11);
                 cv[39].destination = s->ssl_ca_file;                  cv[39].destination = s->ssl_ca_file;
                 cv[41].destination = &(s->range_requests);  
   
                   cv[41].destination = &(s->range_requests);
                 cv[47].destination = s->ssl_cipher_list;                  cv[47].destination = s->ssl_cipher_list;
                 cv[48].destination = &(s->ssl_use_sslv2);                  cv[48].destination = &(s->ssl_use_sslv2);
                 cv[62].destination = &(s->ssl_use_sslv3);  
                 cv[63].destination = s->ssl_dh_file;  
                 cv[64].destination = s->ssl_ec_curve;  
                 cv[66].destination = &(s->ssl_honor_cipher_order);  
                 cv[67].destination = &(s->ssl_empty_fragments);  
   
                 cv[49].destination = &(s->etag_use_inode);                  cv[49].destination = &(s->etag_use_inode);
   
                 cv[50].destination = &(s->etag_use_mtime);                  cv[50].destination = &(s->etag_use_mtime);
                 cv[51].destination = &(s->etag_use_size);                  cv[51].destination = &(s->etag_use_size);
                cv[53].destination = &(s->log_timeouts);
                /* ssl.verify */                cv[54].destination = &(s->defer_accept);
                 cv[56].destination = &(s->ssl_verifyclient);                  cv[56].destination = &(s->ssl_verifyclient);
                 cv[57].destination = &(s->ssl_verifyclient_enforce);                  cv[57].destination = &(s->ssl_verifyclient_enforce);
                 cv[58].destination = &(s->ssl_verifyclient_depth);                  cv[58].destination = &(s->ssl_verifyclient_depth);
                 cv[59].destination = s->ssl_verifyclient_username;                  cv[59].destination = s->ssl_verifyclient_username;
   
                 cv[60].destination = &(s->ssl_verifyclient_export_cert);                  cv[60].destination = &(s->ssl_verifyclient_export_cert);
                   cv[61].destination = &(s->set_v6only);
                   cv[62].destination = &(s->ssl_use_sslv3);
                   cv[63].destination = s->ssl_dh_file;
                   cv[64].destination = s->ssl_ec_curve;
                 cv[65].destination = &(s->ssl_disable_client_renegotiation);                  cv[65].destination = &(s->ssl_disable_client_renegotiation);
                   cv[66].destination = &(s->ssl_honor_cipher_order);
                   cv[67].destination = &(s->ssl_empty_fragments);
                   cv[70].destination = &(s->listen_backlog);
                   cv[71].destination = s->error_handler_404;
                 #if defined(__FreeBSD__) || defined(__NetBSD__) \
                  || defined(__OpenBSD__) || defined(__DragonflyBSD__)
                   cv[75].destination = s->bsd_accept_filter;
                 #endif
                   cv[76].destination = &(s->stream_request_body);
                   cv[77].destination = &(s->stream_response_body);
   
                 srv->config_storage[i] = s;                  srv->config_storage[i] = s;
   
                if (0 != (ret = config_insert_values_global(srv, ((data_config *)srv->config_context->data[i])->value, cv))) {                if (0 != (ret = config_insert_values_global(srv, config->value, cv, i == 0 ? T_CONFIG_SCOPE_SERVER : T_CONFIG_SCOPE_CONNECTION))) {
                         break;                          break;
                 }                  }
   
                   if (s->stream_request_body & FDEVENT_STREAM_REQUEST_BUFMIN) {
                           s->stream_request_body |= FDEVENT_STREAM_REQUEST;
                   }
                   if (s->stream_response_body & FDEVENT_STREAM_RESPONSE_BUFMIN) {
                           s->stream_response_body |= FDEVENT_STREAM_RESPONSE;
                   }
         }          }
   
        if (buffer_is_empty(stat_cache_string)) {        {
                 specific_config *s = srv->config_storage[0];
                 s->http_parseopts= /*(global, but stored in con->conf.http_parseopts)*/
                    (srv->srvconf.http_header_strict  ?(HTTP_PARSEOPT_HEADER_STRICT) :0)
                   |(srv->srvconf.http_host_strict    ?(HTTP_PARSEOPT_HOST_STRICT
                                                       |HTTP_PARSEOPT_HOST_NORMALIZE):0)
                   |(srv->srvconf.http_host_normalize ?(HTTP_PARSEOPT_HOST_NORMALIZE):0);
         }
 
         if (buffer_string_is_empty(stat_cache_string)) {
                 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;                  srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
         } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {          } else if (buffer_is_equal_string(stat_cache_string, CONST_STR_LEN("simple"))) {
                 srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;                  srv->srvconf.stat_cache_engine = STAT_CACHE_ENGINE_SIMPLE;
Line 295  static int config_insert(server *srv) { Line 336  static int config_insert(server *srv) {
   
         buffer_free(stat_cache_string);          buffer_free(stat_cache_string);
   
           {
                   data_string *ds;
                   int prepend_mod_indexfile = 1;
                   int append_mod_dirlisting = 1;
                   int append_mod_staticfile = 1;
   
                   /* prepend default modules */
                   for (i = 0; i < srv->srvconf.modules->used; i++) {
                           ds = (data_string *)srv->srvconf.modules->data[i];
   
                           if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_indexfile"))) {
                                   prepend_mod_indexfile = 0;
                           }
   
                           if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_staticfile"))) {
                                   append_mod_staticfile = 0;
                           }
   
                           if (buffer_is_equal_string(ds->value, CONST_STR_LEN("mod_dirlisting"))) {
                                   append_mod_dirlisting = 0;
                           }
   
                           if (0 == prepend_mod_indexfile &&
                               0 == append_mod_dirlisting &&
                               0 == append_mod_staticfile) {
                                   break;
                           }
                   }
   
                   if (prepend_mod_indexfile) {
                           /* mod_indexfile has to be loaded before mod_fastcgi and friends */
                           array *modules = array_init();
   
                           ds = data_string_init();
                           buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile"));
                           array_insert_unique(modules, (data_unset *)ds);
   
                           for (i = 0; i < srv->srvconf.modules->used; i++) {
                                   data_unset *du = srv->srvconf.modules->data[i];
                                   array_insert_unique(modules, du->copy(du));
                           }
   
                           array_free(srv->srvconf.modules);
                           srv->srvconf.modules = modules;
                   }
   
                   /* append default modules */
                   if (append_mod_dirlisting) {
                           ds = data_string_init();
                           buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting"));
                           array_insert_unique(srv->srvconf.modules, (data_unset *)ds);
                   }
   
                   if (append_mod_staticfile) {
                           ds = data_string_init();
                           buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile"));
                           array_insert_unique(srv->srvconf.modules, (data_unset *)ds);
                   }
           }
   
         return ret;          return ret;
   
 }  }
Line 304  static int config_insert(server *srv) { Line 405  static int config_insert(server *srv) {
 int config_setup_connection(server *srv, connection *con) {  int config_setup_connection(server *srv, connection *con) {
         specific_config *s = srv->config_storage[0];          specific_config *s = srv->config_storage[0];
   
           PATCH(http_parseopts);
   
         PATCH(allow_http11);          PATCH(allow_http11);
         PATCH(mimetypes);          PATCH(mimetypes);
         PATCH(document_root);          PATCH(document_root);
           PATCH(high_precision_timestamps);
         PATCH(max_keep_alive_requests);          PATCH(max_keep_alive_requests);
         PATCH(max_keep_alive_idle);          PATCH(max_keep_alive_idle);
         PATCH(max_read_idle);          PATCH(max_read_idle);
         PATCH(max_write_idle);          PATCH(max_write_idle);
           PATCH(max_request_size);
         PATCH(use_xattr);          PATCH(use_xattr);
         PATCH(error_handler);          PATCH(error_handler);
           PATCH(error_handler_404);
         PATCH(errorfile_prefix);          PATCH(errorfile_prefix);
 #ifdef HAVE_LSTAT  #ifdef HAVE_LSTAT
         PATCH(follow_symlink);          PATCH(follow_symlink);
Line 323  int config_setup_connection(server *srv, connection *c Line 429  int config_setup_connection(server *srv, connection *c
         PATCH(global_bytes_per_second_cnt);          PATCH(global_bytes_per_second_cnt);
   
         con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;          con->conf.global_bytes_per_second_cnt_ptr = &s->global_bytes_per_second_cnt;
        buffer_copy_string_buffer(con->server_name, s->server_name);        buffer_copy_buffer(con->server_name, s->server_name);
   
         PATCH(log_request_header);          PATCH(log_request_header);
         PATCH(log_response_header);          PATCH(log_response_header);
Line 335  int config_setup_connection(server *srv, connection *c Line 441  int config_setup_connection(server *srv, connection *c
   
         PATCH(range_requests);          PATCH(range_requests);
         PATCH(force_lowercase_filenames);          PATCH(force_lowercase_filenames);
           /*PATCH(listen_backlog);*//*(not necessary; used only at startup)*/
           PATCH(stream_request_body);
           PATCH(stream_response_body);
   
         PATCH(ssl_enabled);          PATCH(ssl_enabled);
   
         PATCH(ssl_pemfile);          PATCH(ssl_pemfile);
 #ifdef USE_OPENSSL  #ifdef USE_OPENSSL
        PATCH(ssl_ctx);        PATCH(ssl_pemfile_x509);
         PATCH(ssl_pemfile_pkey);
 #endif  #endif
         PATCH(ssl_ca_file);          PATCH(ssl_ca_file);
   #ifdef USE_OPENSSL
           PATCH(ssl_ca_file_cert_names);
   #endif
         PATCH(ssl_cipher_list);          PATCH(ssl_cipher_list);
         PATCH(ssl_dh_file);          PATCH(ssl_dh_file);
         PATCH(ssl_ec_curve);          PATCH(ssl_ec_curve);
Line 363  int config_setup_connection(server *srv, connection *c Line 477  int config_setup_connection(server *srv, connection *c
         return 0;          return 0;
 }  }
   
int config_patch_connection(server *srv, connection *con, comp_key_t comp) {int config_patch_connection(server *srv, connection *con) {
         size_t i, j;          size_t i, j;
   
         con->conditional_is_valid[comp] = 1;  
   
         /* skip the first, the global context */          /* skip the first, the global context */
         for (i = 1; i < srv->config_context->used; i++) {          for (i = 1; i < srv->config_context->used; i++) {
                 data_config *dc = (data_config *)srv->config_context->data[i];                  data_config *dc = (data_config *)srv->config_context->data[i];
Line 384  int config_patch_connection(server *srv, connection *c Line 496  int config_patch_connection(server *srv, connection *c
                                 PATCH(document_root);                                  PATCH(document_root);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.range-requests"))) {
                                 PATCH(range_requests);                                  PATCH(range_requests);
                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.error-handler-404"))) {                        } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.error-handler"))) {
                                 PATCH(error_handler);                                  PATCH(error_handler);
                           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.error-handler-404"))) {
                                   PATCH(error_handler_404);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.errorfile-prefix"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.errorfile-prefix"))) {
                                 PATCH(errorfile_prefix);                                  PATCH(errorfile_prefix);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.assign"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.assign"))) {
Line 398  int config_patch_connection(server *srv, connection *c Line 512  int config_patch_connection(server *srv, connection *c
                                 PATCH(max_write_idle);                                  PATCH(max_write_idle);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.max-read-idle"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.max-read-idle"))) {
                                 PATCH(max_read_idle);                                  PATCH(max_read_idle);
                           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.max-request-size"))) {
                                   PATCH(max_request_size);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.use-xattr"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("mimetype.use-xattr"))) {
                                 PATCH(use_xattr);                                  PATCH(use_xattr);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-inode"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("etag.use-inode"))) {
Line 409  int config_patch_connection(server *srv, connection *c Line 525  int config_patch_connection(server *srv, connection *c
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.pemfile"))) {
                                 PATCH(ssl_pemfile);                                  PATCH(ssl_pemfile);
 #ifdef USE_OPENSSL  #ifdef USE_OPENSSL
                                PATCH(ssl_ctx);                                PATCH(ssl_pemfile_x509);
                                 PATCH(ssl_pemfile_pkey);
 #endif  #endif
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.ca-file"))) {
                                 PATCH(ssl_ca_file);                                  PATCH(ssl_ca_file);
   #ifdef USE_OPENSSL
                                   PATCH(ssl_ca_file_cert_names);
   #endif
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.honor-cipher-order"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.honor-cipher-order"))) {
                                 PATCH(ssl_honor_cipher_order);                                  PATCH(ssl_honor_cipher_order);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.empty-fragments"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("ssl.empty-fragments"))) {
Line 434  int config_patch_connection(server *srv, connection *c Line 554  int config_patch_connection(server *srv, connection *c
                                 PATCH(follow_symlink);                                  PATCH(follow_symlink);
 #endif  #endif
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.name"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.name"))) {
                                buffer_copy_string_buffer(con->server_name, s->server_name);                                buffer_copy_buffer(con->server_name, s->server_name);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.tag"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.tag"))) {
                                 PATCH(server_tag);                                  PATCH(server_tag);
                           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.stream-request-body"))) {
                                   PATCH(stream_request_body);
                           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.stream-response-body"))) {
                                   PATCH(stream_response_body);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("connection.kbytes-per-second"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("connection.kbytes-per-second"))) {
                                 PATCH(kbytes_per_second);                                  PATCH(kbytes_per_second);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-request-handling"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("debug.log-request-handling"))) {
Line 457  int config_patch_connection(server *srv, connection *c Line 581  int config_patch_connection(server *srv, connection *c
                                 PATCH(allow_http11);                                  PATCH(allow_http11);
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.force-lowercase-filenames"))) {
                                 PATCH(force_lowercase_filenames);                                  PATCH(force_lowercase_filenames);
                         #if 0 /*(not necessary; used only at startup)*/
                           } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.listen-backlog"))) {
                                   PATCH(listen_backlog);
                         #endif
                         } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) {                          } else if (buffer_is_equal_string(du->key, CONST_STR_LEN("server.kbytes-per-second"))) {
                                 PATCH(global_kbytes_per_second);                                  PATCH(global_kbytes_per_second);
                                 PATCH(global_bytes_per_second_cnt);                                  PATCH(global_bytes_per_second_cnt);
Line 504  typedef struct { Line 632  typedef struct {
   
 #if 0  #if 0
 static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) {  static int tokenizer_open(server *srv, tokenizer_t *t, buffer *basedir, const char *fn) {
        if (buffer_is_empty(basedir) ||        if (buffer_string_is_empty(basedir) ||
                         (fn[0] == '/' || fn[0] == '\\') ||                          (fn[0] == '/' || fn[0] == '\\') ||
                         (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {                          (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {
                 t->file = buffer_init_string(fn);                  t->file = buffer_init_string(fn);
Line 541  static int tokenizer_close(server *srv, tokenizer_t *t Line 669  static int tokenizer_close(server *srv, tokenizer_t *t
 #endif  #endif
 static int config_skip_newline(tokenizer_t *t) {  static int config_skip_newline(tokenizer_t *t) {
         int skipped = 1;          int skipped = 1;
        assert(t->input[t->offset] == '\r' || t->input[t->offset] == '\n');        force_assert(t->input[t->offset] == '\r' || t->input[t->offset] == '\n');
         if (t->input[t->offset] == '\r' && t->input[t->offset + 1] == '\n') {          if (t->input[t->offset] == '\r' && t->input[t->offset + 1] == '\n') {
                 skipped ++;                  skipped ++;
                 t->offset ++;                  t->offset ++;
Line 552  static int config_skip_newline(tokenizer_t *t) { Line 680  static int config_skip_newline(tokenizer_t *t) {
   
 static int config_skip_comment(tokenizer_t *t) {  static int config_skip_comment(tokenizer_t *t) {
         int i;          int i;
        assert(t->input[t->offset] == '#');        force_assert(t->input[t->offset] == '#');
         for (i = 1; t->input[t->offset + i] &&          for (i = 1; t->input[t->offset + i] &&
              (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r');               (t->input[t->offset + i] != '\n' && t->input[t->offset + i] != '\r');
              i++);               i++);
Line 923  static int config_parse(server *srv, config_t *context Line 1051  static int config_parse(server *srv, config_t *context
         int ret;          int ret;
   
         pParser = configparserAlloc( malloc );          pParser = configparserAlloc( malloc );
           force_assert(pParser);
         lasttoken = buffer_init();          lasttoken = buffer_init();
         token = buffer_init();          token = buffer_init();
         while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {          while((1 == (ret = config_tokenizer(srv, t, &token_id, token))) && context->ok) {
                buffer_copy_string_buffer(lasttoken, token);                buffer_copy_buffer(lasttoken, token);
                 configparser(pParser, token_id, token, context);                  configparser(pParser, token_id, token, context);
   
                 token = buffer_init();                  token = buffer_init();
Line 972  static int tokenizer_init(tokenizer_t *t, const buffer Line 1101  static int tokenizer_init(tokenizer_t *t, const buffer
         return 0;          return 0;
 }  }
   
int config_parse_file(server *srv, config_t *context, const char *fn) {static int config_parse_file_stream(server *srv, config_t *context, const buffer *filename) {
         tokenizer_t t;          tokenizer_t t;
         stream s;          stream s;
         int ret;          int ret;
   
           if (0 != stream_open(&s, filename)) {
                   log_error_write(srv, __FILE__, __LINE__, "sbss",
                                   "opening configfile ", filename, "failed:", strerror(errno));
                   return -1;
           } else {
                   tokenizer_init(&t, filename, s.start, s.size);
                   ret = config_parse(srv, context, &t);
           }
   
           stream_close(&s);
           return ret;
   }
   
   int config_parse_file(server *srv, config_t *context, const char *fn) {
         buffer *filename;          buffer *filename;
           size_t i;
           int ret = -1;
         #ifdef GLOB_BRACE
           int flags = GLOB_BRACE;
         #else
           int flags = 0;
         #endif
           glob_t gl;
   
        if (buffer_is_empty(context->basedir) ||        if ((fn[0] == '/' || fn[0] == '\\') ||
                        (fn[0] == '/' || fn[0] == '\\') ||            (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\')) ||
                        (fn[0] == '.' && (fn[1] == '/' || fn[1] == '\\'))) {            (fn[0] == '.' && fn[1] == '.' && (fn[2] == '/' || fn[2] == '\\'))) {
                 filename = buffer_init_string(fn);                  filename = buffer_init_string(fn);
         } else {          } else {
                 filename = buffer_init_buffer(context->basedir);                  filename = buffer_init_buffer(context->basedir);
                 buffer_append_string(filename, fn);                  buffer_append_string(filename, fn);
         }          }
   
        if (0 != stream_open(&s, filename)) {        switch (glob(filename->ptr, flags, NULL, &gl)) {
                if (s.size == 0) {        case 0:
                        /* the file was empty, nothing to parse */                for (i = 0; i < gl.gl_pathc; ++i) {
                        ret = 0;                        buffer_copy_string(filename, gl.gl_pathv[i]);
                } else {                        ret = config_parse_file_stream(srv, context, filename);
                        log_error_write(srv, __FILE__, __LINE__, "sbss",                        if (0 != ret) break;
                                        "opening configfile ", filename, "failed:", strerror(errno));                }
                        ret = -1;                globfree(&gl);
                }                 break;
        } else {        case GLOB_NOMATCH:
                tokenizer_init(&t, filename, s.start, s.size);                if (filename->ptr[strcspn(filename->ptr, "*?[]{}")] != '\0') { /*(contains glob metachars)*/
                ret = config_parse(srv, context, &t);                        ret = 0; /* not an error if no files match glob pattern */
                 }
                 else {
                         log_error_write(srv, __FILE__, __LINE__, "sb", "include file not found: ", filename);
                 }
                 break;
         case GLOB_ABORTED:
         case GLOB_NOSPACE:
                 log_error_write(srv, __FILE__, __LINE__, "sbss", "glob()", filename, "failed:", strerror(errno));
                 break;
         }          }
   
         stream_close(&s);  
         buffer_free(filename);          buffer_free(filename);
         return ret;          return ret;
 }  }
Line 1018  static char* getCWD(void) { Line 1178  static char* getCWD(void) {
         s = malloc(len);          s = malloc(len);
         if (!s) return NULL;          if (!s) return NULL;
         while (NULL == getcwd(s, len)) {          while (NULL == getcwd(s, len)) {
                if (errno != ERANGE || SSIZE_MAX - len < len) return NULL;                if (errno != ERANGE || SSIZE_MAX - len < len) {
                         free(s);
                         return NULL;
                 }
                 len *= 2;                  len *= 2;
                 s1 = realloc(s, len);                  s1 = realloc(s, len);
                 if (!s1) {                  if (!s1) {
Line 1039  int config_parse_cmd(server *srv, config_t *context, c Line 1202  int config_parse_cmd(server *srv, config_t *context, c
   
         if (NULL == (oldpwd = getCWD())) {          if (NULL == (oldpwd = getCWD())) {
                 log_error_write(srv, __FILE__, __LINE__, "s",                  log_error_write(srv, __FILE__, __LINE__, "s",
                                "cannot get cwd", strerror(errno));                        "cannot get cwd", strerror(errno));
                 return -1;                  return -1;
         }          }
   
           if (!buffer_string_is_empty(context->basedir)) {
                   if (0 != chdir(context->basedir->ptr)) {
                           log_error_write(srv, __FILE__, __LINE__, "sbs",
                                   "cannot change directory to", context->basedir, strerror(errno));
                           free(oldpwd);
                           return -1;
                   }
           }
   
         source = buffer_init_string(cmd);          source = buffer_init_string(cmd);
         out = buffer_init();          out = buffer_init();
   
         if (!buffer_is_empty(context->basedir)) {  
                 chdir(context->basedir->ptr);  
         }  
   
         if (0 != proc_open_buffer(cmd, NULL, out, NULL)) {          if (0 != proc_open_buffer(cmd, NULL, out, NULL)) {
                 log_error_write(srv, __FILE__, __LINE__, "sbss",                  log_error_write(srv, __FILE__, __LINE__, "sbss",
                                "opening", source, "failed:", strerror(errno));                        "opening", source, "failed:", strerror(errno));
                 ret = -1;                  ret = -1;
         } else {          } else {
                tokenizer_init(&t, source, out->ptr, out->used);                tokenizer_init(&t, source, CONST_BUF_LEN(out));
                 ret = config_parse(srv, context, &t);                  ret = config_parse(srv, context, &t);
         }          }
   
         buffer_free(source);          buffer_free(source);
         buffer_free(out);          buffer_free(out);
        chdir(oldpwd);        if (0 != chdir(oldpwd)) {
                 log_error_write(srv, __FILE__, __LINE__, "sss",
                         "cannot change directory to", oldpwd, strerror(errno));
                 free(oldpwd);
                 return -1;
         }
         free(oldpwd);          free(oldpwd);
         return ret;          return ret;
 }  }
Line 1069  int config_parse_cmd(server *srv, config_t *context, c Line 1242  int config_parse_cmd(server *srv, config_t *context, c
 static void context_init(server *srv, config_t *context) {  static void context_init(server *srv, config_t *context) {
         context->srv = srv;          context->srv = srv;
         context->ok = 1;          context->ok = 1;
        context->configs_stack = array_init();        vector_config_weak_init(&context->configs_stack);
        context->configs_stack->is_weakref = 1; 
         context->basedir = buffer_init();          context->basedir = buffer_init();
 }  }
   
 static void context_free(config_t *context) {  static void context_free(config_t *context) {
        array_free(context->configs_stack);        vector_config_weak_clear(&context->configs_stack);
         buffer_free(context->basedir);          buffer_free(context->basedir);
 }  }
   
Line 1086  int config_read(server *srv, const char *fn) { Line 1258  int config_read(server *srv, const char *fn) {
         data_string *dcwd;          data_string *dcwd;
         int ret;          int ret;
         char *pos;          char *pos;
        data_array *modules;        buffer *filename;
   
         context_init(srv, &context);          context_init(srv, &context);
         context.all_configs = srv->config_context;          context.all_configs = srv->config_context;
Line 1098  int config_read(server *srv, const char *fn) { Line 1270  int config_read(server *srv, const char *fn) {
 #endif  #endif
         if (pos) {          if (pos) {
                 buffer_copy_string_len(context.basedir, fn, pos - fn + 1);                  buffer_copy_string_len(context.basedir, fn, pos - fn + 1);
                 fn = pos + 1;  
         }          }
   
         dc = data_config_init();          dc = data_config_init();
         buffer_copy_string_len(dc->key, CONST_STR_LEN("global"));          buffer_copy_string_len(dc->key, CONST_STR_LEN("global"));
   
        assert(context.all_configs->used == 0);        force_assert(context.all_configs->used == 0);
         dc->context_ndx = context.all_configs->used;          dc->context_ndx = context.all_configs->used;
         array_insert_unique(context.all_configs, (data_unset *)dc);          array_insert_unique(context.all_configs, (data_unset *)dc);
         context.current = dc;          context.current = dc;
   
         /* default context */          /* default context */
         srv->config = dc->value;  
         dpid = data_integer_init();          dpid = data_integer_init();
         dpid->value = getpid();          dpid->value = getpid();
         buffer_copy_string_len(dpid->key, CONST_STR_LEN("var.PID"));          buffer_copy_string_len(dpid->key, CONST_STR_LEN("var.PID"));
        array_insert_unique(srv->config, (data_unset *)dpid);        array_insert_unique(dc->value, (data_unset *)dpid);
   
         dcwd = data_string_init();          dcwd = data_string_init();
        buffer_prepare_copy(dcwd->value, 1024);        buffer_string_prepare_copy(dcwd->value, 1023);
         if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {          if (NULL != getcwd(dcwd->value->ptr, dcwd->value->size - 1)) {
                dcwd->value->used = strlen(dcwd->value->ptr) + 1;                buffer_commit(dcwd->value, strlen(dcwd->value->ptr));
                 buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD"));                  buffer_copy_string_len(dcwd->key, CONST_STR_LEN("var.CWD"));
                array_insert_unique(srv->config, (data_unset *)dcwd);                array_insert_unique(dc->value, (data_unset *)dcwd);
         } else {
                 dcwd->free((data_unset*) dcwd);
         }          }
   
        ret = config_parse_file(srv, &context, fn);        filename = buffer_init_string(fn);
         ret = config_parse_file_stream(srv, &context, filename);
         buffer_free(filename);
   
         /* remains nothing if parser is ok */          /* remains nothing if parser is ok */
        assert(!(0 == ret && context.ok && 0 != context.configs_stack->used));        force_assert(!(0 == ret && context.ok && 0 != context.configs_stack.used));
         context_free(&context);          context_free(&context);
   
         if (0 != ret) {          if (0 != ret) {
                 return ret;                  return ret;
         }          }
   
         if (NULL != (dc = (data_config *)array_get_element(srv->config_context, "global"))) {  
                 srv->config = dc->value;  
         } else {  
                 return -1;  
         }  
   
         if (NULL != (modules = (data_array *)array_get_element(srv->config, "server.modules"))) {  
                 data_string *ds;  
                 data_array *prepends;  
   
                 if (modules->type != TYPE_ARRAY) {  
                         fprintf(stderr, "server.modules must be an array");  
                         return -1;  
                 }  
   
                 prepends = data_array_init();  
   
                 /* prepend default modules */  
                 if (NULL == array_get_element(modules->value, "mod_indexfile")) {  
                         ds = data_string_init();  
                         buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile"));  
                         array_insert_unique(prepends->value, (data_unset *)ds);  
                 }  
   
                 prepends = (data_array *)configparser_merge_data((data_unset *)prepends, (data_unset *)modules);  
                 buffer_copy_string_buffer(prepends->key, modules->key);  
                 array_replace(srv->config, (data_unset *)prepends);  
                 modules->free((data_unset *)modules);  
                 modules = prepends;  
   
                 /* append default modules */  
                 if (NULL == array_get_element(modules->value, "mod_dirlisting")) {  
                         ds = data_string_init();  
                         buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting"));  
                         array_insert_unique(modules->value, (data_unset *)ds);  
                 }  
   
                 if (NULL == array_get_element(modules->value, "mod_staticfile")) {  
                         ds = data_string_init();  
                         buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile"));  
                         array_insert_unique(modules->value, (data_unset *)ds);  
                 }  
         } else {  
                 data_string *ds;  
   
                 modules = data_array_init();  
   
                 /* server.modules is not set */  
                 ds = data_string_init();  
                 buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_indexfile"));  
                 array_insert_unique(modules->value, (data_unset *)ds);  
   
                 ds = data_string_init();  
                 buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_dirlisting"));  
                 array_insert_unique(modules->value, (data_unset *)ds);  
   
                 ds = data_string_init();  
                 buffer_copy_string_len(ds->value, CONST_STR_LEN("mod_staticfile"));  
                 array_insert_unique(modules->value, (data_unset *)ds);  
   
                 buffer_copy_string_len(modules->key, CONST_STR_LEN("server.modules"));  
                 array_insert_unique(srv->config, (data_unset *)modules);  
         }  
   
   
         if (0 != config_insert(srv)) {          if (0 != config_insert(srv)) {
                 return -1;                  return -1;
         }          }
Line 1241  int config_set_defaults(server *srv) { Line 1350  int config_set_defaults(server *srv) {
                 { FDEVENT_HANDLER_UNSET,          NULL }                  { FDEVENT_HANDLER_UNSET,          NULL }
         };          };
   
        if (!buffer_is_empty(srv->srvconf.changeroot)) {        if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
                 if (-1 == stat(srv->srvconf.changeroot->ptr, &st1)) {                  if (-1 == stat(srv->srvconf.changeroot->ptr, &st1)) {
                         log_error_write(srv, __FILE__, __LINE__, "sb",                          log_error_write(srv, __FILE__, __LINE__, "sb",
                                         "server.chroot doesn't exist:", srv->srvconf.changeroot);                                          "server.chroot doesn't exist:", srv->srvconf.changeroot);
Line 1254  int config_set_defaults(server *srv) { Line 1363  int config_set_defaults(server *srv) {
                 }                  }
         }          }
   
        if (buffer_is_empty(s->document_root)) {        if (!srv->srvconf.upload_tempdirs->used) {
                 data_string *ds = data_string_init();
                 const char *tmpdir = getenv("TMPDIR");
                 if (NULL == tmpdir) tmpdir = "/var/tmp";
                 buffer_copy_string(ds->value, tmpdir);
                 array_insert_unique(srv->srvconf.upload_tempdirs, (data_unset *)ds);
         }
 
         if (srv->srvconf.upload_tempdirs->used) {
                 buffer * const b = srv->tmp_buf;
                 size_t len;
                 if (!buffer_string_is_empty(srv->srvconf.changeroot)) {
                         buffer_copy_buffer(b, srv->srvconf.changeroot);
                         buffer_append_slash(b);
                 } else {
                         buffer_reset(b);
                 }
                 len = buffer_string_length(b);
 
                 for (i = 0; i < srv->srvconf.upload_tempdirs->used; ++i) {
                         const data_string * const ds = (data_string *)srv->srvconf.upload_tempdirs->data[i];
                         buffer_string_set_length(b, len); /*(truncate)*/
                         buffer_append_string_buffer(b, ds->value);
                         if (-1 == stat(b->ptr, &st1)) {
                                 log_error_write(srv, __FILE__, __LINE__, "sb",
                                         "server.upload-dirs doesn't exist:", b);
                         } else if (!S_ISDIR(st1.st_mode)) {
                                 log_error_write(srv, __FILE__, __LINE__, "sb",
                                         "server.upload-dirs isn't a directory:", b);
                         }
                 }
         }
 
         chunkqueue_set_tempdirs_default(
                 srv->srvconf.upload_tempdirs,
                 srv->srvconf.upload_temp_file_size);
 
         if (buffer_string_is_empty(s->document_root)) {
                 log_error_write(srv, __FILE__, __LINE__, "s",                  log_error_write(srv, __FILE__, __LINE__, "s",
                                 "a default document-root has to be set");                                  "a default document-root has to be set");
   
                 return -1;                  return -1;
         }          }
   
        buffer_copy_string_buffer(srv->tmp_buf, s->document_root);        buffer_copy_buffer(srv->tmp_buf, s->document_root);
   
         buffer_to_lower(srv->tmp_buf);          buffer_to_lower(srv->tmp_buf);
   
Line 1274  int config_set_defaults(server *srv) { Line 1420  int config_set_defaults(server *srv) {
                         is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);                          is_lower = buffer_is_equal(srv->tmp_buf, s->document_root);
   
                         /* lower-case existed, check upper-case */                          /* lower-case existed, check upper-case */
                        buffer_copy_string_buffer(srv->tmp_buf, s->document_root);                        buffer_copy_buffer(srv->tmp_buf, s->document_root);
   
                         buffer_to_upper(srv->tmp_buf);                          buffer_to_upper(srv->tmp_buf);
   
Line 1306  int config_set_defaults(server *srv) { Line 1452  int config_set_defaults(server *srv) {
                 srv->srvconf.port = s->ssl_enabled ? 443 : 80;                  srv->srvconf.port = s->ssl_enabled ? 443 : 80;
         }          }
   
        if (srv->srvconf.event_handler->used == 0) {        if (buffer_string_is_empty(srv->srvconf.event_handler)) {
                 /* choose a good default                  /* choose a good default
                  *                   *
                  * the event_handler list is sorted by 'goodness'                   * the event_handler list is sorted by 'goodness'
Line 1342  int config_set_defaults(server *srv) { Line 1488  int config_set_defaults(server *srv) {
         }          }
   
         if (s->ssl_enabled) {          if (s->ssl_enabled) {
                if (buffer_is_empty(s->ssl_pemfile)) {                if (buffer_string_is_empty(s->ssl_pemfile)) {
                         /* PEM file is require */                          /* PEM file is require */
   
                         log_error_write(srv, __FILE__, __LINE__, "s",                          log_error_write(srv, __FILE__, __LINE__, "s",

Removed from v.1.1  
changed lines
  Added in v.1.1.1.3


FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>